webpack打包原理

迷南。 2023-06-06 03:45 83阅读 0赞

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的顺序排列。

  1. // webpack.config.js
  2. module.exports = {
  3. entry:'./a.js',
  4. output:{
  5. filename:'bundle.js'
  6. }
  7. };
  8. // a.js
  9. var b = require('./b.js');
  10. console.log('a');
  11. b.b1();
  12. // b.js
  13. exports.b1 = function () {
  14. console.log('b1')
  15. };
  16. exports.b2 = function () {
  17. console.log('b2')
  18. };

以上代码我们打包处理的js为

  1. // bundle.js
  2. /******/ (function(modules) { // webpackBootstrap
  3. /******/ // The module cache
  4. /******/ var installedModules = {};
  5. /******/ // The require function
  6. /******/ function __webpack_require__(moduleId) {
  7. /******/ // Check if module is in cache
  8. /******/ if(installedModules[moduleId])
  9. /******/ return installedModules[moduleId].exports;
  10. /******/ // Create a new module (and put it into the cache)
  11. /******/ var module = installedModules[moduleId] = {
  12. /******/ exports: {},
  13. /******/ id: moduleId,
  14. /******/ loaded: false
  15. /******/ };
  16. /******/ // Execute the module function
  17. /******/ modules[moduleId].call(module.exports, module, module.exports, __webpack_require__);
  18. /******/ // Flag the module as loaded
  19. /******/ module.loaded = true;
  20. /******/ // Return the exports of the module
  21. /******/ return module.exports;
  22. /******/ }
  23. /******/ // expose the modules object (__webpack_modules__)
  24. /******/ __webpack_require__.m = modules;
  25. /******/ // expose the module cache
  26. /******/ __webpack_require__.c = installedModules;
  27. /******/ // __webpack_public_path__
  28. /******/ __webpack_require__.p = "";
  29. /******/ // Load entry module and return exports
  30. /******/ return __webpack_require__(0);
  31. /******/ })
  32. /************************************************************************/
  33. /******/ ([
  34. /* 0 */
  35. /***/ function(module, exports, __webpack_require__) {
  36. var b = __webpack_require__(1);
  37. console.log('a');
  38. b.b1();
  39. /***/ },
  40. /* 1 */
  41. /***/ function(module, exports) {
  42. exports.b1 = function () {
  43. console.log('b1')
  44. };
  45. exports.b2 = function () {
  46. console.log('b2')
  47. };
  48. /***/ }
  49. /******/ ]);

我们看到_webpack_require是模块加载函数,接收模块id(对,webpack中每个模块都会有一个独一无二的id,其实也就是在IIFE传参数组中的索引值(0,1,2…)
a依赖b,所以在a中调用webpack加载模块的函数

  1. // 1是模块b的id
  2. var b = __webpack_require__(1);

无论什么模块规范书写。我们的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。

发表评论

表情:
评论列表 (有 0 条评论,83人围观)

还没有评论,来说两句吧...

相关阅读

    相关 webpack打包原理

    webpack只是一个打包模块的机制,只是把依赖的模块转化成可以代表这些包的静态文件。并不是什么commonjs或者amd之类的模块化规范。webpack就是识别你的 入口文件

    相关 浅谈webpack打包原理

    浅谈webpack打包原理 模块化机制 webpack并不强制你使用某种模块化方案,而是通过兼容所有模块化方案让你无痛接入项目。有了webpack,你可以随意选择你