定义 mark.js
export const val = 'sd';
export default () => {
console.log('jaja');
};
index.js
import mark from './mark';
const name = 'jack';
mark();
export default name;
下面的代码是 webpack 打包后生成的代码
(function(modules) {
// webpackBootstrap
// The module cache
var installedModules = {};
// The require function
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;
}
// expose the modules object (__webpack_modules__)
__webpack_require__.m = modules;
// expose the module cache
__webpack_require__.c = installedModules;
// define getter function for harmony exports
__webpack_require__.d = function(exports, name, getter) {
if (!__webpack_require__.o(exports, name)) {
Object.defineProperty(exports, name, { enumerable: true, get: getter });
}
};
// define __esModule on exports
__webpack_require__.r = function(exports) {
if (typeof Symbol !== 'undefined' && Symbol.toStringTag) {
Object.defineProperty(exports, Symbol.toStringTag, { value: 'Module' });
}
Object.defineProperty(exports, '__esModule', { value: true });
};
// create a fake namespace object
// mode & 1: value is a module id, require it
// mode & 2: merge all properties of value into the ns
// mode & 4: return value when already ns object
// mode & 8|1: behave like require
__webpack_require__.t = function(value, mode) {
if (mode & 1) value = __webpack_require__(value);
if (mode & 8) return value;
if (mode & 4 && typeof value === 'object' && value && value.__esModule)
return value;
var ns = Object.create(null);
__webpack_require__.r(ns);
Object.defineProperty(ns, 'default', { enumerable: true, value: value });
if (mode & 2 && typeof value != 'string')
for (var key in value)
__webpack_require__.d(
ns,
key,
function(key) {
return value[key];
}.bind(null, key),
);
return ns;
};
// getDefaultExport function for compatibility with non-harmony modules
__webpack_require__.n = function(module) {
var getter =
module && module.__esModule
? function getDefault() {
return module['default'];
}
: function getModuleExports() {
return module;
};
__webpack_require__.d(getter, 'a', getter);
return getter;
};
// Object.prototype.hasOwnProperty.call
__webpack_require__.o = function(object, property) {
return Object.prototype.hasOwnProperty.call(object, property);
};
// __webpack_public_path__
__webpack_require__.p = '';
// Load entry module and return exports
return __webpack_require__((__webpack_require__.s = './src/index.js'));
})(
/************************************************************************/
{
/***/ './src/index.js':
/*!**********************!*\
!*** ./src/index.js ***!
\**********************/
/*! exports provided: default */
/***/ function(module, __webpack_exports__, __webpack_require__) {
'use strict';
eval(
'__webpack_require__.r(__webpack_exports__);\n/* harmony import */ var _mark__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ./mark */ "./src/mark.js");\n\n\nconst name = \'jack\';\nObject(_mark__WEBPACK_IMPORTED_MODULE_0__["default"])();\n/* harmony default export */ __webpack_exports__["default"] = (name);\n\n\n//# sourceURL=webpack:///./src/index.js?',
);
/***/
},
/***/ './src/mark.js':
/*!*********************!*\
!*** ./src/mark.js ***!
\*********************/
/*! exports provided: default */
/***/ function(module, __webpack_exports__, __webpack_require__) {
'use strict';
eval(
'__webpack_require__.r(__webpack_exports__);\n/* harmony default export */ __webpack_exports__["default"] = (() => {\n console.log(\'jaja\')\n});\n\n\n//# sourceURL=webpack:///./src/mark.js?',
);
/***/
},
},
);
一步一步来看, 整体是个立即执行函数, 精简下如下
(function(modules) {
// ...
})({
'.src/index.js': function(module, __webpack_exports__, __webpack_require__) {
'use strict';
eval();
// ...
//...
},
});
传入立即执行函数的 modules 对应的就是一个对象,对象的 key 是文件路径,value 是函数,函数参数为 module, webpack_exports, webpack_require. 函数内部是用使用 eval 执行,单独拿出来看下。
eval index
__webpack_require__.r(__webpack_exports__);
/* harmony import */
var _mark__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(
/*! ./mark */ './src/mark.js',
);
const name = 'jack';
Object(_mark__WEBPACK_IMPORTED_MODULE_0__['default'])();
/* harmony default export */
__webpack_exports__['default'] = name;
//# sourceURL=webpack:///./src/index.js?
eval mark
__webpack_require__.r(__webpack_exports__);
/* harmony export (binding) */
__webpack_require__.d(__webpack_exports__, 'val', function() {
return val;
});
const val = 'sd';
/* harmony default export */
__webpack_exports__['default'] = () => {
console.log('jaja');
};
//# sourceURL=webpack:///./src/mark.js?
可以看到,是通过__webpack_require__ 去加载模块,并且将我们的变量 name 赋值给 webpack_exports 的 default 属性上。至于 webpack_require.r 我们稍后分析。
接下来 看看 立即执行函数内部做了什么
// 内部定义的 module 缓存, 存放加载过的模块
var installedModules = {};
function __webpack_require__(moduleId) {
// 如果加载过, 直接返回 installedModules里对应模块的 exports
if (installedModules[moduleId]) {
return installedModules[moduleId].exports;
}
// 没有加载过,则创建一个 moudle 变量
var module = (installedModules[moduleId] = {
i: moduleId, // i 代表 moduleId,也就是 './src/index.js'
l: false, // l (loaded) 代表是否加载完毕
exports: {}, // exports 后面导出的内容
});
// 执行 modules 里的方法,就是上面提到过的 立即执行函数传入的 ./src/index 对应的 value
// function (module, __webpack_exports__, __webpack_require__) {...}
modules[moduleId].call(
module.exports,
module,
module.exports,
__webpack_require__,
);
// 执行完毕,设置模块对应的 l 为 true
module.l = true;
// 返回 module.exports
return module.exports;
}
eval 里主要使用了 webpack_require.r(webpack_exports)
// 在__webpack_exports__上定义 __esModule 为 true
__webpack_require__.r = function(exports) {
if (typeof Symbol !== 'undefined' && Symbol.toStringTag) {
Object.defineProperty(exports, Symbol.toStringTag, { value: 'Module' });
}
Object.defineProperty(exports, '__esModule', { value: true });
};
这里的 webpack_exports 就是 webpack_require 函数里的 module.exports
webpack_require.d
__webpack_require__.d = function(exports, name, getter) {
if (!__webpack_require__.o(exports, name)) {
Object.defineProperty(exports, name, { enumerable: true, get: getter });
}
};
通过__webpack_require__.d 对 module.exports 对象上赋值
也就是 eval 里的执行完以后,我们的 module.exports.default = name
分别打印 index.js 和 mark.js 对应的 module


