开门见山。
1、打包单一模块
webpack.config.js
module.exports = {
entry:"./chunk1.js",
output: {
path: __dirname + '/dist',
filename: '[name].js'
},
};
chunk1.js
var chunk1=1;
exports.chunk1=chunk1;
那么打包后长什么样子呢?
(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 = "";
// Load entry module and return exports
return __webpack_require__(0);
})([function(module, exports) {
var chunk1=1;
exports.chunk1=chunk1;
}]);
好吧,好像废话好多。那么我们来简化一下。
{function(){})([function(){},function(){}])
我们来看匿名函数做了什么:
function(modules) { // webpackBootstrap
// modules就是一个数组,元素就是一个个函数体,就是我们声明的模块
var installedModules = {};
// The require function
function __webpack_require__(moduleId) {
...
}
// expose the modules object (__webpack_modules__)
__webpack_require__.m = modules;
// expose the module cache
__webpack_require__.c = installedModules;
// __webpack_public_path__
__webpack_require__.p = "";
// Load entry module and return exports
return __webpack_require__(0);
}
整个函数里就是声明了一个变量installedModules和函数webpack_require,并在函数上添加了三个属性module、cache、path,m保存的是传入的数组模块,c保存的时候installedModules的变量,p是一个空字符串。最后执行webpack_require函数,参数为0,并将结果返回。
好,我们来看webpack_require这个函数做了什么事情:
function __webpack_require__(moduleId) {
//moduleId就是调用是传入的0
// installedModules[0]是undefined,继续往下
if(installedModules[moduleId])
return installedModules[moduleId].exports;
// module就是{exports: {},id: 0,loaded: false}
var module = installedModules[moduleId] = {
exports: {},
id: moduleId,
loaded: false
};
// 下面接着分析这个
modules[moduleId].call(module.exports, module, module.exports, __webpack_require__);
// 表明模块已经载入
module.loaded = true;
// 返回module.exports(注意modules[moduleId].call的时候module.exports会被修改)
return module.exports;
}
接下来来看一下
modules[moduleId].call({}, module, module.exports, __webpack_require__)
干了什么:
module就是之前声明的
{exports: {},id: 0,loaded: false}
webpack_require就是声明的webpack_require函数
运行后module.exports就是{chunk1:1}(具体如何做到的等会讲)。所以当我们使用chunk1这个模块的时候(比如varchunk1=require(“chunk1”),得到的就是一个对象{chunk1:1})。如果模块里没有exports.chunk1=chunk1或者module.exports=chunk1得到的就是一个空对象{}
2、使用一个模块
上面我们分析了如何打包一个模块,接下来我们分析一下如何使用一个模块。
webpack.config.js
module.exports = {
entry:"./main.js",
output: {
path: __dirname + '/dist',
filename: '[name].js'
}
};
main.js
var chunk1=require("./chunk1");
console.log(chunk1);
打包后:
(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 = "";
// Load entry module and return exports
return __webpack_require__(0);
})([function (module, exports, __webpack_require__) {
var chunk1=__webpack_require__(1);
console.log(chunk1);
}, function (module, exports) {
var chunk1 = 1;
exports.chunk1 = chunk1;
}]);
不一样的地方就是自执行函数的参数由
[function(module, exports) {
var chunk1=1; exports.chunk1=chunk1;
}]
变为
[function (module, exports, __webpack_require__) {
var chunk1=__webpack_require__(1);
console.log(chunk1);
}, function (module, exports) {
var chunk1 = 1;
exports.chunk1 = chunk1;
}]
其实就是多了一个main模块,不过这个模块没有导出项,而且这个模块依赖于chunk1模块。所以当运行webpack_require(0)的时候,main模块缓存到installedModules[0]上,modules[0].call(也就是调用main模块)的时候,chunk1被缓存到installedModules[1]上,并且导出对象{chunk1:1}给模块main使用