webpack只是一个打包模块的机制,只是把依赖的模块转化成可以代表这些包的静态文件。并不是什么commonjs或者amd之类的模块化规范。webpack就是识别你的 入口文件。识别你的模块依赖,来打包你的代码。至于你的代码使用的是commonjs还是amd或者es6的import。webpack都会对其进行分析。来获取代码的依赖。webpack做的就是分析代码。转换代码,编译代码,输出代码。webpack本身是一个node的模块,所以webpack.config.js是以commonjs形式书写的(node中的模块化是commonjs规范的)
webpack中每个模块有一个唯一的id,是从0开始递增的。整个打包后的bundle.js是一个匿名函数自执行。参数则为一个数组。数组的每一项都为个function。function的内容则为每个模块的内容,并按照require的顺序排列。
// webpack.config.js
module.exports = {
entry:'./a.js',
output:{
filename:'bundle.js'
}
};
- 1
- 2
- 3
- 4
- 5
- 6
- 7
// a.js
var b = require('./b.js');
console.log(‘a’);
b.b1();
- 1
- 2
- 3
- 4
- 5
- 6
// b.js
exports.b1 = function () {
console.log('b1')
};
exports.b2 = function () {
console.log(‘b2’)
};
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
以上代码我们打包处理的js为
// 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 = “”;
/******/ // Load entry module and return exports
/******/ return webpack_require(0);
/******/ })
/************************************************************************/
/*****/ ([
/ 0 /
/**/ function(module, exports, webpack_require) {
var b = __webpack_require__(1);
console.log('a');
b.b1();
/**/ },
/ 1 /
/**/ function(module, exports) {
exports.b1 = function () {
console.log('b1')
};
exports.b2 = function () {
console.log('b2')
};
/***/ }
/******/ ]);
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
- 19
- 20
- 21
- 22
- 23
- 24
- 25
- 26
- 27
- 28
- 29
- 30
- 31
- 32
- 33
- 34
- 35
- 36
- 37
- 38
- 39
- 40
- 41
- 42
- 43
- 44
- 45
- 46
- 47
- 48
- 49
- 50
- 51
- 52
- 53
- 54
- 55
- 56
- 57
- 58
- 59
- 60
- 61
- 62
- 63
- 64
- 65
- 66
- 67
- 68
我们看到_webpack_require是模块加载函数,接收模块id(对,webpack中每个模块都会有一个独一无二的id,其实也就是在IIFE传参数组中的索引值(0,1,2…)
a依赖b,所以在a中调用webpack加载模块的函数
上面是使用的commonjs规范书写的
webpack2是如何对实现es6 modules的
webpack模块化原理-ES module
无论什么模块规范书写。我们的webpack进行识别后打包的内容不会相差很多,webpack有优秀的语法分析能力,支持 CommonJs AMD 等规范。
webpack为什么能把任何形式的资源都视作模块呢?因为loader机制。不同的资源采用不同的loader进行转换。CMD、AMD 、import、css 、等都有相应的loader去进行转换。那为什么我们平时写的es6的模块机制,不用增加import的loader呢。因为我们使用了babel把import转换成了require。并且Webpack 2 将增加对 ES6 模块的原生支持并且混用 ES6、AMD 和 CommonJS 模块。这意味着 Webpack 现在可以识别 import 和 export 了,不需要先把它们转换成 CommonJS 模块的格式:Webpack 2 有哪些新东西webpack对于es模块的实现,也是基于自己实现的webpack_require 和webpack_exports ,装换成类似于commonjs的形式。es6 module是静态的依赖,所以在运行前进行代码转换,这里的实现是将所有导出项作为一个对象的属性,在入口文件执行时,去递归的加载模块。
如何实现一个简单的webpack
读取文件分析模块依赖
对模块进行解析执行(深度遍历)
针对不同的模块使用相应的loader
编译模块,生成抽象语法树AST。
循环遍历AST树,拼接输出js。
webpack 源码解析
细说 webpack 之流程篇
如何实现一个简单的webpack
loader原理
在解析对于文件,会自动去调用响应的loaderloader 本质上是一个函数,输入参数是一个字符串,输出参数也是一个字符串。当然,输出的参数会被当成是 JS 代码,从而被 esprima 解析成 AST,触发进一步的依赖解析。webpack会按照从右到左的顺序执行loader。
Webpack——令人困惑的地方
作者:209bd3bc6844
链接:https://www.jianshu.com/p/e24ed38d89fd
来源:简书
简书著作权归作者所有,任何形式的转载都请联系作者获得授权并注明出处。
</div>
<link href="https://csdnimg.cn/release/phoenix/mdeditor/markdown_views-e9f16cbbc2.css" rel="stylesheet">
</div>
</article>