webpack 在前端开发中作为模块打包工具非常受开发者的青睐, 丰富的 loader 使它可以实现各种各样的功能. 本文将通过 webpack 来打包一个 js 文件, 看看 webpack 是如何加载各个模块的.
两个简单的源文件
为了方便分析 webpack 加载模块的原理, 我们准备了两个文件:
- hello.js
- const hello = {say: arg => {
- console.info('hello' + arg || 'world');
- }
- };
- export default hello;
- index.js
- import Hello from './hello';
- Hello.say('man');
index.js 作为入口文件, 引用了 hello.js 模块.
Webpack 打包
在命令行执行 webpack index.js bundle.js 对入口文件进行打包, 生成 bundle.js , 大体结构为 (为了方便阅读, 我删除了部分多余的代码):
可以看到, 最终生成的文件以 (function (modules) {})([模块 1, 模块 2]) 的方式启动, 我们定义的模块被包装成一个个匿名函数, 然后以数组的形式传递个一个匿名函数 function (modules) {}, 在这个匿名函数中定义了一个 __webpack_require__() 函数, 用来加载模块, 最后, 通过 return __webpack_require__(__webpack_require__.s = 0); 来加载第一个模块 index.js
__webpack_require__() 函数
该函数接收一个 moduleId 作为参数, 这个参数就是各个模块在数组中的索引,
- function __webpack_require__(moduleId) {
- /******/
- /******/// Check if module is in cache
- /******/
- if (installedModules[moduleId]) {
- /******/
- return installedModules[moduleId].exports;
- /******/
- }
- /******/// Create a new module (and put it into the cache)
- /******/
- var module = installedModules[moduleId] = {
- /******/
- i: moduleId,
- /******/
- l: false,
- /******/
- exports: {}
- /******/
- };
- /******/
- /******/// Execute the module function
- /******/
- modules[moduleId].call(module.exports, module, module.exports, __webpack_require__);
- /******/
- /******/// Flag the module as loaded
- /******/
- module.l = true;
- /******/
- /******/// Return the exports of the module
- /******/
- return module.exports;
- /******/
- }
其中 installedModules 是用来缓存执行过的模块. 通过 modules[moduleId].call() 来执行模块, 最后返回模块的 exports.
模块接受的参数
以 hello.js 模块为例
- (function (module, __webpack_exports__, __webpack_require__) {
- "use strict";
- const hello = {
- say: arg => {
- console.info('hello' + arg || 'world');
- }
- };
- /* harmony default export */
- __webpack_exports__["a"] = (hello);
- /***/
- })
webpack 会向模块传递
module, __webpack_exports__, __webpack_require__
三个参数, 前两个是用来导出模块内的变量, 第三个参数为前面介绍的
__webpack_require__()
的引用, 用来导入其它模块.
来源: http://www.jb51.net/article/140734.htm