webpack工程化08(webpack dev server)

2018-12-31  本文已影响8人  Mr绍君

webpack搭建服务有几种方式,第一种:webpack watch mode 已命令行方式执行配置文件启动服务(基本不用);第二种:webpack-dev-server 这也是webpack官方推荐的方式(最常见);第三种:express + webpack-dev-middleware 可以更加灵活的自定义服务(更灵活,但难度也会高一点)

本文只讲第二种和第三种。

1.webpack-dev-server

webpack-dev-server的功能其实非常强大,比如我们最熟悉的模块热更新,接口代理,路劲重定向,live reloading等

我们来看一下devServer的一些配置
contentBase:静态文件的路径,port:端口,historyApiFallback:地址指向,https:支持https,proxy:代理,hot:热更新,openpage:启动服务打开的页面,lay:懒加载,overlay:错误提示是否在html上遮罩提示

我们直接来看一个最简单的demo

//webpack.config.js
const path = require('path')
var HtmlWebpackPlugin = require('html-webpack-plugin');

module.exports = {
    entry: {
        app: path.resolve(__dirname, 'src/app.js')
    },
    output: {
        filename: '[name]-[hash:5]-bundle.js',
        path: path.resolve(__dirname,'dist')
    },
    devServer: {
        port: '8080'
    },
    plugins: [
        new HtmlWebpackPlugin({
            template: path.join(__dirname, 'index.html')
        })
    ]
}

然后在package.josn文件的script中加一条脚本。

"dev": "webpack-dev-server --open"

然后执行 npm run dev 启动服务,服务成功启动。

在index.html中写个hello word,页面自动更新,在devServer下,文件打包在内存中,所以dist文件是不会生产的。


下面来看一下常见的一些配置

inline设置为false之后,在页面头部会显示一个编译的进程,而inline为true的话,编译信息会显示在console里面。(一般为true)


当我们输入一个不存在的路由的时候,页面往往会报一个404或者提示找不到页面


如果我们把historyApiFallback设为true就不会有这个问题,而且historyApiFallback可以自定义页面的路径跳转和显示。(可用正则)

historyApiFallback: {
            rewrites: [
                {
                    from: '/test/a',
                    to: '/test/a.html'
                }
            ]
        }

我们在跟目录建一个test文件夹,里面放一个a.html。当我们改变地址的时候就会跳转到a.html页面

Proxy:这个配置也是很重要的,因为在项目中接口的请求往往是跨域访问的,所以需要proxy来做代理。proxy有几个参数,target代理目标,changeOrigin可以改变访问的源,headers请求头信息,pathRewrite地址重写。

举个例子。

我们先引入axios,用来请求接口,target接口地址是我博客的一个地址,因为我的博客地址也是以api开头,所以需要pathRewrite把/api替换成/api

const path = require('path')
const webpack = require('webpack')
var HtmlWebpackPlugin = require('html-webpack-plugin');

module.exports = {
    entry: {
        app: path.resolve(__dirname, 'src/app.js')
    },
    output: {
        filename: '[name]-[hash:5]-bundle.js',
        path: path.resolve(__dirname,'dist')
    },
    devServer: {
        inline: true,
        port: '8080',
        historyApiFallback: true,
        proxy: {
            '/api': {
                target: 'https://api.yeshaojun.com',
                changeOrigin: true,
                pathRewrite: {
                    '/api': '/api'
                }
            }
        }
    },
    plugins: [
        new HtmlWebpackPlugin({
            template: path.join(__dirname, 'index.html')
        }),
        new webpack.ProvidePlugin({
            axios: 'axios'
        })  
    ]
}
//app.js
setTimeout(function() {
    axios.get('/api/newslist').then(res=> {
        console.log(res)
    })
},2000)

我们可以看到,接口就请求成功了。


下面介绍一下模块热更新,这个几乎是项目必用的一个功能,好处也很明显,不会刷新页面,只更新我们修改的内容,让我们调试更加方便。

在配置文件中,将hot设置true,同时在插件中使用webpack.HotModuleReplacementPlugin,这样模块热更新就配置完了。

但是在实际的热更新中,一般先通过loder来处理,然后再进行热更新。

css的热更新依赖于style-loader,js的热更新一般依赖于框架提供的loader,比如vue-loader

当然也可以自己配置。


直接看demo

//app.js
import './A.css'

var div = document.getElementById('app')
div.innerHTML = 'hello word111'
div.setAttribute('class', 'test')

//A.css
.test {
    background: #000;
    color: #fff;
}
const path = require('path')
const webpack = require('webpack')
const HtmlWebpackPlugin = require('html-webpack-plugin');

module.exports = {
    entry: {
        app: path.resolve(__dirname, 'src/app')
    },
    output: {
        filename: '[name]-[hash:5]-bundle.js',
        path: path.resolve(__dirname, 'dist')
    },
    module: {
        rules: [
            {
                test: /\.css$/,
                use: ['style-loader','css-loader']
            }
        ]
    },
    devServer: {
        port: '8080',
        hot: true
    },
    plugins: [
        new webpack.HotModuleReplacementPlugin(),
        new HtmlWebpackPlugin({
            template: path.resolve(__dirname, 'index.html')
        })
        
    ]
}

运行之后,修改.test背景色,发现页面没有刷新,背景直接变色了,可见css的热更新是好的。

修改div.innerHTML发现页面刷新了,很显然js并没有实现热更新。

在app.js中加两行代码

if(module.hot) {
    module.hot.accept()
}

至此,js热更新也实现了。

开发cheap-module-scoure-map,生产:scoure-map

上一篇下一篇

猜你喜欢

热点阅读