实时编译及重新加载
一般每次修改代码以后,都需要手动 npm run build 进行编译打包后才可以看到实际打包后的内容,这个过程的频繁操作非常影响开发效率,所以我们希望可以做到当文件发生变化时,自动的完成编译和展示。
webpack 中有几个不同的选项,可以使代码发生变化后自动完成编译:
一、webpack watch mode
webpack 提供了 watch 模式,在该模式下,webpack 依赖图中的所有文件,只要有一个发生了更新,代码就会被重新编译,就不需要手动去运行 npm run build 指令了,启用该模式的方式如下:
1、配置文件中添加 watch
在 webpack 的配置文件中添加 watch: true
:
const path = require('path')
module.exports = {
// ...
watch: true,
entry: './index.js',
output: {
filename: 'bundle.js',
path: path.join(__dirname, '/')
},
// ...
}
2、设置 watch 运行命令
在启动命令中,添加 --watch 的标识:
{
// ...
"scripts": {
"watch": "webpack --watch"
},
// ...
}
二、webpack-dev-server
使用 watch 进行代码监听存在一些问题:
- watch 只能对代码进行实时编译,无法开启本地服务来运行代码,做到实时重新加载(live reloading)
- 编译成功后,会形成新的打包文件夹,也就是会频繁操作
file stystem
,而实际上我们只要在项目全编写完再生产打包文件夹; - 使用 watch 进行代码编译时,会刷新整个页面,无法保留页面的一些状态;
- watch 方式编译文件,会对整个源代码进行编译,无论是否发生改变。
以上问题可以使用 webpack-dev-server
(WDR)来进行优化,webpack-dev-server
提供了一个简单的 web 服务器,能够实时重新加载(live reloading),启用方式如下:
1、安装 webpack-dev-server
npm install --save-dev webpack-dev-server
2、设置 start 运行命令
如果没有自定义 webpack-dev-server
的相关配置,可以直接执行 webpack serve, webpack 会自动调用 webpack-dev-server
:
{
// ...
"scripts": {
"watch": "webpack --watch",
"start": "webpack serve"
},
// ...
}
如果要自定义 webpack-dev-server
的相关配置,则启动命令中执行 webpack-dev-server
:
{
// ...
"scripts": {
"watch": "webpack --watch",
"start": "webpack serve"
"start": "webpack-dev-server"
},
// ...
}
webpack-dev-server
带有许多可配置的选项,可在 webpack.config.js 中进行任何的配置。
3、自定义配置项
const path = require('path')
module.exports = {
entry: './index.js',
output: {
filename: 'bundle.js',
path: path.join(__dirname, '/')
},
devServer: {
hot: true, // 启动模块热更新 HMR
open: true, // 开启自动打开浏览器页面
},
}
常见配置项如下:
devServer: {
contentBase: path.join(__dirname, 'static'), // 告诉服务器从哪里提供内容(默认当前工作目录)
openPage: 'views/index.html', // 指定默认启动浏览器时打开的页面
index: 'views/index.html', // 指定首页位置
watchContentBase: true, // contentBase 下文件变动将 reload 页面 (默认 false)
host: 'localhost', // 默认 localhost, 想外部可访问用 '0.0.0.0'
port: 8080, // 默认 8080
inline: true, // 可以监控 JS 变化
hot: true, // 模块热替换(热启动)
open: true, // 启动时自动打开浏览器(指定打开 chrome,open: 'Google Chrome')
compress: true, // 一切服务都启用 gzip 压缩
disableHostCheck: true, // true:不进行 host 检查
quiet: false,
https: false,
clientLogLevel: 'none',
stats: { // 设置控制台的提示信息
chunks: false,
children: false,
modules: false,
entrypoints: false, // 是否输出入口信息
warnings: false,
performance: false, // 是否输出 webpack 建议(如文件体积大小)
},
historyApiFallback: {
disableDotRule: true,
},
watchOptions: {
ignored: /node_modules/, // 略过 node_modules 目录
},
proxy: { // 接口代理(这段配置更推荐:写到 package.json,再引入到这里)
"/api-dev": {
"target": "http://api.test.xxx.com",
"secure": false,
"changeOrigin": true,
"pathRewrite": { // 将 url 上的某段重写(例如此处是将 api-dev 替换成了空)
"^/api-dev": ""
}
}
},
before(app) { },
}
使用 webpack-dev-server
打包代码时,不会生成对应的打包文件夹的,因为 webpack-dev-server
内部用了一个 memfs
库,可以将打包后的文件夹直接加载到内存中,而不需要频繁操作 file system,从而提升编译效率。
三、webpack-dev-middleware
webpack-dev-server
内部默认使用 express 来搭建本地服务器,开启本地服务,但有时需要自定义对应的配置,此时可以用 webpack-dev-middleware。
webpack-dev-middleware 是一个封装器(wrapper),可以把 webpack 处理后的文件传递给服务器(server)
,webpack-dev-server
在内部使用了它。
同时 webpack-dev-middleware 也可以作为一个单独的包来使用,以便根据需求进行更多自定义设置。
下面是一个 webpack-dev-middleware 配合 express server 的示例:
1、安装 webpack-dev-middleware
这里以 express 为例,也可以使用其它工具,如 koa
npm install --save-dev express webpack-dev-middleware
2、创建 server.js 文件
在项目根目录下,新建 server.js:
const express = require('express')
const webpack = require('webpack')
const webpackDevMiddleware = require('webpack-dev-middleware')
// 创建服务器对象
const app = express()
// 使用 webpack 函数加载配置文件,生成一个 webpack 编译器
const complier = webpack(require('./webpack.config.js'))
// webpack-dev-middleware 会将 complire 转换为一个中间件
const middleware = webpackDevMiddleware(complier)
// 使用中间件
app.use(middleware)
// 开启服务,此时就可以对该服务进行任何需要的定制
app.listen(3000, () => console.log('serve is running'))
3、运行
# 执行
node server.js