李学长提供
webpack的工作流程
1.初始化Compiler:new Webpack(config) 得到Compiler对象
2.开始编译:调用Compiler对象run方法开始执行编译
3.确定入口:根据配置中的entry找出所有的入口文件
4.编译模块:从入口文件出发,调用所有配置的loader对模块进行编译,再找出该模块的依赖的模块递归编译所有的模块
5.完成模块编译:在经过第4步使用loader编译完所有模块之后,得到每个模块被编译的最终内容以及他们之间的依赖关系
6.输出资源:根据入口和模块之间的依赖关系,组装成一个个包含多个模块的chunk,再把每个chunk转换成一个单独的文件加入到输出列表。(注意这一步是可以修改输出内容的最后机会)
7.输出完成:再确定好输出内容后,根据配置确定输出的路径和文件名,把文件内容写入到文件系统
webpack plugin的原理是什么
我的理解是:在webpack中,插件本质就是一个类,他可以对我们打包的资源做各种操作,
例如: 热模块替换插件HotModuleReplacementPlugin [模块更新操作,永远不要在生产环境(production)下启用 HMR]、HtmlWebpackPlugin生成index.html模板、OptimizeCSSPlugin css代码压缩插件,等等。
我自己也有看过webpack官网配置,通过complier创建compilation然后compilation对我们打包的资源在进行做各种操作,webpack本身提供了多个钩子函数供我们进行操作,像异步串行钩子tapAsync、tapPromise,比较常用。
我们也可以通过compilation.assets方法往输出资源中添加要输出的资源。
webpack loader的原理是什么
对于loader的理解,首先loader的执行顺序是倒着执行的,其实loader的本质就是一个函数,他可以见我们的资源文件进行装换,作用就是将a文件转换成b文件,
例如babel-loader将es6等语法转换成可以兼容各个浏览器的语法文件、url-loader、css-loader对ccs进行转换、sass-loader对sass进行语法装换等。
当然webpack也为loader专门提供的库,他又同步loader,通过提供this.callback函数 【 第一个参数是否有错误,第二个参数是暴露的数据,第三个。。。可选】
loader默认从下往上执行
pitch从前往后执行[module.exports.pitch],也可以通过this.query,获取webpack配置的传参。
webacpk 八股文
webpack 作用
- 模块打包: 合并文件
- 编译兼容: 帮助我们对代码做
polyfilljs 和 css 的兼容性问题 - 扩展能力:按需加载、代码压缩, 缓存, 跨域,热更新
处理应用程序:它会在内部从一个或多个入口点构建一个 依赖图(dependency graph),然后将你项目中所需的每一个模块组合成一个或多个 bundles,它们均为静态资源,用于展示你的内容
代码分割
文件压缩合并
编译兼容
模块合并
按需加载
代码校验
自动刷新
模块 热替换
Tree shaking
Loader 和 plugin 区别
- Loader:模块代码转换器,让webpack能够去处理除了JS、JSON之外的其他类型的文件,并将它们转换为有效 模块,以供应用程序使用,以及被添加到依赖图中。
- Plugin:扩展插件。在webpack运行的生命周期中会广播出许多事件,plugin可以监听这些事件,在合适的时机通过webpack提供的api改变输出结果。常见的有:打包优化,资源管理,注入环境变量
构建流程
- 初始化参数。获取用户在webpack.config.js文件配置的参数
- 开始编译。初始化compiler对象,注册所有的插件plugins,插件开始监听webpack构建过程的生命周期事件,不同环节会有相应的处理,然后开始执行编译。
- 确定入口。根据webpack.config.js文件的entry入口,从配置的entry入口,开始解析文件构建AST语法树,找出依赖,递归下去。
- 编译模块。递归过程中,根据文件类型和loader配置,调用相应的loader对不同的文件做转换处理,在找出该模块依赖的模块,递归本操作,直到项目中依赖的所有模块都经过了本操作的编译处理。
- 完成编译并输出。递归结束,得到每个文件结果,包含转换后的模块以及他们之前的依赖关系,根据entry以及output等配置生成代码块chunk
- 打包完成。根据output输出所有的chunk到相应的文件目录