浅谈Webpack 是如何加载模块的


Posted in Javascript onMay 24, 2018

Webpack 在前端开发中作为模块打包工具非常受开发者的青睐,丰富的 loader 使它可以实现各种各样的功能。本文将通过 webpack 来打包一个 js 文件,看看 webpack 是如何加载各个模块的。

两个简单的源文件

为了方便分析 webpack 加载模块的原理,我们准备了两个文件:

hello.js

const hello = {
 say: arg => {
  console.info('hello ' + arg || 'world');
 }
};

export default hello;

index.js

import Hello from './hello';

Hello.say('man');

index.js 作为入口文件,引用了 hello.js 模块。

Webpack 打包

在命令行执行 webpack index.js bundle.js 对入口文件进行打包,生成 bundle.js ,大体结构为(为了方便阅读,我删除了部分多余的代码):

浅谈Webpack 是如何加载模块的

可以看到,最终生成的文件以 (function (modules) {})([模块1, 模块2]) 的方式启动,我们定义的模块被包装成一个个匿名函数,然后以数组的形式传递个一个匿名函数 function (modules) {},在这个匿名函数中定义了一个 __webpack_require__() 函数,用来加载模块,最后,通过 return __webpack_require__(__webpack_require__.s = 0); 来加载第一个模块 index.js

__webpack_require__() 函数

该函数接收一个 moduleId 作为参数,这个参数就是各个模块在数组中的索引,

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] = {
   /******/
   i: moduleId,
   /******/
   l: false,
   /******/
   exports: {}
   /******/
  };
  /******/
  /******/ // Execute the module function
  /******/
  modules[moduleId].call(module.exports, module, module.exports, __webpack_require__);
  /******/
  /******/ // Flag the module as loaded
  /******/
  module.l = true;
  /******/
  /******/ // Return the exports of the module
  /******/
  return module.exports;
  /******/
 }

其中 installedModules 是用来缓存执行过的模块。通过 modules[moduleId].call() 来执行模块,最后返回模块的 exports。

模块接受的参数

以 hello.js 模块为例

(function (module, __webpack_exports__, __webpack_require__) {

  "use strict";
  const hello = {
   say: arg => {
    console.info('hello ' + arg || 'world');
   }
  };

  /* harmony default export */
  __webpack_exports__["a"] = (hello);

  /***/
 })

webpack 会向模块传递 module, __webpack_exports__, __webpack_require__ 三个参数,前两个是用来导出模块内的变量,第三个参数为前面介绍的 __webpack_require__() 的引用,用来导入其它模块。

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持三水点靠木。

Javascript 相关文章推荐
基于jquery的返回顶部效果(兼容IE6)
Jan 17 Javascript
JavaScript地图拖动功能SpryMap的简单实现
Jul 17 Javascript
文本框回车提交与禁止提交示例
Sep 27 Javascript
append和appendTo的区别以及appendChild用法
Dec 24 Javascript
node.js入门教程
Jun 01 Javascript
javascript使用数组的push方法完成快速排序
Sep 15 Javascript
js监听鼠标事件控制textarea输入字符串的个数
Sep 29 Javascript
JS模式之简单的订阅者和发布者模式完整实例
Jun 30 Javascript
webuploader分片上传的实现代码(前后端分离)
Sep 10 Javascript
vueScroll实现移动端下拉刷新、上拉加载
Mar 22 Javascript
13 个npm 快速开发技巧(推荐)
Jul 04 Javascript
关于angular浏览器兼容性问题的解决方案
Jul 26 Javascript
jquery.onoff实现简单的开关按钮功能(推荐)
May 24 #jQuery
详解javascript中的变量提升和函数提升
May 24 #Javascript
JavaScript轮播停留效果的实现思路
May 24 #Javascript
vue2单元测试环境搭建
May 24 #Javascript
Vue+mui实现图片的本地缓存示例代码
May 24 #Javascript
vue组件name的作用小结
May 23 #Javascript
linux 后台运行node服务指令方法
May 23 #Javascript
You might like
php中经典方法实现判断多维数组是否为空
2011/10/23 PHP
php牛逼的面试题分享
2013/01/18 PHP
解析PHP 5.5 新特性
2013/07/02 PHP
PHP base64编码后解码乱码的解决办法
2014/06/19 PHP
ThinkPHP的Widget扩展实例
2014/06/19 PHP
基于thinkPHP实现的微信自定义分享功能示例
2016/09/23 PHP
javascript中删除指定数组中指定的元素的代码
2011/02/12 Javascript
jquery实现文字由下到上循环滚动的实例代码
2013/08/09 Javascript
使用jquery插件qrcode生成二维码
2015/10/22 Javascript
JS实现屏蔽网页右键复制及ctrl+c复制的方法【2种方法】
2016/09/04 Javascript
Angular2仿照微信UI实现9张图片上传和预览的示例代码
2017/10/19 Javascript
vue+webpack实现异步加载三种用法示例详解
2018/04/24 Javascript
详解多页应用 Webpack4 配置优化与踩坑记录
2018/10/16 Javascript
详细讲解如何创建, 发布自己的 Vue UI 组件库
2019/05/29 Javascript
Vue+Element-UI实现上传图片并压缩
2019/11/26 Javascript
JS动态显示倒计时效果
2019/12/12 Javascript
vue实现微信浏览器左上角返回按钮拦截功能
2020/01/18 Javascript
[03:28]2014DOTA2国际邀请赛 走近EG战队天才中单Arteezy
2014/07/12 DOTA
零基础学Python(一)Python环境安装
2014/08/20 Python
python基础教程之匿名函数lambda
2017/01/17 Python
Python实现基于多线程、多用户的FTP服务器与客户端功能完整实例
2017/08/18 Python
Python调用ctypes使用C函数printf的方法
2017/08/23 Python
django将网络中的图片,保存成model中的ImageField的实例
2019/08/07 Python
python中的线程threading.Thread()使用详解
2019/12/17 Python
TensorFlow基本的常量、变量和运算操作详解
2020/02/03 Python
python 中的paramiko模块简介及安装过程
2020/02/29 Python
HTML5 Canvas玩转酷炫大波浪进度图效果实例(附demo)
2016/12/14 HTML / CSS
Stefania Mode英国:奢华设计师和时尚服装
2017/10/23 全球购物
ZWILLING双立人英国网上商店:德国刀具锅具厨具品牌
2018/05/15 全球购物
Dyson戴森波兰官网:Dyson.pl
2019/08/05 全球购物
教师师德教育的自我评价
2013/10/31 职场文书
学校领导四风问题整改措施思想汇报
2014/10/09 职场文书
反邪教观后感
2015/06/11 职场文书
python 如何用map()函数创建多线程任务
2021/04/07 Python
你真的了解PHP中的引用符号(&)吗
2021/05/12 PHP
灵能百分百第三季什么时候来?
2022/03/15 日漫