揭秘webpack插件工作流程和原理( 三 )

MyPlugin.js
const Compiler = require('./Compiler')class MyPlugin{    apply(compiler){//接受 compiler参数        compiler.hooks.run.tap("MyPlugin", () => console.log('开始编译...'));        compiler.hooks.compile.tapAsync('MyPlugin', (name, age) => {          setTimeout(() => {            console.log('编译中...')          }, 1000)        });    }}//这里类似于webpack.config.js的plugins配置//向 plugins 属性传入 new 实例const myPlugin = new MyPlugin();const options = {    plugins: [myPlugin]}let compiler = new Compiler(options)compiler.run()【揭秘webpack插件工作流程和原理】想要深入了解tapable的文章可以看看这篇文章:
webpack4核心模块tapable源码解析: https://www.cnblogs.com/tugenhua0707/p/11317557.html
理解Compiler(负责编译)开发插件首先要知道compiler和 compilation 对象是做什么的
Compiler 对象包含了当前运行Webpack的配置,包括entry、output、loaders等配置,这个对象在启动Webpack时被实例化,而且是全局唯一的 。Plugin可以通过该对象获取到Webpack的配置信息进行处理 。
如果看完这段话,你还是没理解compiler是做啥的,不要怕,接着看 。运行npm run build,把compiler的全部信息输出到控制台上console.log(Compiler) 。

揭秘webpack插件工作流程和原理

文章插图
 
compiler
// 为了能更直观的让大家看清楚compiler的结构,里面的大量代码使用省略号(...)代替 。Compiler {  _pluginCompat: SyncBailHook {    ...  },  hooks: {    shouldEmit: SyncBailHook {     ...    },    done: AsyncSeriesHook {     ...    },    additionalPass: AsyncSeriesHook {     ...    },    beforeRun: AsyncSeriesHook {     ...    },    run: AsyncSeriesHook {     ...    },    emit: AsyncSeriesHook {     ...    },    assetEmitted: AsyncSeriesHook {     ...    },    afterEmit: AsyncSeriesHook {     ...    },    thisCompilation: SyncHook {     ...    },    compilation: SyncHook {     ...    },    normalModuleFactory: SyncHook {     ...    },    contextModuleFactory: SyncHook {     ...    },    beforeCompile: AsyncSeriesHook {      ...    },    compile: SyncHook {     ...    },    make: AsyncParallelHook {     ...    },    afterCompile: AsyncSeriesHook {     ...    },    watchRun: AsyncSeriesHook {     ...    },    failed: SyncHook {     ...    },    invalid: SyncHook {     ...    },    watchClose: SyncHook {     ...    },    infrastructureLog: SyncBailHook {     ...    },    environment: SyncHook {     ...    },    afterEnvironment: SyncHook {     ...    },    afterPlugins: SyncHook {     ...    },    afterResolvers: SyncHook {     ...    },    entryOption: SyncBailHook {     ...    },    infrastructurelog: SyncBailHook {     ...    }  },  ...  outputPath: '',//输出目录  outputFileSystem: NodeOutputFileSystem {   ...  },  inputFileSystem: CachedInputFileSystem {    ...  },  ...  options: {    //Compiler对象包含了webpack的所有配置信息,entry、module、output、resolve等信息    entry: [      'babel-polyfill',      '/Users/frank/Desktop/fe/fe-blog/webpack-plugin/src/index.js'    ],    devServer: { port: 3000 },    output: {      ...    },    module: {      ...    },    plugins: [ MyWebpackPlugin {} ],    mode: 'production',    context: '/Users/frank/Desktop/fe/fe-blog/webpack-plugin',    devtool: false,    ...    performance: {      maxAssetSize: 250000,      maxEntrypointSize: 250000,      hints: 'warning'    },    optimization: {      ...     },    resolve: {      ...    },    resolveLoader: {      ...    },    infrastructureLogging: { level: 'info', debug: false }  },  context: '/Users/frank/Desktop/fe/fe-blog/webpack-plugin',//上下文,文件目录  requestShortener: RequestShortener {    ...  },  ...  watchFileSystem: NodeWatchFileSystem {    //监听文件变化列表信息     ...  }}


推荐阅读