webpack本质原理简单入门
首先这边只谈论最纯粹的webpack不带任何 loader / plugin
但webpack本身原理是非常简单的,我们可以直接将划分为四个模块的功能:
- 依赖分析(Dependency Analysis)
- 作用域隔离(Scope Isolation)
- 模块系统模拟(Module System Simulation)
- 基础打包输出(Basic Bundling)
四大核心能力详解
1. 依赖分析(Dependency Analysis)
- 做什么:
从入口文件开始,递归分析所有import/require语句,构建完整的依赖关系图。 - 示例:
→ 生成依赖图谱:// a.js import { b } from './b.js'; import { c } from './c.js'; // b.js import { d } from './d.js';graph TD A[a.js] --> B[b.js] A --> C[c.js] B --> D[d.js]
2. 作用域隔离(Scope Isolation)
- 解决问题:避免模块间变量污染。
- 实现方式:
每个模块的代码会被包裹到一个函数闭包中:// 原始模块 const name = 'a'; export default name; // 打包后 function(module, exports) { const name = 'a'; exports.default = name; }
3. 模块系统模拟(Module System Simulation)
- 关键函数:
__webpack_require__
模拟 Node.js 的require和 ES Module 的import:// 模拟的模块缓存 const cache = {}; function __webpack_require__(moduleId) { if (cache[moduleId]) return cache[moduleId]; const module = { exports: {} }; // 执行模块代码(闭包) modulesmodule, module.exports, __webpack_require__; cache[moduleId] = module.exports; return module.exports; }
4. 基础打包输出(Basic Bundling)
- 输出结构:
将所有模块闭包存入一个对象,通过__webpack_require__启动入口:(function(modules) { // 模块系统实现... })({ "./a.js": function(module, exports, __webpack_require__) { /* a.js 代码 */ }, "./b.js": function(module, exports, __webpack_require__) { /* b.js 代码 */ } });
纯手工实现模拟
1. 原始文件
src/index.js:
import { message } from './message.js';
console.log(message);
src/message.js:
export const message = 'Hello';
2. 模拟 Webpack 打包结果
// dist/bundle.js
(function(modules) {
const cache = {};
function require(moduleId) {
if (cache[moduleId]) return cache[moduleId];
const module = { exports: {} };
modulesmodule, module.exports, require;
cache[moduleId] = module.exports;
return module.exports;
}
// 执行入口模块
require("./src/index.js");
})({
"./src/index.js": function(module, exports, require) {
const { message } = require("./src/message.js");
console.log(message);
},
"./src/message.js": function(module, exports) {
exports.message = 'Hello';
}
});
3. 注意点
- 变量隔离:
message.js中的message不会污染全局 - 依赖管理:通过
require函数精准定位模块 - 缓存机制:重复引入同一模块时直接读取缓存
如何验证
我们可以直接用webpack打包,然后查看打包后的文件是否与我们手工模拟的结果是否基本一致。
1. 安装 Webpack
npm install webpack webpack-cli --save-dev
2. 配置 Webpack
webpack.config.js:
module.exports = {
mode: 'development',
devtool: false // 关闭 SourceMap 更清晰看代码
};
3.执行查看
npx webpack