const {
SyncHook, // 同步 執行
SyncBailHook, // 同步執行,可是一旦有返回值,就執行退出,再也不繼續執行其餘
AsyncParallelHook, // 異步 並行執行
AsyncSeriesBailHook, // 異步 串行執行
} = require('tapable');css
class Lesson {
constructor() {
// 初始化 hook容器
this.hooks = {
// 同步鉤子,任務會依次執行
// go: new SyncHook(['address']),
go: new SyncBailHook(['address']), // 一旦有返回值,就不會再往下執行了
// 異步hooks
// AsyncParallelHook 異步並行
// leave: new AsyncParallelHook(['name', 'age']),
leave: new AsyncSeriesBailHook(['name', 'age']),
};
}webpack
tap() {
// 往hooks 容器中註冊事件/ 添加回調函數
this.hooks.go.tap('class001', (address) => {
console.log('class001', address);
return 111;
});
this.hooks.go.tap('class002', (address) => {
console.log('class002', address);
});web
this.hooks.leave.tapAsync('class003', (name, age, cb) => { setTimeout(() => { console.log('class003', name, age); cb(); }, 2000); }); this.hooks.leave.tapPromise('class004', (name, age) => { return new Promise((resolve) => { setTimeout(() => { console.log('class004', name, age); resolve(); }, 1000); }); });
}json
start() {
this.hooks.go.call('c318');
this.hooks.leave.callAsync('zh', '18', () => {
// 表明全部leave容器中的函數觸發完了,才觸發
console.log('end');
});
}
}
const l = new Lesson();
l.tap();
l.start();數組
##### 2 complier 類 擁有各類鉤子函數 ```js class Plugin1 { apply(complier) { complier.hooks.emit.tap('Plugin1', () => { console.log('emit 111111111111'); }); complier.hooks.afterEmit.tap('Plugin1', () => { console.log('emit after 111111111111'); }); } } module.exports = Plugin1;
const fs = require('fs'); const util = require('util'); const path = require('path'); const { RawSource } = require('webpack-sources'); // 將fs . readFile 的異步方法,改變成同步的寫法 const readFile = util.promisify(fs.readFile); class Plugin2 { apply(compiler) { // 初始化compilation 的鉤子 compiler.hooks.thisCompilation.tap('Plugin2', (compilation) => { // debugger; // console.log(compilation); compilation.hooks.additionalAssets.tapAsync('Plugin2', async (cb) => { const content = 'debug'; // 往要輸出資源中,添加一個a.txt compilation.assets['a.txt'] = { size() { return content.length; }, // 文件大小 source() { return content; }, // 文件內容 }; const data = await readFile(path.resolve(__dirname, '../b.txt')); compilation.assets['b.txt'] = new RawSource(data); compilation.emitAsset('c.txt', new RawSource(data)); cb(); }); }); } } module.exports = Plugin2;
const path = require('path'); const fs = require('fs'); const {promisify} = require('util') const { validate } = require('schema-utils'); const globby = require('globby'); const webpack = require('webpack'); const schema = require('./schema.json'); const { Compilation } = require('webpack'); const readFile = promisify(fs.readFile); const {RawSource} = webpack.sources class CopyWebpackPlugin { constructor(options = {}) { // 驗證options是否符合規範 validate(schema, options, { name: 'CopyWebpackPlugin' }) this.options = options; } apply(compiler) { // 初始化compilation compiler.hooks.thisCompilation.tap('CopyWebpackPlugin', (compilation) => { // 添加資源的hooks compilation.hooks.additionalAssets.tapAsync('CopyWebpackPlugin', async (cb) => { // 將from中的資源複製到to中,輸出出去 const { from, ignore } = this.options; const to = this.options.to ? this.options.to : '.'; // context就是webpack配置 // 運行指令的目錄 const context = compiler.options.context; // process.cwd() // 將輸入路徑變成絕對路徑 const absoluteFrom = path.isAbsolute(from) ? from : path.resolve(context, from); // 1. 過濾掉ignore的文件 // globby(要處理的文件夾,options) const paths = await globby(absoluteFrom, { ignore }); console.log(paths); // 全部要加載的文件路徑數組 // 2. 讀取paths中全部資源 const files = await Promise.all( paths.map(async (absolutePath) => { // 讀取文件 const data = await readFile(absolutePath); // basename獲得最後的文件名稱 const relativePath = path.basename(absolutePath); // 和to屬性結合 // 沒有to --> reset.css // 有to --> css/reset.css const filename = path.join(to, relativePath); return { // 文件數據 data, // 文件名稱 filename } }) ) // 3. 生成webpack格式的資源 const assets = files.map((file) => { const source = new RawSource(file.data); return { source, filename: file.filename } }) // 4. 添加compilation中,輸出出去 assets.forEach((asset) => { compilation.emitAsset(asset.filename, asset.source); }) cb(); }) }) } } module.exports = CopyWebpackPlugin;