至于 bundle.js 中的其他内容,都是些辅助函数,暂不分析了。
梳理下 webpack bundle.js 里的流程
- 运行立即执行函数,并传入 modules 对象,key 对应文件路径,value 对应 eval 函数
- 立即执行函数返回 wepack_require('./src/index.js') 加载入口文件对应模块并返回相应的 exports
- webpack_require 里先判断是否加载过,如果加载过直接返回闭包里 installedModules 里对应的模块
- 如果没有,则先创建 module 对象,设置 loaded false, exports 为空对象
- 执行传入立即执行函数相应模块对应的 eval 方法
- eval 去执行 webpack_require 去加载依赖的模块,通过__webpack_require__.d 给 exports 对象赋值, _webpack_require** .r 定义 **esModule 为 true, 直接给 module.exports.default 赋值默认导出。
- 模块加载过后,设置 installedModules 里对应模块的 l flag 为 true,返回 module.exports
定义 mark.js
index.js
下面的代码是 webpack 打包后生成的代码
一步一步来看, 整体是个立即执行函数, 精简下如下
传入立即执行函数的 modules 对应的就是一个对象,对象的 key 是文件路径,value 是函数,函数参数为 module, webpack_exports, webpack_require. 函数内部是用使用 eval 执行,单独拿出来看下。
eval index
eval mark
可以看到,是通过__webpack_require__ 去加载模块,并且将我们的变量 name 赋值给 webpack_exports 的 default 属性上。至于 webpack_require.r 我们稍后分析。
接下来 看看 立即执行函数内部做了什么
eval 里主要使用了 webpack_require.r(webpack_exports)
这里的 webpack_exports 就是 webpack_require 函数里的 module.exports
webpack_require.d
通过__webpack_require__.d 对 module.exports 对象上赋值
也就是 eval 里的执行完以后,我们的 module.exports.default = name
分别打印 index.js 和 mark.js 对应的 module
至于 bundle.js 中的其他内容,都是些辅助函数,暂不分析了。
梳理下 webpack bundle.js 里的流程