webpack 原理和二次开发
这部分是面试的加分项,大家不要深究细节。即便面试被问到,实际工作中应用的概率也非常小。 webpack 本身就是一个工具,只是用来打包构建。而且发展多年已经成熟完善,日常的开发场景都能满足。
webpack 构建流程
几个核心概念
- Entry:入口,Webpack 执行构建的第一步将从 Entry 开始,可抽象成输入。
- Module:模块,在 Webpack 里一切皆模块,一个模块对应着一个文件。Webpack 会从配置的 Entry 开始递归找出所有依赖的模块。
- Chunk:代码块,一个 Chunk 由多个模块组合而成,用于代码合并与分割。
- Loader:模块转换器,用于把模块原内容按照需求转换成新内容。
- Plugin:扩展插件,在 Webpack 构建流程中的特定时机会广播出对应的事件,插件可以监听这些事件的发生,在特定时机做对应的事情。
Webpack 的构建流程可以分为以下三大阶段:
- 初始化:启动构建,读取与合并配置参数,加载 Plugin,实例化 Compiler。
- 编译:从 Entry 发出,针对每个 Module 串行调用对应的 Loader 去翻译文件内容,再找到该 Module 依赖的 Module,递归地进行编译处理。
- 输出:对编译后的 Module 组合成 Chunk,把 Chunk 转换成文件,输出到文件系统。
开发 loader
以 less-loader 为例,回顾一下使用规则
js
{
test: /\.less$/,
// 注意顺序
loader: ['style-loader', 'css-loader', 'less-loader']
}所以,loader 的作用:
- 一个代码转换器,将 less 代码转换为 css 代码
- 再例如 vue-template-compiler
- 再例如 babel 编译 jsx
所以一个 loader 的基本开发模式:
js
const less = require('node-less')
module.exports = function(source) {
// source 即 less 代码,需要返回 css 代码
return less(source)
}以上是 loader 的基本开发方式,实际开发中可能还会有更多要求
- 支持 options ,如
url-loader的使用 - 支持异步 loader
- 缓存策略
js
// options
const loaderUtils = require('loader-utils')
module.exports = function(source) {
// 获取 loader 的 options
const options = loaderUtils.getOptions(this)
return source // 示例,直接返回 source 了
}js
// 异步 loader
module.exports = function(source) {
// 使用异步 loader
const callback = this.async()
// 执行异步函数,如读取文件
someAsyncFn(source, function(err, result, sourceMaps, ast) {
// 通过 callback 返回异步执行后的结果
callback(err, result, sourceMaps, ast)
})
}js
// 缓存
module.exports = function(source) {
// 关闭该 Loader 的缓存功能(webpack 默认开启缓存)
this.cacheable(false)
return source
}
讨论区
欢迎留下想法与补充