这是我参与「第五届青训营 」伴学笔记创作活动的第 13 天
课程重点:
- 什么是webpack
- 使用webpack
- 理解loader
- 理解插件
1. 什么是webpack
webpack的作用是把很多文件打包整合到一起, 缩小项目体积, 提高加载速度,常用的场景是:
- 代码压缩
将JS、CSS代码混淆压缩,让代码体积更小,加载更快
- 编译语法
编写CSS时使用Less、Sass,编写 JS 时使用ES6、TypeScript等,这些标准目前都无法被浏览器兼容,因此需要构建工具编译,例如使用Babel编译ES6语法。
- 处理模块化:
CSS 和 JS 的模块化语法,目前都无法被浏览器兼容。因此开发环境可以使用既定的模块化语法,但是需要构建工具将模块化语法编译为浏览器可识别形式。
2. 使用webpack
首先需要使用 node 安装 webpack
npm install webpack
npm install webpack-cli
复制代码
entry:项目入口
output:项目打包完结果放的地方
模块化+一致性
- 多个文件资源合并成一个,减少 http 请求数
- 支持模块化开发
- 支持高级 JS 特性
- 支持 Typescript、CoffeeScript 方言
- 统一图片、CSS、字体 等其它资源的处理模型
- Etc..
写配置文件
- 流程类:作用于流程中某个or若干个环节,直接影响打包效果的配置项
entry 和 output
entry 用于定于一次打包的入口文件,也就是从哪个文件开始打包
output 参数是个对象,用于定义构建后的文件的输出。其中包含path和filename,代表了输出路径和输出文件名称
entry: './js/app.js',
output: {
path: './build',
filename: 'bundle.js'
},
处理CSS
test:过滤条件
use:定义处理文件的loader数组
接入Babel
把高版本JS代码转译成低版本的
生成HTML
- 工具类:主流程之外,提供更多工程化能力的配置项
- HMT
模块热替换:写的代码不用重新编译,页面就能更新
devServer:hot true+watch:true持续更新 - Tree-Shaking
删除没用到的代码Dead Code
代码没用到,不可到达;代码执行的结果不会被用到;代码只读不写
- 其他工具
缓存 SourceMap 性能监控 日志 代码压缩 分包
3. 理解loader
loader 主要的作用的内容转换,因为 webpack 只认识 js 代码,loader要做的就是把非 js 的资源转换成 js 的资源,css 是链式调用的,比如 less 的解析需要用到如下三个 loader,他们是按照顺序分别执行的:
loader 的执行分为 pitch 和 normol 两个阶段,前者是从数组第一个向后执行,而后者是从最后一个向前执行,loader 会先执行 pitch,然后获取资源再执行 normal loader,但是如果 pitch 有返回值时,就不会走之后的 loader,并将返回值返回给之前的 loader。
4. 理解插件
插件架构可以提升工具的拓展性:webpack的原理和底层是非常复杂的,新人需要了解整个流程成本很高,迭代成本很高,牵一发动全身,并且作为开源项目缺乏成长性,参与它很难。插件的精髓是,对外开放拓展,对修改封闭,我只实现核心的功能,其他的功能都由插件生态来共建和实现
webpack的实现原理是:Webpack 编译阶段会为各个编译对象初始化不同的 Hook ,开发者可以在自己编写的 Plugin 中监听到这些 Hook ,在打包的某个特定时间段触发对应 Hook 注入特定的逻辑从而实现自己的行为。
webpack上有两个很重要的对象:
- compiler 对象中保存着完整的 Webpack 环境配置,它通过 CLI 或 者 Node API传递的所有选项创建出一个 compilation 实例。这个对象会在首次启动 Webpack 时创建,我们可以通过 compiler 对象上访问到 Webapck 的主环境配置,比如 loader 、 plugin 等等配置信息
- compilation 对象代表一次资源的构建,compilation 实例能够访问所有的模块和它们的依赖,在 compilation 对象中我们可以获取/操作本次编译当前模块资源、编译生成资源、变化的文件以及被跟踪的状态信息,同样 compilation 也基于 tapable 拓展了不同时机的 Hook 回调
Plugin 的原型对象上需要存在一个 apply 方法,当 webpack 创建 compiler 对象时会调用各个插件实例上的 apply 方法并且传入 compiler 对象作为参数。同时需要指定一个绑定在 compiler 对象上的 Hook , 在 Hook 的回调中处理插件自身的逻辑,根据 Hook 的种类,在完成逻辑后通知 webpack 继续进行
Webpack Plugin 的核心机制就是基于 tapable 产生的发布订阅者模式,在不同的周期触发不同的 Hook 从而影响最终的打包结果。