使用 webpack API 中的 compiler 钩子,可以在特定的时期进行操作
compiler 钩子
Compiler 模块是 webpack 的支柱引擎,它通过 CLI 或 Node API 传递的所有选项,创建出一个 compilation 实例。它扩展(extend)自 Tapable 类,以便注册和调用插件。大多数面向用户的插件首,会先在 Compiler 上注册。
此模块会暴露在 webpack.Compiler,可以直接通过这种方式使用。关于更多信息,请查看这个示例。
监听(watching)
Compiler
支持可以监控文件系统的 监听(watching) 机制,并且在文件修改时重新编译。当处于监听模式(watch mode)时,compiler 会触发诸如 watchRun
, watchClose
和invalid
等额外的事件。通常用于 开发环境 中使用,也常常会在 webpack-dev-server
这些工具的底层之下调用,由此开发人员无须每次都使用手动方式重新编译。还可以通过 CLI 进入监听模式。
相关钩子
以下生命周期钩子函数,是由 compiler 暴露,可以通过如下方式访问:
compiler.hooks.someHook.tap(...)
取决于不同的钩子类型,也可以在某些钩子上访问 tapAsync 和 tapPromise。
这里我们使用 emit 钩子 (生成资源到 output 目录之前。)
remove-comments-plugin.js
class RemoveCommentsPlugin {
apply(compiler) {
compiler.hooks.emit.tap('RemoveCommentsPlugin', compilation => {
// compilation 可以理解为此次打包的上下文
// 使用 compilation 对象的 assets 属性可以获取文件名称信息
for( const name in compilation.assets) {
// console.log(name);
// 通过 source() 方法,获取文件中的内容
// console.log(compilation.assets[name].source());
// 处理 .js 文件中的注释,先判断获取 .js 文件,使用 endsWith() 方法
if (name.endsWith('.js')) {
// 定义source()方法
const contents = compilation.assets[name].source()
// 使用正则替换掉注释
const noComments = contents.replace(/\/\*{2,}\/\s?/g,'')
// 替换后覆盖掉原内容,根据 webpack 格式要求,暴露以下方法
// 暴露 source() 方法,返回新的内容
// 暴露 size() 方法,返回新内容大小
compilation.assets[name]= {
source: () => noComments,
size: () => noComments.length
}
}
}
})
}
}
module.exports = RemoveCommentsPlugin
在 webpack.config.js 中引入插件
webpack.config.js
const HtmlWebpackPlugin = require('html-webpack-plugin');
const {CleanWebpackPlugin} = require('clean-webpack-plugin')
const CopyWebpackPlugin = require('copy-webpack-plugin');
const path = require('path');
const RemoveCommentsPlugin = require('./remove-comments-plugin') // 自定义插件
module.exports = {
entry: './path/to/my/entry/file.js',
output: {
/**
* With zero configuration,
* clean-webpack-plugin will remove files inside the directory below
* clean-webpack-plugin将删除下面目录中的文件
*/
path: path.resolve(process.cwd(), 'dist'),
},
module: {
rules: [
{
test: /\.(js|jsx)$/,
loader: 'babel-loader',
},
],
},
plugins: [
new CleanWebpackPlugin(),
new HtmlWebpackPlugin({
title: 'My App', // 标题
filename: 'index.html', // 输出文件名
}),
new CopyWebpackPlugin({
patterns: [
{ from: "source", to: "dest" }, // 'from' 我们сopy文件所在的Glob或路径
{ from: "other", to: "public" }, // 'to' 打包输出路径
],
}),
new RemoveCommentsPlugin() // 自定义插件
],
};
build 之后,可以看到注释已经被清除