自定义plugin
-
Table与webpack
-
webpack中有Compile和Compilation,他们通过插件注入的方式监听webpack的生命周期
-
Table
这个库存在着各种个样的Hook实例,这个hook就可以帮助我们监听webpack生命周期- 同步
const {SyncHook, SyncBailHook, SyncLoopHook, SyncWaterfallHook} = require("tapable"); class test { constructor(){ this.hooks = { // syncHook: new SyncHook(["name", "age"]), // 同步依次执行 // syncHook: new SyncBailHook(["name", "age"]), // 在监听过程中,出现有返回值就不会在执行了 // syncHook: new SyncLoopHook(["name", "age"]) // 监听过程中返回值为true,那么这个回掉函数就会一直执行 // 当有返回值的时候,就会把返回值传递到下一次回掉作为 第一个 参数,前提是返回的值不是undefined syncHook: new SyncWaterfallHook(["name", "age"]) } this.hook.syncHook.tap("e1", (name, xx) => { // .. }) this.hook.syncHook.tap("e2", (name, xx) => { // .. }) } emit(){ this.hook.syncHook.call(..,参数) } }
- 异步
const {AsyncSeriesHook, AsyncParalleHook} = require("tapable"); class test { constructor(){ this.hooks = { // series: 在一个hook中,监听多次事件(多个回掉函数),这些回掉函数会穿行执行,即会等到上一个回掉执行完成才会继续 // asyncHook: new AsyncParallelHook(["name", "age"]) // Parallel:在一个hhok中监听了多次事件,会并行执行,不会等待上一个函数是否执行完成 asyncHook: new AsyncParallelHook(["name", "age"]) } this.hook.syncHook.tapAsync("e1", (name, xx) => { // .. }) this.hook.syncHook.tapAsync("e2", (name, xx) => { // .. }) } emit(){ this.hook.asyncHook.callAsync(..,参数) } }
- promise, 同样受到并行串行限制
const {AsyncSeriesHook, AsyncParalleHook} = require("tapable"); class test { constructor(){ this.hooks = { // series: 在一个hook中,监听多次事件(多个回掉函数),这些回掉函数会穿行执行,即会等到上一个回掉执行完成才会继续 // asyncHook: new AsyncParallelHook(["name", "age"]) // Parallel:在一个hhok中监听了多次事件,会并行执行,不会等待上一个函数是否执行完成 asyncHook: new AsyncParallelHook(["name", "age"]) } this.hook.asyncHook.tapPromise("e1". (name,age) => { return new Promise((res, rej) => { setTimeout(() => { // xxx res() },0) }) }) } emit(){ this.hook.asyncHook.promise(..,参数).then(() => { // .. }) } }
-
-
自定义plugin
-
const { NodeSSH } = require('node-ssh'); class CustomPlugin { constructor(options) { this.ssh = new NodeSSH(); this.options = options; } apply(compiler) { // 这里你可以监听任何生命周期hook compiler.hooks.afterEmit.tapAsync("CustomPlugin", async (compilation, callback) => { // 1.获取输出的文件夹 const outputPath = compilation.outputOptions.path; // 2.连接服务器(ssh连接) await this.connectServer(); // 3.删除原来目录中的内容 const serverDir = this.options.remotePath; await this.ssh.execCommand(`rm -rf ${serverDir}/*`); // 4.上传文件到服务器(ssh连接) await this.uploadFiles(outputPath, serverDir); // 5.关闭ssh this.ssh.dispose(); // plugin在被注册过程中会得到 compilation 对象 callback() }) } async connectServer() { await this.ssh.connect({ host: this.options.host, username: this.options.username, password: this.options.password }); console.log("连接成功~"); } async uploadFiles(localPath, remotePath) { const status = await this.ssh.putDirectory(localPath, remotePath, { recursive: true, concurrency: 10 }); console.log('传送到服务器: ', status ? "成功": "失败"); } } // 使用 const path = require('path'); const HtmlWebpackPlugin = require('html-webpack-plugin'); const AutoUploadPlugin = require("./plugins/AutoUploadPlugin"); module.exports = { entry: "./src/main.js", output: { path: path.resolve(__dirname, "./build"), filename: "bundle.js" }, plugins: [ new HtmlWebpackPlugin(), new AutoUploadPlugin({ host: "", username: "", password: "", removePath: "/root/test" }) ] }
-