当前位置:Gxlcms > JavaScript > webpack原理的深入介绍(附示例)

webpack原理的深入介绍(附示例)

时间:2021-07-01 10:21:17 帮助过:15人阅读

本篇文章给大家带来的内容是关于webpack原理的深入介绍(附示例),有一定的参考价值,有需要的朋友可以参考一下,希望对你有所帮助。

本文抄自《深入浅出webpack》,建议想学习原理的手打一遍,操作一遍,给别人讲一遍,然后就会了

在阅读前希望您已有webpack相关的实践经验,不然读了也读不懂

本文阅读需要几分钟,理解需要自己动手操作蛮长时间

0 配置文件

首先简单看一下webpack配置文件(webpack.config.js):

  1. var path = require('path');
  2. var node_modules = path.resolve(__dirname, 'node_modules');
  3. var pathToReact = path.resolve(node_modules, 'react/dist/react.min.js');
  4. module.exports = {
  5. // 入口文件,是模块构建的起点,同时每一个入口文件对应最后生成的一个 chunk。
  6. entry: {
  7. bundle: [
  8. 'webpack/hot/dev-server',
  9. 'webpack-dev-server/client?http://localhost:8080',
  10. path.resolve(__dirname, 'app/app.js')
  11. ]
  12. },
  13. // 文件路径指向(可加快打包过程)。
  14. resolve: {
  15. alias: {
  16. 'react': pathToReact
  17. }
  18. },
  19. // 生成文件,是模块构建的终点,包括
输出文件与输出路径。 output: { path: path.resolve(__dirname, 'build'), filename: '[name].js' }, // 这里配置了处理各模块的 loader ,包括 css 预处理 loader ,es6 编译 loader,图片处理 loader。 module: { loaders: [ { test: /\.js$/, loader: 'babel', query: { presets: ['es2015', 'react'] } } ], noParse: [pathToReact] }, // webpack 各插件对象,在 webpack 的事件流中执行对应的方法。 plugins: [ new webpack.HotModuleReplacementPlugin() ] };

1. 工作原理概述

1.1 基本概念

在了解webpack原理之前,需要掌握以下几个核心概念

  • Entry: 入口,webpack构建第一步从entry开始

  • module:模块,在webpack中一个模块对应一个文件。webpack会从entry开始,递归找出所有依赖的模块

  • Chunk:代码块,一个chunk由多个模块组合而成,用于代码合并与分割

  • Loader: 模块转换器,用于将模块的原内容按照需求转换成新内容

  • Plugin:拓展插件,在webpack构建流程中的特定时机会广播对应的事件,插件可以监听这些事件的发生,在特定的时机做对应的事情

1.2 流程概述

webpack从启动到结束依次执行以下操作:

  1. graph TD
  2. 初始化参数 --> 开始编译
  3. 开始编译 -->确定入口
  4. 确定入口 --> 编译模块
  5. 编译模块 --> 完成编译模块
  6. 完成编译模块 -->
输出资源 输出资源 --> 输出完成

各个阶段执行的操作如下:

  1. 初始化参数:从配置文件(默认webpack.config.js)和shell语句中读取与合并参数,得出最终的参数

  2. 开始编译(compile):用上一步得到的参数初始化Comiler对象,加载所有配置的插件,通过执行对象的run方法开始执行编译

  3. 确定入口:根据配置中的entry找出所有的入口文件

  4. 编译模块:从入口文件出发,调用所有配置的Loader对模块进行翻译,再找出该模块依赖的模块,再递归本步骤直到所有入口依赖的文件都经过处理

  5. 完成编译模块:经过第四步之后,得到了每个模块被翻译之后的最终内容以及他们之间的依赖关系

  6. 输出资源:根据入口和模块之间的依赖关系,组装成一个个包含多个模块的chunk,再将每个chunk转换成一个单独的文件加入输出列表中,这是可以修改输出内容的最后机会

  7. 输出完成:在确定好输出内容后,根据配置(webpack.config.js && shell)确定输出的路径和文件名,将文件的内容写入文件系统中(fs)

在以上过程中,webpack会在特定的时间点广播特定的事件,插件监听事件并执行相应的逻辑,并且插件可以调用webpack提供的api改变webpack的运行结果

1.3 流程细节

webpack构建流程可分为以下三大阶段。

  1. 初始化:启动构建,读取与合并配置参数,加载plugin,实例化Compiler

  2. 编译:从Entry出发,针对每个Module串行调用对应的Loader去翻译文件中的内容,再找到该Module依赖的Module,递归的进行编译处理

  3. 输出:将编译后的Module组合成Chunk,将Chunk转换成文件,输出到文件系统中

如果只执行一次,流程如上,但在开启监听模式下,流程如下图

  1. graph TD
  2. 初始化-->编译;
  3. 编译-->
输出; 输出-->文本发生变化 文本发生变化-->编译

1.3.1初始化阶段

在初始化阶段会发生的事件如下

事件描述
初始化参数从配置文件和shell语句中读取与合并参数,得出最终的参数,这个过程还会执行配置文件中的插件实例化语句 new Plugin()
实例化Compiler实例化Compiler,传入上一步得到的参数,Compiler负责文件监听和启动编译。在Compiler实例中包含了完整的webpack配置,全局只有一个Compiler实例。
加载插件依次调用插件的apply方法,让插件可以监听后续的所有事件节点。同时向插件中传入compiler实例的引用,以方便插件通过compiler调用webpack的api
environment开始应用Node.js风格的文件系统到compiler对象,以方便后续的文件寻找和读取
Entry-option读取配置的Entrys,为每个Entry实例化一个对应的EntryPlugin,为后面该Entry的递归解析工作做准备
After-plugins调用完所有内置的和配置的插件的apply方法
After-resolvers根据配置初始化resolver,resolver负责在文件系统中寻找指定路径的文件

#### 1.3.2 编译阶段 (事件名全为小写)

事件解释
run启动一次编译
Watch-run在监听模式下启动编译,文件发生变化会重新编译
compile告诉插件一次新的编译将要启动,同时会给插件带上compiler对象
compilation当webpack以开发模式运行时,每当检测到文件的变化,便有一次新的compilation被创建。一个Compilation对象包含了当前的模块资源、编译生成资源、变化的文件等。compilation对象也提供了很多事件回调给插件进行拓展
make一个新的compilation对象创建完毕,即将从entry开始读取文件,根据文件类型和编译的loader对文件进行==编译==,编译完后再找出该文件依赖的文件,递归地编译和解析
after-compile一次compilation执行完成
invalid当遇到错误会触发改事件,该事件不会导致webpack退出


在编译阶段最重要的事件是compilation,因为在compilation阶段调用了Loader,完成了每个模块的==转换==操作。在compilation阶段又会发生很多小事件,如下表

事件解释
build-module使用相应的Loader去转换一个模块
Normal-module-loader在使用loader转换完一个模块后,使用acorn解析转换后的内容,输出对应的抽象语法树(AST),以方便webpack对代码进行分析
program从配置的入口模块开始,分析其AST,当遇到require等导入其他模块的语句时,便将其加入依赖的模块列表中,同时对于新找出来的模块递归分析,最终弄清楚所有模块的依赖关系
seal所有模块及依赖的模块都通过Loader转换完成,根据依赖关系生成Chunk


2.3 输出阶段

输出阶段会发生的事件及解释:

事件解释
should-emit所有需要输出的文件已经生成,询问插件有哪些文件需要输出,有哪些不需要输出
emit确定好要输出哪些文件后,执行文件输出,==可以在这里获取和修改输出的内容==
after-mit文件输出完毕
done成功完成一次完整的编译和输出流程
failed如果在编译和输出中出现错误,导致webpack退出,就会直接跳转到本步骤,插件可以在本事件中获取具体的错误原因

在输出阶段已经得到了各个模块经过转化后的结果和其依赖关系,并且将相应的模块组合在一起形成一个个chunk.在输出阶段根据chunk的类型,使用对应的模板生成最终要输出的文件内容. |

  1. //以下代码用来包含webpack运行过程中的每个阶段
  2. //file:webpack.config.js
  3. const path = require('path');
  4. //插件监听事件并执行相应的逻辑
  5. class TestPlugin {
  6. constructor() {
  7. console.log('@plugin constructor');
  8. }
  9. apply(compiler) {
  10. console.log('@plugin apply');
  11. compiler.plugin('environment', (options) => {
  12. console.log('@environment');
  13. });
  14. compiler.plugin('after-environment', (options) => {
  15. console.log('@after-environment');
  16. });
  17. compiler.plugin('entry-option', (options) => {
  18. console.log('@entry-option');
  19. });
  20. compiler.plugin('after-plugins', (options) => {
  21. console.log('@after-plugins');
  22. });
  23. compiler.plugin('after-resolvers', (options) => {
  24. console.log('@after-resolvers');
  25. });
  26. compiler.plugin('before-run', (options, callback) => {
  27. console.log('@before-run');
  28. callback();
  29. });
  30. compiler.plugin('run', (options, callback) => {
  31. console.log('@run');
  32. callback();
  33. });
  34. compiler.plugin('watch-run', (options, callback) => {
  35. console.log('@watch-run');
  36. callback();
  37. });
  38. compiler.plugin('normal-module-factory', (options) => {
  39. console.log('@normal-module-factory');
  40. });
  41. compiler.plugin('context-module-factory', (options) => {
  42. console.log('@context-module-factory');
  43. });
  44. compiler.plugin('before-compile', (options, callback) => {
  45. console.log('@before-compile');
  46. callback();
  47. });
  48. compiler.plugin('compile', (options) => {
  49. console.log('@compile');
  50. });
  51. compiler.plugin('this-compilation', (options) => {
  52. console.log('@this-compilation');
  53. });
  54. compiler.plugin('compilation', (options) => {
  55. console.log('@compilation');
  56. });
  57. compiler.plugin('make', (options, callback) => {
  58. console.log('@make');
  59. callback();
  60. });
  61. compiler.plugin('compilation', (compilation) => {
  62. compilation.plugin('build-module', (options) => {
  63. console.log('@build-module');
  64. });
  65. compilation.plugin('normal-module-loader', (options) => {
  66. console.log('@normal-module-loader');
  67. });
  68. compilation.plugin('program', (options, callback) => {
  69. console.log('@program');
  70. callback();
  71. });
  72. compilation.plugin('seal', (options) => {
  73. console.log('@seal');
  74. });
  75. });
  76. compiler.plugin('after-compile', (options, callback) => {
  77. console.log('@after-compile');
  78. callback();
  79. });
  80. compiler.plugin('should-emit', (options) => {
  81. console.log('@should-emit');
  82. });
  83. compiler.plugin('emit', (options, callback) => {
  84. console.log('@emit');
  85. callback();
  86. });
  87. compiler.plugin('after-emit', (options, callback) => {
  88. console.log('@after-emit');
  89. callback();
  90. });
  91. compiler.plugin('done', (options) => {
  92. console.log('@done');
  93. });
  94. compiler.plugin('failed', (options, callback) => {
  95. console.log('@failed');
  96. callback();
  97. });
  98. compiler.plugin('invalid', (options) => {
  99. console.log('@invalid');
  100. });
  101. }
  102. }
  1. #在目录下执行
  2. webpack
  3. #
输出以下内容 @plugin constructor @plugin apply @environment @after-environment @entry-option @after-plugins @after-resolvers @before-run @run @normal-module-factory @context-module-factory @before-compile @compile @this-compilation @compilation @make @build-module @normal-module-loader @build-module @normal-module-loader @seal @after-compile @should-emit @emit @after-emit @done Hash: 19ef3b418517e78b5286 Version: webpack 3.11.0 Time: 95ms Asset Size Chunks Chunk Names bundle.js 3.03 kB 0 [emitted] main [0] ./main.js 44 bytes {0} [built] [1] ./show.js 114 bytes {0} [built]

2 输出文件分析

2.1 举个栗子

下面通过 Webpack 构建一个采用 CommonJS 模块化编写的项目,该项目有个网页会通过 JavaScript 在网页中显示 Hello,Webpack

运行构建前,先把要完成该功能的最基础的 JavaScript 文件和 HTML 建立好,需要如下文件:

页面入口文件 index.html

  1. <html>
  2. <head>
  3. <meta charset="UTF-8">
  4. </head>
  5. <body>
  6. <p id="app"></p>
  7. <!--导入 Webpack
输出的 JavaScript 文件--> <script src="./dist/bundle.js"></script> </body> </html>

JS 工具函数文件 show.js

  1. // 操作 DOM 元素,把 content 显示到网页上
  2. function show(content) {
  3. window.document.getElementById('app').innerText = 'Hello,' + content;
  4. }
  5. // 通过 CommonJS 规范导出 show 函数
  6. module.exports = show;

JS 执行入口文件 main.js

  1. // 通过 CommonJS 规范导入 show 函数
  2. const show = require('./show.js');
  3. // 执行 show 函数
  4. show('Webpack');

Webpack 在执行构建时默认会从项目根目录下的 webpack.config.js 文件读取配置,所以你还需要新建它,其内容如下:

  1. const path = require('path');
  2. module.exports = {
  3. // JavaScript 执行入口文件
  4. entry: './main.js',
  5. output: {
  6. // 把所有依赖的模块合并
输出到一个 bundle.js 文件 filename: 'bundle.js', // 输出文件都放到 dist 目录下 path: path.resolve(__dirname, './dist'), } };

由于 Webpack 构建运行在 Node.js 环境下,所以该文件最后需要通过 CommonJS 规范导出一个描述如何构建的 Object 对象。

  1. |-- index.html
  2. |-- main.js
  3. |-- show.js
  4. |-- webpack.config.js

一切文件就绪,在项目根目录下执行 webpack 命令运行 Webpack 构建,你会发现目录下多出一个 dist目录,里面有个 bundle.js 文件, bundle.js 文件是一个可执行的 JavaScript 文件,它包含页面所依赖的两个模块 main.jsshow.js 及内置的 webpackBootstrap 启动函数。 这时你用浏览器打开 index.html 网页将会看到 Hello,Webpack

2.2 bundle.js文件做了什么

看之前记住:一个模块就是一个文件,

首先看下bundle.js长什么样子:

006tNc79gy1fz5a7ouqzaj31cf0jijzy.jpg

注意:序号1处是个自执行函数,序号2作为自执行函数的参数传入

具体代码如下:(建议把以下代码放入编辑器中查看,最好让index.html执行下,弄清楚执行的顺序)

  1. (function(modules) { // webpackBootstrap
  2. // 1. 缓存模块
  3. var installedModules = {};
  4. // 2. 定义可以在浏览器使用的require函数
  5. function __webpack_require__(moduleId) {
  6. // 2.1检查模块是否在缓存里,在的话直接返回
  7. if(installedModules[moduleId]) {
  8. return installedModules[moduleId].exports;
  9. }
  10. // 2.2 模块不在缓存里,新建一个对象module=installModules[moduleId] {i:moduleId,l:模块是否加载,exports:模块返回值}
  11. var module = installedModules[moduleId] = {
  12. i: moduleId,//第一次执行为0
  13. l: false,
  14. exports: {}
  15. };//第一次执行module:{i:0,l:false,exports:{}}
  16. // 2.3 执行传入的参数中对应id的模块 第一次执行数组中传入的第一个参数
  17. //modules[0].call({},{i:0,l:false,exports:{}},{},__webpack_require__函数)
  18. modules[moduleId].call(module.exports, module, module.exports, __webpack_require__);
  19. // 2.4 将这个模块标记为已加载
  20. module.l = true;
  21. // 2.5 返回这个模块的导出值
  22. return module.exports;
  23. }
  24. // 3. webpack暴露属性 m c d n o p
  25. __webpack_require__.m = modules;
  26. __webpack_require__.c = installedModules;
  27. __webpack_require__.d = function(exports, name, getter) {
  28. if(!__webpack_require__.o(exports, name)) {
  29. Object.defineProperty(exports, name, {
  30. configurable: false,
  31. enumerable: true,
  32. get: getter
  33. });
  34. }
  35. };
  36. __webpack_require__.n = function(module) {
  37. var getter = module && module.__esModule ?
  38. function getDefault() { return module['default']; } :
  39. function getModuleExports() { return module; };
  40. __webpack_require__.d(getter, 'a', getter);
  41. return getter;
  42. };
  43. __webpack_require__.o = function(object, property) { return Object.prototype.hasOwnProperty.call(object, property); };
  44. __webpack_require__.p = "";
  45. // 4. 执行reruire函数引入第一个模块(main.js对应的模块)
  46. return __webpack_require__(__webpack_require__.s = 0);
  47. })
  48. ([ // 0. 传入参数,参数是个数组
  49. /* 第0个参数 main.js对应的文件*/
  50. (function(module, exports, __webpack_require__) {
  51. // 通过 CommonJS 规范导入 show 函数
  52. const show = __webpack_require__(1);//__webpack_require__(1)返回show
  53. // 执行 show 函数
  54. show('Webpack');
  55. }),
  56. /* 第1个参数 show.js对应的文件 */
  57. (function(module, exports) {
  58. // 操作 DOM 元素,把 content 显示到网页上
  59. function show(content) {
  60. window.document.getElementById('app').innerText = 'Hello,' + content;
  61. }
  62. // 通过 CommonJS 规范导出 show 函数
  63. module.exports = show;
  64. })
  65. ]);

以上看上去复杂的代码其实是一个自执行函数(文件作为自执行函数的参数),可以简写如下:

  1. (function(modules){
  2. //模拟require语句
  3. function __webpack_require__(){}
  4. //执行存放所有模块数组中的第0个模块(main.js)
  5. __webpack_require_[0]
  6. })([/*存放所有模块的数组*/])

bundles.js能直接在浏览器中运行的原因是,在输出的文件中通过__webpack_require__函数,定义了一个可以在浏览器中执行的加载函数(加载文件使用ajax实现),来模拟Node.js中的require语句。

原来一个个独立的模块文件被合并到了一个单独的 bundle.js 的原因在于浏览器不能像 Node.js 那样快速地去本地加载一个个模块文件,而必须通过网络请求去加载还未得到的文件。 如果模块数量很多,加载时间会很长,因此把所有模块都存放在了数组中,执行一次网络加载。

修改main.js,改成import引入模块

  1. import show from './show';
  2. show('Webpack');

在目录下执行webpack,会发现:

  1. 生成的代码会有所不同,但是主要的区别是自执行函数的参数不同,也就是2.2代码的第二部分不同

  1. ([//自执行函数和上面相同,参数不同
  2. /* 0 */
  3. (function(module, __webpack_exports__, __webpack_require__) {
  4. "use strict";
  5. Object.defineProperty(__webpack_exports__, "__esModule", { value: true });
  6. /* harmony import */ var __WEBPACK_IMPORTED_MODULE_0__show__ = __webpack_require__(1);
  7. Object(__WEBPACK_IMPORTED_MODULE_0__show__["a" /* default */])('Webpack');
  8. }),
  9. /* 1 */
  10. (function(module, __webpack_exports__, __webpack_require__) {
  11. "use strict";
  12. /* harmony export (immutable) */ __webpack_exports__["a"] = show;
  13. function show(content) {
  14. window.document.getElementById('app').innerText = 'Hello,' + content;
  15. }
  16. })
  17. ]);

参数不同的原因是es6的import和export模块被webpack编译处理过了,其实作用是一样的,接下来看一下在main.js中异步加载模块时,bundle.js是怎样的

2.3异步加载时,bundle.js代码分析

main.js修改如下

  1. import('./show').then(show=>{
  2. show('Webpack')
  3. })

构建成功后会生成两个文件

  1. bundle.js 执行入口文件

  2. 0.bundle.js 异步加载文件

其中0.bundle.js文件的内容如下:

  1. webpackJsonp(/*在其他文件中存放的模块的ID*/[0],[//本文件所包含的模块
  2. /* 0 */,
  3. /* 1 show.js对应的模块 */
  4. (function(module, __webpack_exports__, __webpack_require__) {
  5. "use strict";
  6. Object.defineProperty(__webpack_exports__, "__esModule", { value: true });
  7. /* harmony export (immutable) */
  8. __webpack_exports__["default"] = show;
  9. function show(content) {
  10. window.document.getElementById('app').innerText = 'Hello,' + content;
  11. }
  12. })
  13. ]);

bundle.js文件的内容如下:

注意:bundle.js比上面的bundle.js的区别在于:

  1. 多了一个__webpack_require__.e,用于加载被分割出去的需要异步加载的chunk对应的文件

  2. 多了一个webpackJsonp函数,用于从异步加载的文件中安装模块

  1. (function(modules) { // webpackBootstrap
  2. // install a JSONP callback for chunk loading
  3. var parentJsonpFunction = window["webpackJsonp"];
  4. // webpackJsonp用于从异步加载的文件中安装模块
  5. // 将webpackJsonp挂载到全局是为了方便在其他文件中调用
  6. /**
  7. * @param chunkIds 异步加载的模块中需要安装的模块对应的id
  8. * @param moreModules 异步加载的模块中需要安装模块列表
  9. * @param executeModules 异步加载的模块安装成功后需要执行的模块对应的index
  10. */
  11. window["webpackJsonp"] = function webpackJsonpCallback(chunkIds, moreModules, executeModules) {
  12. // add "moreModules" to the modules object,
  13. // then flag all "chunkIds" as loaded and fire callback
  14. var moduleId, chunkId, i = 0, resolves = [], result;
  15. for(;i < chunkIds.length; i++) {
  16. chunkId = chunkIds[i];
  17. if(installedChunks[chunkId]) {
  18. resolves.push(installedChunks[chunkId][0]);
  19. }
  20. installedChunks[chunkId] = 0;
  21. }
  22. for(moduleId in moreModules) {
  23. if(Object.prototype.hasOwnProperty.call(moreModules, moduleId)) {
  24. modules[moduleId] = moreModules[moduleId];
  25. }
  26. }
  27. if(parentJsonpFunction) parentJsonpFunction(chunkIds, moreModules, executeModules);
  28. while(resolves.length) {
  29. resolves.shift()();
  30. }
  31. };
  32. // The module cache
  33. var installedModules = {};
  34. // objects to store loaded and loading chunks
  35. var installedChunks = {
  36. 1: 0
  37. };
  38. // The require function
  39. function __webpack_require__(moduleId) {
  40. // Check if module is in cache
  41. if(installedModules[moduleId]) {
  42. return installedModules[moduleId].exports;
  43. }
  44. // Create a new module (and put it into the cache)
  45. var module = installedModules[moduleId] = {
  46. i: moduleId,
  47. l: false,
  48. exports: {}
  49. };
  50. // Execute the module function
  51. modules[moduleId].call(module.exports, module, module.exports, __webpack_require__);
  52. // Flag the module as loaded
  53. module.l = true;
  54. // Return the exports of the module
  55. return module.exports;
  56. }
  57. // This file contains only the entry chunk.
  58. // The chunk loading function for additional chunks
  59. /**
  60. * 用于加载被分割出去的需要异步加载的chunk对应的文件
  61. * @param chunkId 需要异步加载的chunk对应的id
  62. * @returns {Promise}
  63. */
  64. __webpack_require__.e = function requireEnsure(chunkId) {
  65. var installedChunkData = installedChunks[chunkId];
  66. if(installedChunkData === 0) {
  67. return new Promise(function(resolve) { resolve(); });
  68. }
  69. // a Promise means "currently loading".
  70. if(installedChunkData) {
  71. return installedChunkData[2];
  72. }
  73. // setup Promise in chunk cache
  74. var promise = new Promise(function(resolve, reject) {
  75. installedChunkData = installedChunks[chunkId] = [resolve, reject];
  76. });
  77. installedChunkData[2] = promise;
  78. // start chunk loading
  79. var head = document.getElementsByTagName('head')[0];
  80. var script = document.createElement('script');
  81. script.type = "text/javascript";
  82. script.charset = 'utf-8';
  83. script.async = true;
  84. script.timeout = 120000;
  85. if (__webpack_require__.nc) {
  86. script.setAttribute("nonce", __webpack_require__.nc);
  87. }
  88. script.src = __webpack_require__.p + "" + chunkId + ".bundle.js";
  89. var timeout = setTimeout(onScriptComplete, 120000);
  90. script.onerror = script.onload = onScriptComplete;
  91. function onScriptComplete() {
  92. // avoid mem leaks in IE.
  93. script.onerror = script.onload = null;
  94. clearTimeout(timeout);
  95. var chunk = installedChunks[chunkId];
  96. if(chunk !== 0) {
  97. if(chunk) {
  98. chunk[1](new Error('Loading chunk ' + chunkId + ' failed.'));
  99. }
  100. installedChunks[chunkId] = undefined;
  101. }
  102. };
  103. head.appendChild(script);
  104. return promise;
  105. };
  106. // expose the modules object (__webpack_modules__)
  107. __webpack_require__.m = modules;
  108. // expose the module cache
  109. __webpack_require__.c = installedModules;
  110. // define getter function for harmony exports
  111. __webpack_require__.d = function(exports, name, getter) {
  112. if(!__webpack_require__.o(exports, name)) {
  113. Object.defineProperty(exports, name, {
  114. configurable: false,
  115. enumerable: true,
  116. get: getter
  117. });
  118. }
  119. };
  120. // getDefaultExport function for compatibility with non-harmony modules
  121. __webpack_require__.n = function(module) {
  122. var getter = module && module.__esModule ?
  123. function getDefault() { return module['default']; } :
  124. function getModuleExports() { return module; };
  125. __webpack_require__.d(getter, 'a', getter);
  126. return getter;
  127. };
  128. // Object.prototype.hasOwnProperty.call
  129. __webpack_require__.o = function(object, property) { return Object.prototype.hasOwnProperty.call(object, property); };
  130. // __webpack_public_path__
  131. __webpack_require__.p = "";
  132. // on error function for async loading
  133. __webpack_require__.oe = function(err) { console.error(err); throw err; };
  134. // Load entry module and return exports
  135. return __webpack_require__(__webpack_require__.s = 0);
  136. })
  137. /************************************************************************/
  138. ([//存放没有经过异步加载的,随着执行入口文件加载的模块
  139. /* 0 */
  140. /***/ (function(module, exports, __webpack_require__) {
  141. __webpack_require__.e/* import() */(0).then(__webpack_require__.bind(null, 1)).then(show=>{
  142. show('Webpack')
  143. })
  144. /***/ })
  145. ]);

以上就是webpack原理的深入介绍(附示例)的详细内容,更多请关注Gxl网其它相关文章!

人气教程排行