webpack 的核心功能,是抽離成很多個(gè)內(nèi)部插件來實(shí)現(xiàn)的现恼。
1剂跟、 webpack 配置文件處理
2哀军、文件位置解析
webpack 需要從入口文件開始,順藤摸瓜找到所有的文件
3、加載文件
4、文件解析,從解析結(jié)果中找到文件引入的其他文件,文件位置解析
5、找到所有對應(yīng)的 loader窗悯,然后逐個(gè)執(zhí)行
處理完整入口文件之后,得到依賴的其他文件偷拔,遞歸進(jìn)行處理蒋院。最后得到了所有文件的 module 。最終輸出的是打包完成的 bundle 文件莲绰。所以會(huì)有
6欺旧、module 合并成 chunk 中 輸出最終文件
內(nèi)部插件是如何對 webpack 產(chǎn)生作用的呢?
- 先創(chuàng)建一個(gè) Compiler 實(shí)例,然后調(diào)用 WebpackOptionsApply
- 這個(gè)模塊給 Compiler 實(shí)例添加內(nèi)部插件:
// https://github.com/webpack/webpack/blob/master/lib/webpack.js#L37
compiler = new Compiler();
// 其他代碼..
compiler.options = new WebpackOptionsApply().process(options, compiler);
- 在 WebpackOptionsApply 這個(gè)插件內(nèi)部會(huì)根據(jù)我們傳入的 webpack 配置來初始化需要的內(nèi)部插件:
JsonpTemplatePlugin = require("./JsonpTemplatePlugin");
NodeSourcePlugin = require("./node/NodeSourcePlugin");
compiler.apply(
new JsonpTemplatePlugin(options.output),
new FunctionModulePlugin(options.output),
new NodeSourcePlugin(options.node),
new LoaderTargetPlugin(options.target)
);
// 其他代碼..
compiler.apply(new EntryOptionPlugin());
compiler.applyPluginsBailResult("entry-option", options.context, options.entry);
compiler.apply(
new CompatibilityPlugin(),
new HarmonyModulesPlugin(options.module),
new AMDPlugin(options.module, options.amd || {}),
new CommonJsPlugin(options.module),
new LoaderPlugin(),
new NodeStuffPlugin(options.node),
new RequireJsStuffPlugin(),
new APIPlugin(),
new ConstPlugin(),
new UseStrictPlugin(),
new RequireIncludePlugin(),
new RequireEnsurePlugin(),
new RequireContextPlugin(options.resolve.modules, options.resolve.extensions, options.resolve.mainFiles),
new ImportPlugin(options.module),
new SystemPlugin(options.module)
);
- 每一個(gè)內(nèi)部插件蛤签,都是通過監(jiān)聽任務(wù)點(diǎn)的方式辞友,來實(shí)現(xiàn)自定義的邏輯
參考文章:
https://juejin.cn/post/6844903726981840904
https://cloud.tencent.com/developer/article/1006353