博客
电影
宝箱
友链
关于
<
Webpack自动更新php静态资源文件名hash
《一个青年艺术家的画像》读后感
>
Webpack构建流程之源码分析
作者:
Cifer
类别: 技术
时间:2019-10-11 01:35:33
字数:4112
版权所有,未经允许,请勿转载,谢谢合作~
写本文之前,其实Cifer也在网上参考了不少例子,发现关于Webpack基于原码分析构建流程的文章,已经不仅仅是“一千个读者就有一千个哈姆雷特”,而是“一千个读者就有一万个堂吉诃德”,有时我在想,大家说的是同一个Webpack吗? 直到我写时,才发现真是这么回事。 环境: node@v10.15.3 webpack@4.40.2 npm@6.4.1 webpack-cli@3.3.9 #### 从npm run build 开始说起 既然说到原码,第一个疑问就是,为什么在命令行执行npm run build,webpack就开始运行了? ``` npm run build ``` 在项目中根目录package.json配置了该命令: ```json { "scripts": { "build": "webpack" } } ``` 假设webpack是安装在项目中而不是全局中,根据npm的规则,npm run build相当于执行了 ``` ./node_modules/.bin/webpack ``` 而./node_modules/.bin/webpack,它其实是webpack包中bin内的入口文件,比如是./node_modules/webpack/bin/webpack.js,两者之间是文件与软链的关系,这个对应关系一般是在模块的package.json配置,如webpack是: ./node_modules/webpack-cli/package.json ```json { "bin": { "webpack": "./bin/webpack.js" } } ``` #### webpack-cli与webpack-command 由上可知,我们实际执行了: ./node_modules/webpack/bin/webpack.js ```javascript const CLIs = [ { name: "webpack-cli", package: "webpack-cli", binName: "webpack-cli", alias: "cli", installed: isInstalled("webpack-cli"), recommended: true, url: "https://github.com/webpack/webpack-cli", description: "The original webpack full-featured CLI." }, { name: "webpack-command", package: "webpack-command", binName: "webpack-command", alias: "command", installed: isInstalled("webpack-command"), recommended: false, url: "https://github.com/webpack-contrib/webpack-command", description: "A lightweight, opinionated webpack CLI." } ]; ``` 它会选择两者之一运行命名与配置。 因为版本是4+,webpack的命令抽出了单独的模块,官方推荐的是webpack-cli,当然也webpack-command替代模块,不过我们一般使用前者,即/node_modules/webpack-cli/bin/cli.js。 #### webpack-cli 同理,会执行webpack-cli入口文件: ./node_modules/webpack-cli/bin/cli.js ```javascript yargs.parse(process.argv.slice(2), (err, argv, output) => { function processOptions(options) { const webpack = require("webpack"); let compiler; try { compiler = webpack(options); } catch (err) { throw err; } compiler.run() } rocessOptions(options); }) ``` yargs 是shell与node交互的模块,这里将获取shell上的命令。require的webpack是webpack.Compiler,实例化这个编译器对象Compiler,调用run方法. #### webpack Compiler ./node_modules/webpack/lib/Compiler.js ```javascript class Compiler extends Tapable { run(callback) { this.hooks.beforeRun.callAsync(this, err => { this.hooks.run.callAsync(this, err => { this.readRecords(err => { this.compile(onCompiled); }); }); }); } compile(callback) { const params = this.newCompilationParams(); this.hooks.beforeCompile.callAsync(params, err => { this.hooks.compile.call(params); const compilation = this.newCompilation(params); this.hooks.make.callAsync(compilation, err => { compilation.finish(err => { compilation.seal(err => { this.hooks.afterCompile.callAsync(compilation, err => { return callback(null, compilation); }); }); }); }); }); } emitAssets() {} const onCompiled = (err, compilation) => { this.emitAssets(compilation, err => { }) } } ``` run中执行编译compile,经历各类中间过程,最终完成编译,并生成资源emitAssets。 在编译器对象的执行我们的资源编译对象compilation,无论是Compiler还是compilation拥有众多的勾子,我们可以用plugin监听它们,并改变结果。 #### webpack Compilation ```javascript class Compilation extends Tapable { addEntry(context, entry, name, callback) { this._addModuleChain() } _addModuleChain(context, dependency, onModule, callback) { } processModuleDependencies(module, callback) { this.addModuleDependencies() } addModuleDependencies( module, dependencies, bail, cacheGroup, recursive, callback ) { const afterBuild = () => { this.processModuleDependencies(dependentModule, callback); } this.buildModule() } buildModule(module, optional, origin, dependencies, thisCallback) {} seal(callback) {} } ``` addEntry 找到入口文件 processModuleDependencies 处理模块关系 buildModule 构建 seal 构建chunk …… 其实所谓的过程,只是Compiler与Compilation的执行顺序,原码及官方文档都有详细的,就不一一列举了: Compiler : <a href="https://webpack.js.org/api/compiler-hooks/" target="_blank" ref="nofollow">https://webpack.js.org/api/compiler-hooks/</a> Compilation: <a href="https://webpack.js.org/api/compilation-hooks/" target="_blank" ref="nofollow">https://webpack.js.org/api/compilation-hooks/</a> 基于对应的勾子,组合一下,选择你认为核心部分,就可以编出各种“webpack构建流程”。
如果觉得有帮忙,您可以在本页底部留言。
相关推荐:
从youtube观看记录分析时长
Webpack深入浅出plugin
Webpack自动更新php静态资源文件名hash
Webpack基于scss生成css独立文件
Webpack深入浅出loader
移动端浏览器真机调试的几种方法
接入台湾超商门店地址选择
ember入门教程
Ember之Handlebars模板引擎
Mac高频快捷键之前端篇
简述浏览器缓存之cookie
浏览器打开页面的过程中发生了什么
Git命令简化笔记
PHP实现微信JS-SDK权限验证
SQL快速运用指南
如何用正确的姿势写HTML
正则表达式实例解析
……
更多
<
Webpack自动更新php静态资源文件名hash
《一个青年艺术家的画像》读后感
>
全部留言
我要留言
内容:
网名:
邮箱:
个人网站:
发表
全部留言