webpack工作原理概括(面试)
webpack里的基本概念(非配置)
- Entry: Webpack 执行构建的第一步将从 Entry 开始,可抽象成输入。
type: {[key:string]:string|Array<string>} | string
- Module: 模块, 在webpack中 一切皆模块,一个模块对应一个文件,webpack会从配置的Entry中开始递归找出所有依赖模块
- Chunk: 代码块,一个Chunk由多个模块组成,用于代码分割
- Loader: 模块转换器,用于把模块原内容按照需求规则转换成新内容
- Plugin: 扩展插件.在webpack构建流程中的特定时机会广播出对应的事件,插件可以监听这些事件的发生,在热定时机做对应的事.
webpack构建流程概括
流程步骤 | 流程解释 | |
---|---|---|
初始化参数 | 从配置文件(webpack.config.js)和shell或npm script语句中读取合并参数,得出最终的参数 | |
开始编译 | 使用上一步得到的参数初始化Compiler对象,加载所有配置的插件,执行对象的run方法进行编译 | |
确定入口 | 根据配置中的entry找出所有的入口文件 | |
编译模块 | 从入口文件出发,调用所有配置的loader对模块进行翻译,再找出该模块依赖的模块,再递归本步骤,直到所有入口依赖的文件都经过编译 | |
完成模块编译 | 编译完成,得到每个模块被翻译后的最终内容以及他们之间的依赖关系 | |
输出资源 | 根据入口和模块之间的依赖关系,组装成一个个包含多个模块的Chunk,再把每个Chunk转换成一个单独的文件加入到输出列表 | |
输出完成 | 根据配置的输出路径和文件名,吧文件内容写入到文件系统 |
webpack流程可分为三大阶段
- 初始化阶段: 启动构建,读取并且合并配置参数,加载Plugin,实例化Compiler.
- 编译阶段: 从Entry出发,针对每个Module串行调用对应的loader去翻译文件内容,再找到该Module依赖的Module,递归进行编译
- 输出阶段: 对编译后的Module组合成Chunk,把Chunk转换成文件,输出到文件系统
watch的情况:
开启watch监听模式, 文件发生变化会重新进行 编译 输出.
webpack输入文件(webpack4)
(function (modules) {
// 缓存模块
var installedModules = {};
// 创建 requie函数,类似于node中的require
function __webpack_require__(moduleId) {
// 执行前检查要导入的模块是否在缓存中,存在则直接从缓存中导出模块
if (installedModules[moduleId]) {
return installedModules[moduleId].exports;
}
// 缓存中不存在,创建模块并且添加到缓存中
var module = installedModules[moduleId] = {
i: moduleId, // 模块路径 ./src/a.js
l: false, // 模块是否执行
exports: {} // 模块
};
// 从 modules 中获取 index 为 moduleId 的模块对应的函数
// 再调用这个函数,同时把函数需要的参数传入
modules[moduleId].call(module.exports, module, module.exports, __webpack_require__);
// 修改标志位,标记已执行
module.l = true;
// 返回这个模块的导出值
return module.exports;
}
// Webpack 配置中的 publicPath,用于加载被分割出去的异步代码
__webpack_require__.p = "";
// 从入口加载
return __webpack_require__(__webpack_require__.s = "./src/index.js");
})
({
"./src/a.js":
(function (module, exports, __webpack_require__) {
eval("const b = __webpack_require__(/*! ./base/b */ \"./src/base/b.js\")\r\nmodule.exports = 'a' + b\n\n//# sourceURL=webpack:///./src/a.js?");
}),
"./src/base/b.js":
(function (module, exports) {
eval("module.exports = 'b'\n\n//# sourceURL=webpack:///./src/base/b.js?");
}),
"./src/index.js":
(function (module, exports, __webpack_require__) {
eval("const a = __webpack_require__(/*! ./a */ \"./src/a.js\")\r\nconsole.log(a)\n\n//# sourceURL=webpack:///./src/index.js?");
})
});