最近有同学致力于写一个脚手架工具,在研究webpack源码,问了我几个问题,然而我完全不能解答。于是开始研究webpack。
webpack做的事情主要是实现前端模块化(即:让前端也可以像node端一样适用require方法加载模块)和借助插件实现编译、热加载等功能。webpack源码系列第一部分,就分享最简单的内容——如何使用require方法加载模块并打包。
__webpack_require__方法
待打包的文件bundle_require.js
// bundle_require.js
console.log('success');
仅使用最简单的打包,不使用插件。打包后的文件index.bundle.js
// index.bundle.js
/******/ (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] = {
/******/ exports: {},
/******/ id: moduleId,
/******/ loaded: false
/******/ };
/******/ // Execute the module function
/******/ modules[moduleId].call(module.exports, module, module.exports, __webpack_require__);
/******/ // Flag the module as loaded
/******/ module.loaded = 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;
/******/ // __webpack_public_path__
/******/ __webpack_require__.p = "/bundle";
/******/ // Load entry module and return exports
/******/ return __webpack_require__(0);
/******/ })
/************************************************************************/
/******/ ([
/* 0 */
/***/ function(module, exports, __webpack_require__) {
'use strict';
__webpack_require__(1);
/***/ },
/* 1 */
/***/ function(module, exports) {
'use strict';
/*(function(a){
console.log(a.name);
})
({name: 'hello'})*/
console.log('success');
/***/ }
/******/ ]);
bundle文件中是一个立即执行函数,形如(function(modules){})([module_1, module_2, ...])
形参modules
对应的实参为一个模块数组[module_1, module_2, ...]
,该模块数组的每个成员都是使用require
加载的一个模块,每个被加载的模块都被封装成一个函数。
var installedModules = {};
是加载模块的缓存,如果已经加载过无需再次加载。
__webpack_require__
方法通过installedModules
对象缓存第一次加载的模块,通过modules[moduleId].call(module.exports, module, module.exports, __webpack_require__);
执行形参中的各个模块。使用call
是因为为了确保每个module中的this
指向的是module本身。然后给它传__webpack_require__
函数是想让module有加载其他module的能力。
模块间有简单依赖的情况
模块依赖:bundle_require.js
依赖dependency.js
// bundle_require.js
var dependency = require('./dependency.js');
console.log(dependency.name);
console.log('success');
// dependency.js
module.exports = {
name: 'hello'
}
打包后的文件index.bundle.js
// index.bundle.js
/******/ (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] = {