浅谈Webpack 是如何加载模块的

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 ,大体结构为(为了方便阅读,我删除了部分多余的代码):

可以看到,最终生成的文件以 (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__() 的引用,用来导入其它模块。

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

(0)

相关推荐

  • Webpack常见静态资源处理-模块加载器(Loaders)+ExtractTextPlugin插件

    webpack系列目录 webpack 系列 二:webpack 介绍&安装 webpack 系列 三:webpack 如何集成第三方js库 webpack 系列 四:webpack 多页面支持 & 公共组件单独打包 webpack 系列 五:webpack Loaders 模块加载器 webpack 系列 六:前端项目模板-webpack+gulp实现自动构建部署 基于webpack搭建纯静态页面型前端工程解决方案模板, 最终形态源码见github: https://github.com

  • webpack配置sass模块的加载的方法

    webpack管理的项目,我们希望用sass定义样式,为了正常编译,需要做如下配置.这里不讲webpack的入门,入门的文章,我推荐这篇<webpack入门>. 为了使用sass,我们需要安装sass的依赖包 //在项目下,运行下列命令行 npm install --save-dev sass-loader //因为sass-loader依赖于node-sass,所以还要安装node-sass npm install --save-dev node-sass 当然了,使用样式的话,css-lo

  • 详解webpack异步加载业务模块

    虽然把我们用到的JS文件全部打包一个可以节省请求数,但如果打包后的JS文件过大,那么也容易出现白屏现象,许多操作失灵.而且一些区域是点到才出现,那么相关的JS其实可以剥离出这个大JS文件外.这就涉及到异步加载了.异步加载是SPA的重要构建方式之一. 我们沿着上一篇的目录,这次学习webpack的require.ensure API.此文件也叫做ensure.html,涉及到avalon, jquery,还有两个业务代码ensure.js与ensure_a.js. 先看我们的页面: <!DOCTY

  • 浅谈Webpack 是如何加载模块的

    Webpack 在前端开发中作为模块打包工具非常受开发者的青睐,丰富的 loader 使它可以实现各种各样的功能.本文将通过 webpack 来打包一个 js 文件,看看 webpack 是如何加载各个模块的. 两个简单的源文件 为了方便分析 webpack 加载模块的原理,我们准备了两个文件: hello.js const hello = { say: arg => { console.info('hello ' + arg || 'world'); } }; export default h

  • 浅谈vue首屏加载优化

    本文介绍了浅谈vue首屏加载优化,分享给大家,具体如下: 库使用情况 vue vue-router axios muse-ui material-icons vue-baidu-map 未优化前 首先我们在正常情况下build 优化 1. 按需加载 当前流行的UI框架如iview,muse-ui,Element UI都支持按需加载,只需稍微改动一下代码. 修改前: import MuseUI from 'muse-ui' import 'muse-ui/dist/muse-ui.css' imp

  • 浅谈SpringBoot资源初始化加载的几种方式

    目录 一.问题 二.资源初始化 一.问题 在平时的业务模块开发过程中,难免会需要做一些全局的任务.缓存.线程等等的初始化工作,那么如何解决这个问题呢?方法有多种,但具体又要怎么选择呢? 二.资源初始化 1.既然要做资源的初始化,那么就需要了解一下springboot启动过程(这里大体说下启动过程,详细:https://www.jb51.net/article/133648.htm) 按照前面的分析,Spring-boot容器启动流程总体可划分为2部分: 执行注解:扫描指定范围下的bean.载入自

  • 浅谈解决Hibernate懒加载的4种方式

    本文总结了我在学习hibernate的过程中,解决hibernate懒加载问题的四种方式. 所谓懒加载(lazy)就是延时加载,延迟加载. 什么时候用懒加载呢,我只能回答要用懒加载的时候就用懒加载. 至于为什么要用懒加载呢,就是当我们要访问的数据量过大时,明显用缓存不太合适,因为内存容量有限,为了减少并发量,减少系统资源的消耗,我们让数据在需要的时候才进行加载,这时我们就用到了懒加载. 例如,有一个对象是Employee,还有一个对象是Department.显然,对于Employee相对Depa

  • 浅谈MUI框架中加载外部网页或服务器数据的方法

    我们很多同学在实施使用MUI框架的时候,在打开新的页面的时候常使用的方式是:mui.openwindow的方法,然而遇到网页需要从服务器或者是要嵌套外部的网页的时候,由于网速的问题会遇到加载时出现白屏,等待时间过长,导致用户体验不好. 页面加载的时候使用plus.webview.create方法就很好的解决了这个问题. 废话不多说直接贴代码 首先我们需要在创建一个父页面,以下是父页面的JS // H5 plus事件处理 function plusReady(){ var nwaiting = p

  • 浅谈SpringBoot2.4 配置文件加载机制大变化

    前言 Spring Boot 2.4.0.M2刚刚发布,它对 application.properties 和 application.yml 文件的加载方式进行重构.如果应用程序仅使用单个 application.properties 或 application.yml 作为配置文件,那么可能感受不到任何区别.但是如果您的应用程序使用更复杂的配置(例如,Spring Cloud 配置中心等),则需要来了解更改的内容以及原因. 为什么要进行这些更改 随着最新版本 Spring Boot 发布,S

  • 浅谈hibernate中懒加载禁用操作

    浅谈hibernate中懒加载禁用操作 懒加载的概念:懒加载就是hibernate中的延迟加载,在hibernate中的一对多,多对多关系中通过对象导航来查询对象时一般默认的就是懒加载.就是当我们查询一个对象的时候,在默认情况下,返回的只是该对象的代理对象,当用户去使用该对象的属性是,才会向数据库中再一次发出查询语句.懒加载在某些情况下确实可以减少不必要的sql语句,但是有的情况下,还是会抛出异常. 下面我将介绍懒加载禁用的方式 方式一: 在需要禁用懒加载的实体对象的配置文件中配置lazy="f

  • 浅谈JVM之类的加载链接和初始化

    加载 JVM可以分为三大部分,五大空间和三大引擎,要讲起来也不是特别复杂,先看下面的总体的JVM架构图. 从上面的图中,我们可以看到JVM中有三大部分,分别是类加载系统,运行时数据区域和Execution Engine. 加载就是根据特定名称查找类或者接口的二进制表示,并根据此二进制表示来创建类和接口的过程. 运行时常量池 我们知道JVM中有一个方法区的区域,在JDK8中,方法区的实现叫做元空间.这个元空间是存放在本地内存中的. 方法区中存放着每个class对应的运行时常量池. 当类或者接口创建

  • 浅谈Java类的加载,链接及初始化

    一 类生命周期 Loading Linking(Verification.Preparation.Resolution) Initializing 二 类加载器 1 图解 2 代码 package jvm; public class T002_ClassLoadLevel { public static void main(String[] args) { System.out.println(String.class.getClassLoader()); System.out.println(

  • 详解webpack import()动态加载模块踩坑

    import webpack根据ES2015 loader 规范实现了用于动态加载的import()方法. 这个功能可以实现按需加载我们的代码,并且使用了promise式的回调,获取加载的包. 在代码中所有被import()的模块,都将打成一个单独的包,放在chunk存储的目录下.在浏览器运行到这一行代码时,就会自动请求这个资源,实现异步加载. 这里是一个简单的demo. import('lodash').then(_ => { // Do something with lodash (a.k.

随机推荐