浅谈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 相关文章推荐
javascript编程起步(第七课)
Jan 10 Javascript
基于jQuery的输入框无值自动显示指定数据的实现代码
Jan 24 Javascript
获取元素距离浏览器周边的位置的方法getBoundingClientRect
Apr 17 Javascript
AngularJS模块管理问题的非常规处理方法
Apr 29 Javascript
浅析JavaScript中的事件机制
Jun 04 Javascript
基于javascript实现最简单的选项卡切换效果
May 16 Javascript
JS去除空格和换行的正则表达式(推荐)
Jun 14 Javascript
jquery实现简单Tab切换菜单效果
Jul 17 Javascript
jQuery实现为table表格动态添加或删除tr功能示例
Feb 19 jQuery
vue+django实现一对一聊天功能的实例代码
Jul 17 Javascript
JS实现点星星消除小游戏
Mar 24 Javascript
js实现ajax的用户简单登入功能
Jun 18 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
浅谈json_encode用法
2015/03/05 PHP
详解php的socket通信
2015/08/11 PHP
Yii数据读取与跳转参数传递用法实例分析
2016/07/12 PHP
Yii2框架BootStrap样式的深入理解
2016/11/07 PHP
PHP在linux上执行外部命令的方法
2017/02/06 PHP
PHP基于socket实现的简单客户端和服务端通讯功能示例
2017/07/10 PHP
javascript学习笔记(十二) RegExp类型介绍
2012/06/20 Javascript
JS+CSS实现仿触屏手机拨号盘界面及功能模拟完整实例
2015/05/16 Javascript
Jquery 分页插件之Jquery Pagination
2015/08/25 Javascript
jquery+php随机生成红包金额数量代码分享
2015/08/27 Javascript
基于JavaScript实现在新的tab页打开url
2016/08/04 Javascript
KnockoutJS 3.X API 第四章之数据控制流if绑定和ifnot绑定
2016/10/10 Javascript
JavaScript实现自定义媒体播放器方法介绍
2017/01/03 Javascript
JavaScript判断浏览器及其版本信息
2017/01/20 Javascript
微信小程序中顶部导航栏的实现代码
2017/03/30 Javascript
详解从买域名到使用pm2部署node.js项目全过程
2018/03/07 Javascript
Vue单页应用引用单独的样式文件的两种方式
2018/03/30 Javascript
微信小程序 腾讯地图显示偏差问题解决
2019/07/27 Javascript
jquery向后台提交数组的代码分析
2020/02/20 jQuery
jQuery实现雪花飘落效果
2020/08/02 jQuery
微信小程序实现日历签到
2020/09/21 Javascript
如何在vue中使用HTML 5 拖放API
2021/01/14 Vue.js
python计算方程式根的方法
2015/05/07 Python
Python优化技巧之利用ctypes提高执行速度
2016/09/11 Python
Python程序慢的重要原因
2020/09/04 Python
使用gunicorn部署django项目的问题
2020/12/30 Python
用CSS3打造HTML5的Logo(实现代码)
2016/06/16 HTML / CSS
详解css3中 text-fill-color属性
2019/07/08 HTML / CSS
英国男士时尚网站:Dandy Fellow
2018/02/09 全球购物
学生生病请假条范文
2014/02/16 职场文书
2014国培学习感言
2014/03/05 职场文书
2014年客房部工作总结
2014/11/22 职场文书
2014年度思想工作总结
2014/11/27 职场文书
班主任工作总结范文
2015/08/13 职场文书
数据库的高级查询六:表连接查询:外连接(左外连接,右外连接,UNION关键字,连接中ON与WHERE的不同)
2021/04/05 MySQL
python3 实现mysql数据库连接池的示例代码
2021/04/17 Python