如上一篇文章所述,配置好entry、output、loader之后,就已经可以完成基本的代码打包工作。除此之外webpack还提供了很多插件,可以简化一些繁琐的操作,比如自动清理打包生成目录等。
此外还提供sourceMap、devServer等多种开发利器。
Plugin
loader 是用于转换某些类型的模块,而插件则可以用于执行范围更广的任务。插件的范围包括,从打包优化和压缩,一直到重新定义环境中的变量。插件接口功能极其强大,可以用来处理各种各样的任务。
通过以下实例,可以了解到插件到使用方式,更多插件API可以通过上述连接查阅。
CleanWebpackPlugin
clean-webpack-plugin插件可以在每次打包时自动清理(删除)之前残留的构建目录。
- 安装
npm install --save -dev clean-webpack-plugin
- 配置及使用
//webpack.config.js
const {CleanWebpackPlugin} = require('clean-webpack-plugin');
module.exports = {
...,
plugin:[
new CleanWebpackPlugin();
],
...
}
HtmlWebpackPlugin
wepack打包完成之后,自动生成一个html文件,并将打包好的js文件引入到html中。
- 安装
npm install --save-dev html-webpack-plugin
- 配置及使用
//webpack.config.js
const HtmlWebpackPlugin = require('html-webpack.plugin');
module.exports = {
...,
plugin:{
...,
new HtmlWebpackplugin({
title:'app',
filename:'app.html',
template:'./src/html/index.html'
}),
...
},
...
}
- 模版
./scr/html/index.html内容
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title><%=htmlWebpackPlugin.options.title%></title>
</head>
<body>
<h1>html-webpack-plugin</h1>
</body>
</html>
MiniCssExtractPlugin
自动提取css相关配置,并导出到一个单独的.css文件中。
- 安装
npm install --save-dev mini-css-extract-plugin
- 配置及使用
const MiniCssExtactPlugin = require('mini-css-extract-plugin');
module.exports = {
...,
plugin:{
...,
new MiniCssExtactPlugin({
filename:'./css/app.css'
}),
...
},
...
}
SourceMap
实际使用过程中,浏览器上运行的往往是webpack编译打包后的代码,如果代码报错,调试时往往比较麻烦、耗费很多时间定位问题原因。而sourceMap这给我们提供了一个映射关系(编译后的代码 => 编译前的代码),方便我们进行调试。
我们可以通过在webpack.config.js中的devtool选项来开始sourceMap。
//webpack.config.js
module.exports = {
mode: 'production',
devtool: 'source-map',
...
}
-
编译后,sourceMap会给每一个编译后的文件生成一个对应的
.map文件,并且在编译后的文件中添加一行注释来告诉浏览器,这个编译文件是有对应的映射表的。 -
大部分现代浏览器如Chrome都是可以识别到
.map文件的,在浏览器调试台中的source选项下可以看到由sourceMap提供的映射关系,这样大大提高了我们代码编写效率。
WebpackDevServer
每次的代码修改都需要重新编译打包,刷新浏览器,特别麻烦,我们可以通过安装 webpackDevServer 来改善这方面的体验。其功效很类似于vscode提供的插件:Live Server。每次我们更新代码时,devserver就会自动编译打包代码,并刷新浏览器(默认全局刷新)。
- 安装
npm install --save-dev webpack-dev-server
-
启用
- 在命令行借助npx启用
npx webpack-dev-server- 先在package.json的script中增加如下字段,然后在命令行中使用
npm run build启用
..., "scripts": { "build": "webpack-dev-server" //可以自动在./node_moudle/.bin/目录下查找对应的webpack-dev-server文件 } -
配置
//webpack.config.js
module.exports = {
...,
devServer: {
// 生成的虚拟目录路径
contentBase: "./dist",
// 自动开启浏览器
open: true,
// devServer端口(默认8080)
port: 8888
}
}
以下是devServer常用的配置选项:代理和局部热更新。更多配置相关API参见官网。
Proxy
主要用于解决跨域请求问题,原理为后端代理。
跨域:一种存在于浏览器上的安全策略;后端服务器上不存在跨域问题。
日常开发过程中,比如devserver配置的监听端口是8888,而后端某个特定服务API接口运行在8081端口上,那么当我们在某些业务逻辑上需要请求该API时就出现了跨域问题。这时候就需要通过devServer.proxy配置来进行处理。
- 配置
//webpack.config.js
module.exports = {
...,
devServer: {
// 生成的虚拟目录路径
contentBase: "./dist",
// 自动开启浏览器
open: true,
// devServer端口
port: 8888,
proxy: {
'/api': {
target: 'http://localhost:8081' //8081指向API运行的服务器端口
}
}
}
}
要注意的是,前端代码依旧运行在devServer的环境下,也就是http://localhost:8888,当他调用/api的时候发往后端的请求是http://localhost:8888/api,devServer接收到请求之后再转发给8081端口,devServer实际发送的请求是http://localhost:8081/api
Hot Module Replacement
本身devServer是支持自动刷新页面的,使用的是live loader,但是这个是每当代码发生变化时自动刷新整个页面,而在实际工作中刷新整个页面往往会带来一些不方便的因素:比如,当页面中表单或者input框之类的,刷新就会丢掉填好的数据。为了解决这个问题,devServer为我们提供了不刷新整个月面而是局部刷新的方式。
模块热替换(HMR - hot module replacement)功能会在应用程序运行过程中,替换、添加或删除模块,而无需重新加载整个页面。主要是通过以下几种方式,来显著加快开发速度:
- 保留在完全重新加载页面期间丢失的应用程序状态。
- 只更新变更内容,以节省宝贵的开发时间。
- 在源代码中 CSS/JS 产生修改时,会立刻在浏览器中进行更新,这几乎相当于在浏览器 devtools 直接更改样式。
摘自官方文档
- 配置
//webpack.config.js
module.exports = {
...,
devServer: {
contentBase: "./dist",
open: true,
port: 8888,
// 开启热更新
hot:true,
// 即使 HMR 不生效,也不去刷新整个页面(选择开启)
hotOnly:true,
}
}
}
-
使用
- 当开启HMR之后,将会暴露出一个module.hot属性。此时,当代码发生变化的时候,devServer就会立刻进行编译并通知浏览器进行局部刷新。因此我们需要对事件进行监听,当我们需要对模块发生变化的时候,进行立刻的局部刷新。
//fn1.js export default function() { console.log('fn1模块执行了 -1'); }//index.js import fn1 from './fn1.js'; box1.onclick = fn1; if (module.hot) {//如果开启 HMR module.hot.accept('./fn1.js', function() { // accept方法,当监听事件发生变化时,接受并触发一个回调函数来响应更新 box1.onclick = fn1; }) }
以上便是对webpack学习的一些初步认识和探索,文章中的内容主要来自于:
1.开课吧课程内容:www.kaikeba.com/
2.webpack官方文档:webpack.js.org/concepts/
3.自己的理解