处理 webpack 在编译过程中的某个特定任务的功能模块,plugins
选项用于以各种方式自定义 webpack 构建过程。其中webpack 附带了各种内置插件,可以通过 webpack.[plugin-name]
访问这些插件。
webpack 打包的整个过程,它并不直接操作文件,而是基于事件机制工作,会监听 webpack 打包过程中的某些节点,执行广泛的任务。
简化了html文件的创建,以便为webpack包提供服务。该插件将生成一个 HTML5 文件,所有的 bundle 会自动添加到 html 中。
具体插入方式是将样式link
插入到head
元素中,script
插入到head
或者body
中。
npm install html-webpack-plugin --save-dev
const HtmlWebpackPlugin = require('html-webpack-plugin'); module.exports = { // ... plugins: [ new HtmlWebpackPlugin({ title: 'HtmlWebpackPlugin 插件学习', minify: { removeComments: true, // 移除HTML中的注释 collapseWhitespace: true, // 删除空白符与换行符 minifyCSS: true, // 压缩内联css }, inject: "head", // 表示script标签插入位置,true(默认值), body, head, false(不插入) }) ], };
多页应用打包:
const path = require('path') const HtmlWebpackPlugin = require('html-webpack-plugin') module.exports = { entry: { index: './src/index.js', login: './src/login.js', }, output: { filename: '[name].bundle.js', path: path.resolve(__dirname, 'dist'), }, plugins: [ new HtmlWebpackPlugin({ filename: 'index.html', // 多个HtmlWebpackPlugin, filename字段不可缺省,否则默认生成的都是 index.html。 }), new HtmlWebpackPlugin({ filename: 'login.html', }), ], }
但是会发现 index.html
和 login.html
同时引入了 index.bundle.js
和 login.bundle.js
,而通常只希望 index.html
中只引入 index.bundle.js
,login.html
只引入 login.bundle.js
。
HtmlWebpackPlugin
提供了一个 chunks
的参数,可以接受一个数组,配置此参数仅会将数组中指定的 js 引入到 html 文件中
module.exports = { plugins: [ new HtmlWebpackPlugin({ filename: 'index.html', chunks: ['index'], // index.html 中仅引入了 index.js 文件 }), new HtmlWebpackPlugin( filename: 'login.html', chunks: ['login'], // login.html 中仅引入了 login.js 文件 }), ], }
在每次构建前清理 /dist
文件夹,用于生产环境,因为生产环境会生成许多bundle文件,不及时清理的话每次都生成新的,导致文件夹比较大,打包前清理上一次生成的 bundle 文件是比较推荐的做法,因此只会生成用到的文件。
npm install clean-webpack-plugin --save-dev
const CleanWebpackPlugin = require('clean-webpack-plugin'); module.exports = { // ... plugins: [ new CleanWebpackPlugin({ // cleanStaleWebpackAssets 清除过时的网页包资产 cleanStaleWebpackAssets: false // 防止监听到改变时把没有改变的文件给清除了(当文件改变后不删除index.html文件) }) ], };
能够对「模块映射到输出 bundle 的过程」保持追踪。可以将数据提取到一个 json 文件中;说白了就是生成一个manifest.json 默认文件名, 是一个文件清单, 内容是打包前文件对应打包后的文件名。
npm install webpack-manifest-plugin --save-dev
const { WebpackManifestPlugin } = require('webpack-manifest-plugin'); module.exports = { // ... plugins: [ new WebpackManifestPlugin() // 可以接受一个options 参数,默认在dist目录下生成 manifest.json ] };
允许在运行时更新各种模块,而无需进行完全刷新。不适用于生产环境,意味着应当只在开发环境使用。启用HMR实际上就是更新 webpack-dev-server
的配置,及使用 webpack 内置的 HMR 插件。
const webpack = require('webpack'); module.exports = { plugins: [ new webpack.HotModuleReplacementPlugin(), ], devServer: { hot: true }, };
webpack要完全启用HMR需要使用webpack.HotModuleReplacementPlugin。如果webpack或webpack-dev-server 通过命令行添加 --hot 选项启动,该插件会自动添加,因此不需要将它添加到webpack.config.js中
但是经实际使用 webpack-dev-server 时发现,在webpack.config.js中仅仅配置了devServer.hot:true
,并未添加上述插件时仍然实现了HMR
原来 webpack-dev-server 内部自动帮我们完成了这个事情。通过在Github 的 webpack-dev-server 搜索,找到以下源码:
if (options.hot || options.hotOnly) { config.plugins = config.plugins || []; // 判断了配置的插件中是否包含名为HotModuleReplacementPlugin的插件,如果没有则添加。 if ( !config.plugins.find( // Check for the name rather than the constructor reference in case // there are multiple copies of webpack installed (plugin) => plugin.constructor.name === 'HotModuleReplacementPlugin' ) ) { config.plugins.push(new webpack.HotModuleReplacementPlugin()); } }