plugins:插件
在vue项目开发中,通常在vue.config.js中会配置webpack的相关配置
其中在plugins中配置相关的插件
plugins:[
new xxx(), // 使用相关插件
new xxx(),
...
]
核心plugins钩子:compiler
和 compilation
对象
Plugin通过访问Compiler和Compilation对象来完成工作。
一、
compiler是webpack的入口执行实例,其主要功能是监控代码、启动和终止一个compilation等宏观任务。compilation是具体负责核心编译工作的,主要是模块依赖分析,优化、连接,打包等工作。打个粗略的比方,compiler是人,compilation是人的大脑,架构设计上是类似的。
给webpack写plugin的时候,我们需要通过compiler提供的钩子来tap宏观生命周期,其中一个最主要的阶段就是compilation(创建编译对象)的hook,通过该hook,我们拿到编译对象,从而得以进一步tap入实际的编译过程。
二、
compiler 在 webpack 构建之初就已经创建,并且贯穿webpack整个生命周 ( before - run - beforeCompiler - complie - make - finishMake - afterComplier - done)
只要是做webpack编译,都会先创建一个compiler
compilation是到准备编译模块时,才会创建compilation对象
是 compile - make 阶段主要使用的对象
|----src
|----main.js
|----plugins
|----my-webpack-plugin.js
|----package.json
|----webpack.config.js
// my-webpack-plugin.js
// 一个 JavaScript 类
class MyExampleWebpackPlugin {
// 在插件函数的 prototype 上定义一个 `apply` 方法,以 compiler 为参数。
apply(compiler) {
// 指定一个挂载到 webpack 自身的事件钩子。
compiler.hooks.emit.tapAsync(
'MyExampleWebpackPlugin',
(compilation, callback) => {
console.log('这是一个示例插件!');
console.log(
'这里表示了资源的单次构建的 `compilation` 对象:',
compilation
);
callback&&callback();
}
);
}
}
// public/index.html
<script>
console.log("v:5.7 Tue Mar 29 2022 13:51:05 GMT+0800");
</script>
// plugins/set-version.js
const fs = require('fs')
const moment = require("moment");
class setVersion {
apply(compiler) {
// environment钩子:在编译器准备环境时调用, 时机就在配置文件中初始化插件之后。
compiler.hooks.environment.tap(
"setVersion",
(compilation, callback) => {
this.setVersion('./public/index.html', './versions.json')
callback && callback();
}
)
}
/**
* @description: 在versions.json文件中记录的版本号上增加并重新写入增加后的值,再根据正则匹配到index.html文件中对应位置进行修改写入
* @param {*} htmlPath
* @param {*} versionPath
*/
setVersion(htmlPath, versionPath) {
// 读取version.json和html文件
const readVersion = fs.readFileSync(versionPath, 'utf8');
const readHtml = fs.readFileSync(htmlPath, 'utf8');
// 获取当前version
let {
version,
unix
} = JSON.parse(readVersion)
const nowUnix = moment().format('X')
const nowTime = moment()
let str = ""
if (unix && nowUnix - unix > 120) { // 120s内打包都会使用同一个版本号
// version增加0.1
let NewVersion = (Number(version) + 0.1).toFixed(1)
// 写入version.json文件
fs.writeFileSync(versionPath, JSON.stringify({
version: NewVersion,
unix: nowUnix
}));
// 编辑html(根据正则匹配到console.log("v: 字符串进行修改)
str = readHtml.toString().replace(/console.log\("v:.*\)/g, `console.log("v:${NewVersion} ${nowTime}")`)
} else {
// 编辑html(根据正则匹配到console.log("v: 字符串进行修改)
str = readHtml.toString().replace(/console.log\("v:.*\)/g, `console.log("v:${version} ${nowTime}")`)
}
// 写入html文件
fs.writeFileSync(htmlPath, str);
}
}
module.exports = setVersion
// 根目录下创建 versions.json,记录版本号
{"version":"5.7","unix":"1648533016"}
// vue.config.js
const setVersion = require('./plugins/set-version')
module.exports = {
configureWebpack:{
plugins: [
new setVersion() // 使用插件
]
}
}
结束:这样在每次打包时都会自动更新版本号并添加当前日期