这篇文章不涉及 Webpack
的原理,只是观察下 Webpack
对 commonjs
和 esmodule
模块打包后的产物,读完后会对模块系统有个更深的了解。
环境配置
Webpack
只配置入口和出口,并且将 devtool
设置为 false
,把 sourcemap
关掉。
// webpack.config.js
const path = require("path");
module.exports = {
entry: "./src/commonjs/index.js",
output: {
path: path.resolve(__dirname, "./dist"),
filename: "main.js",
},
devServer: {
static: path.resolve(__dirname, "./dist"),
},
devtool: false,
};
npm
安装三个 node
包。
npm i -D webpack webpack-cli webpack-dev-server
更详细的过程可以参考 2021年从零开发前端项目指南
小试牛刀
先简单写行代码测试一下:
// src/commonjs/index.js
document.write("hello, liang");
打包产物:
(() => {
var __webpack_exports__ = {};
document.write("hello, liang");
})();
只是简单的包了层 IIFE
。
commonjs 模块
写一个 add
模块函数
// src/commonjs/add.js
console.log("add开始引入");
module.exports.add = (a, b) => {
return a + b;
};
exports.PI = 3.14;
然后 index.js
进行调用。
// src/commonjs/index.js
console.log("commonjs开始执行");
const { add } = require("./add");
document.write("1+1=", add(1, 1));
分析一下打包产物。
变成了 key、value
的键值对,key
是文件名,value
是封装为一个函数的模块,提供 module
和 exports
参数。
这里我们只有一个模块,所以只有一个 key
。
var __webpack_modules__ = {
"./src/commonjs/add.js": (module, exports) => {
console.log("add开始引入");
module.exports.add = (a, b) => {
return a + b;
};
exports.PI = 3.14;
},
};
提供一个 __webpack_require__
方法用来导入上边 __webpack_modules__
中的模块。
function __webpack_require__(moduleId) {
var module = {
exports: {},
});
__webpack_modules__[moduleId](
module,
module.exports,
__webpack_require__
);
return module.exports;
}
因为 module
和 exports
都是对象,所以在 __webpack_modules__
中给 exports
添加值就是改变这里外边的值。
最后把 module.exports
返回即可。
此外,我们可以添加一个 __webpack_module_cache__
变量来保存已经导出过的对象。
var __webpack_module_cache__ = {};
function __webpack_require__(moduleId) {
// 如果已经被导出过,直接返回缓存
var cachedModule = __webpack_module_cache__[moduleId];