实现一个 Webpack 插件把构建信息(如 hash)写进一个文件。
写一个 Webpack 插件就是实现一个类或函数,并在原型上定义 apply 方法。
class 版本
const fs = require('fs')
class BuildInfoPlugin {
constructor({ filename = 'dist/buildinfo.json' } = {}) {
this.filename = filename
}
apply(compiler) {
compiler.hooks.done.tap(this.constructor.name, stats => {
const buildInfo = {
hash: stats.hash
}
return new Promise((resolve, reject) => {
fs.writeFile(
this.filename,
JSON.stringify(buildInfo),
'utf8',
error => {
if (error) {
reject(error)
return
}
resolve()
}
)
})
})
}
}
new BuildInfoPlugin({ filename: 'dist/hash.json' })
function 版本
使用 function 实现一个 class
- class 只能通过 new 调用
- class 中的函数不能被枚举
- class 中的函数不能被 new 调用
- 在 ES6 中使用 class 语法,代码都是在严格模式下运行
'use strict' // 在 ES6 中使用 class 语法,代码都是在严格模式下运行
function BuildInfoPlugin({ filename = 'dist/buildinfo.json' } = {}) {
if (!(this instanceof BuildInfoPlugin)) {
// class 只能通过 new 调用
throw new TypeError(
"TypeError: Class constructor BuildInfoPlugin cannot be invoked without 'new'"
)
}
this.filename = filename
}
Object.defineProperty(BuildInfoPlugin.prototype, 'apply', {
value: function(compiler) {
if (!(this instanceof BuildInfoPlugin)) {
// class 中的函数不能被 new 调用
throw new TypeError('TypeError: apply is not a constructor')
}
compiler.hooks.done.tap(this.constructor.name, stats => {
const buildInfo = {
hash: stats.hash
}
return new Promise((resolve, reject) => {
fs.writeFile(
this.filename,
JSON.stringify(buildInfo),
'utf8',
error => {
if (error) {
reject(error)
return
}
resolve()
}
)
})
})
},
enumerable: false // class 中的函数不能被枚举
})
hash.json
{"hash":"abee8f136a3edc8d9418"}
前端可以利用 hash 判断用户是否在旧页面,提示用户刷新。