浅谈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自己写tab滑动门(通用版)
Oct 30 Javascript
Ext GridPanel加载完数据后进行操作示例代码
Jun 17 Javascript
JavaScript 学习笔记之变量及其作用域
Jan 14 Javascript
几种二级联动案例(jQuery\Array\Ajax php)
Aug 13 Javascript
jQuery实现带遮罩层效果的blockUI弹出层示例【附demo源码下载】
Sep 14 Javascript
jQuery获取this当前对象子元素对象的方法
Nov 29 Javascript
利用js的闭包原理做对象封装及调用方法
Apr 07 Javascript
JavaScript设计模式之代理模式详解
Jun 09 Javascript
你应该知道的几类npm依赖包管理详解
Oct 06 Javascript
ionic3实战教程之随机布局瀑布流的实现方法
Dec 28 Javascript
TypeScript中使用getElementXXX()的示例代码
Sep 12 Javascript
浅谈Vue使用Cascader级联选择器数据回显中的坑
Oct 31 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
laravel 框架结合关联查询 when()用法分析
2019/11/22 PHP
javascript 快速排序函数代码
2012/05/30 Javascript
javascript游戏开发之《三国志曹操传》零部件开发(二)人物行走的实现
2013/01/23 Javascript
jQuery操作input值的各种方法总结
2013/11/21 Javascript
防止登录页面出现在frame中js代码
2014/07/22 Javascript
Jquery ajax加载等待执行结束再继续执行下面代码操作
2015/11/24 Javascript
两种JavaScript的AES加密方式(可与Java相互加解密)
2016/08/02 Javascript
微信小程序 scroll-view组件实现列表页实例代码
2016/12/14 Javascript
Vue如何引入远程JS文件
2017/04/20 Javascript
windows下vue-cli导入bootstrap样式
2017/04/25 Javascript
Vue组件通信实践记录(推荐)
2017/08/15 Javascript
Vue使用.sync 实现父子组件的双向绑定数据问题
2019/04/04 Javascript
js实现计时器秒表功能
2019/12/16 Javascript
JavaScript React如何修改默认端口号方法详解
2020/07/28 Javascript
Vue 禁用浏览器的前进后退操作
2020/09/04 Javascript
Python 变量类型及命名规则介绍
2013/06/08 Python
python中使用urllib2伪造HTTP报头的2个方法
2014/07/07 Python
Python使用ftplib实现简易FTP客户端的方法
2015/06/03 Python
Python 比较两个数组的元素的异同方法
2017/08/17 Python
Python编程求质数实例代码
2018/01/31 Python
Python3多线程操作简单示例
2018/05/22 Python
python3实现随机数
2018/06/25 Python
python+webdriver自动化环境搭建步骤详解
2019/06/03 Python
Django 重写用户模型的实现
2019/07/29 Python
python中property属性的介绍及其应用详解
2019/08/29 Python
Python操作excel的方法总结(xlrd、xlwt、openpyxl)
2019/09/02 Python
Python通过Tesseract库实现文字识别
2020/03/05 Python
李维斯牛仔裤英国官方网站:Levi’s英国
2019/10/10 全球购物
GWT (Google Web Toolkit)有哪些主要的原件组成?
2015/06/08 面试题
大学学习生活感言
2014/01/18 职场文书
孝老爱亲模范事迹材料
2014/05/25 职场文书
对外汉语专业大学生职业生涯规划书
2014/10/11 职场文书
2014年信访工作总结
2014/11/17 职场文书
高中班主任评语
2014/12/30 职场文书
django如何自定义manage.py管理命令
2021/04/27 Python
Python3.8官网文档之类的基础语法阅读
2021/09/04 Python