webpack核心概念
- entry : webpack项目入口
- module : webpack一个模块对应一个文件, webpack从entry开始递归找出所有依赖模块
- chunk : 代码块, 一个chunk由多个模块组成, 主要用于代码合并和分割
- loader : 模块转换器, 用于将制定的模块内容转换为所需要的内容
- plugins : 拓展插件, 用于在webpack构建过程中特定的时机广播对应的事件, 插件可以监听这些事件发生,做特定的事情
webpack流程
初始化
- 初始化相关参数: 从webpack.config.js和shell语句中读取
编译
- 开始编译: 用上一步读取到的配置参数初始化compiler对象, 加载所有的插件, 通过执行对象run方法进行编译
- 确定入口: 根据entry找出所有的入口文件
- 编译模块: 从入口文件出发, 调用所有的配置loader(从右到左,从下到上)对模块进行编译,再找出该模块依赖的模块,进行递归处理
- 完成编译: 经过上一步, 得到每个模块被编译之后的最终内容以及他们的依赖关系
输出
- 输出资源: 根据入口和模块之间的依赖关系, 组装一个个包含多个模块的chunk, 再将每个chunk转换一个单独的文件到输出列表中, 这一步是修改输出内容的最后一步
- 输出完成:根据上一步确定好输出内容之后, 根据webpack.config.js配置确定输出文件的路径和名称, 将文件写入磁盘(fs)
webpack原理
- 读取文件分析模块依赖
- 对模块进行解析执行(深度遍历)
- 对不同的模块使用相应的loader
- 编译模块,生成抽象语法树AST
- 循环遍历AST树,拼接输出js
webpack输出的js文件:1. webpack_require是模块加载函数, 2. 每个模块都有唯一的id(0, 1, 2,…), 3. webpack_require.e是异步加载模块函数(Promise实现), 4. webpackJsonp用于从异步加载的文件中安装模块
webpack模块打包原理
webpack打包出来的代码为啥能在浏览器上运行
- webpack对于ES模块/CommonJS模块的实现,是基于自己实现的webpack_require,所以代码能跑在浏览器中。
- 从 webpack2 开始,已经内置了对 ES6、CommonJS、AMD 模块化语句的支持。但不包括新的ES6语法转为ES5代码,这部分工作还是留给了babel及其插件。
- 在webpack中可以同时使用ES6模块和CommonJS模块。 因为 module.exports很像export default,所以ES6模块可以很方便兼容 CommonJS:import XXX from ‘commonjs-module’。反过来CommonJS兼容ES6模块,需要额外加上default:require(‘es-module’).default。
webpack最终精简代码
1 | (function(modules) { |
webpack优化
打包速度优化
缩小文件查找范围
- include指定查找范围、exclude排除文件查找范围
减小编译的文件内容
- 动态链接库DLL(webpack4可以用splitChunks, 不然代码会重复
充分利用电脑多核性能
- 多进程之HappyPack。 HappyPack就能让Webpack把任务分解给多个子进程去并发的执行,子进程处理完后再把结果发送给主进程,其中子进程的个数为cpu的个数减去1,需要在loader处修改如下
项目代码优化
懒加载
- require.ensure();
- import();
tree shaking
- 目的:消除无用到的代码, 推荐使用方法 { name } form ‘./module.js’
- 原理:ES6引入模块是静态分析,所以编译的时候知道我们加载了哪些代码;进而分析哪些变量未用到,从而删除掉
- 有一些副作用(babel转换代码、自执行函数、函数里面使用外部变量
代码合并和分离(splitChunks)
- 分离部分第三方库(vue、vuex、vue-router)功能,类似于动态链接库DLL
- 合并公共代码(common
webpack插件
插件相关概念
- Tapable: webpack自己写的基础类Tapable, Compiler、Compilation等都是继承于Tabable类
- Compiler: Webpack 环境所有的的配置信息,包含 options,loaders,plugins 这些信息
- Compilation: 包含了当前的模块资源、编译生成资源、变化的文件等
插件创建流程
- 创建一个javascript构造函数
- 在他的原型定义apply方法
- 指定触发webpack的事件钩子
- 在钩子里面实现自己的业务逻辑
- 功能实现完成,调用webpack提供的callback
使用案例
1 | //webpack1 |