先上总结吧,后面有代码分析:
总结:webpack的模块化原理是酱紫的——首先我们需要在webpack.config.js中取指定入口文件,完了分析webpack编译后的文件可以看到,整个文件由一个自执行函数包裹,入参是一个数组,这个数组包含了所有的模块,函数体的逻辑就是webpack的模块化逻辑。其中有一个函数叫webpack_require,参数为moduleId,然后在这个函数体的末尾调用了他传入参数为0并返回,这个0指代的模块就是我们的入口模块。也就是说,从入参的modules数组中取第一个函数进行调用,并传入了module,module.exports以及webpack_require这三个参数,然后你可以在入口函数的函数体内看到又调用了webpack_require(1)···等等来调用入口文件中所有后续需要的模块,这样就会引入后续的第二个第三个····函数,从第二个函数开始的入参exports,都是这个模块的module.exports通过对象的引用传参,这个模块中需要的其他模块也都是通过webpack_require来引的,最终会将module.exports return出来。
webpack(1.x)编译后的文件:
1 | /******/ (function(modules) { // webpackBootstrap |
webpack.config.js文件:
1 | var webpack = require('webpack'); |
精简一下代码:
1 | (function(modules){ |
这块的自执行函数的入参是个数组,这个数组包含了所有模块,这些模块都包裹在函数中。自执行函数体里的逻辑就是处理模块的逻辑,关键就在webpack_require这个函数,这个函数就是require的替代。自执行函数的函数体里先定义了这个函数,然后调用了他并传入一个moduleId,这个例子中是0,也就是我们的入口模块__dirname + ‘/src/app.js’的内容。
webpack_require内部执行了
1 | // Execute the module function |
也就是从入参的modules数组中取第一个函数进行调用,并传入了module,module.exports以及webpack_require,再看第一个函数(入口函数)的逻辑:
1 | function(module, exports, __webpack_require__) { |
可以看到入口模块又调用了webpack_require(1)去引入第二个函数。
这里入参的exports就是这个模块的module.exports通过对象的引用传参,最后会将module.exports return出来。到这里就完成了webpack_require的使命。
比如说在入口模块中又调用了webpack_require(1),就会得到这个模块返回的module.exports。