Jamey's Jamey's
首页
导航站
  • 学习专栏

    • 《HTML》笔记
    • 《CSS》笔记
    • 《JavaScript》笔记
    • 《Vue》笔记
    • 《Git》笔记
    • 《规范》笔记
    • 《软技能》笔记
    • 《面试》笔记
    • 《持续集成&交付&部署》笔记
  • 踩坑专栏

    • 《Element-UI 实践系列》笔记
    • 《移动端 实践系列》笔记
    • 《综合》笔记
  • 配置专栏

    • 《环境系列》笔记
  • 极空间

    • Docker
  • 影视

    • movie
  • 编辑器笔记

    • 开发编辑器
  • 浏览器笔记

    • Chrome
  • Mac笔记

    • Mac
  • 跨界学习

    • 运营
  • 破解合集

    • 破解
  • 本站

    • 分类
    • 标签
    • 归档
  • 我的

    • 收藏
    • 书单
    • 关于

Jamey

首页
导航站
  • 学习专栏

    • 《HTML》笔记
    • 《CSS》笔记
    • 《JavaScript》笔记
    • 《Vue》笔记
    • 《Git》笔记
    • 《规范》笔记
    • 《软技能》笔记
    • 《面试》笔记
    • 《持续集成&交付&部署》笔记
  • 踩坑专栏

    • 《Element-UI 实践系列》笔记
    • 《移动端 实践系列》笔记
    • 《综合》笔记
  • 配置专栏

    • 《环境系列》笔记
  • 极空间

    • Docker
  • 影视

    • movie
  • 编辑器笔记

    • 开发编辑器
  • 浏览器笔记

    • Chrome
  • Mac笔记

    • Mac
  • 跨界学习

    • 运营
  • 破解合集

    • 破解
  • 本站

    • 分类
    • 标签
    • 归档
  • 我的

    • 收藏
    • 书单
    • 关于
  • 深入系列

  • 专题系列

  • underscore系列

  • ES6系列

  • 模块化

    • 模块化
    • 模块导入 import
    • 模块导出 export
    • 模块导入/导出的复合写法
    • 模块继承
    • 跨模块常量
    • 动态加载
      • 一. 适用场景
        • 1. 按需加载
        • 2. 条件加载
        • 3. 动态的模块路径
      • 二. 注意事项
        • 1. 解构赋值输出模块导入
        • 2. 默认模块导入
        • 3. 命名模块导入
        • 4. 并发加载多个模块
        • 5. 异步函数的模块导入
  • 正则表达式

  • 单元测试

  • 微前端

  • 实用函数

  • Rollup

  • 解决方案

  • 《JavaScript》笔记
  • 模块化
Jamey
2022-03-06
目录

动态加载

# 动态加载

import 命令会被 JavaScript 引擎静态分析,先于模块内的其他语句执行(import 命令叫做 连接)。因此,下面的代码会报错。

// Error
if (x === 2) {
  import module from './module';
}
1
2
3
4

⚠️ 注意: 引擎处理 import 语句是在编译阶段,这时并不会去分析或执行 if 语句,所以 import 语句放在 if 代码块之中毫无意义,因此会报句法错误,而不是执行错误。 也就是说,import 和 export 命令只能在模块的顶层,不能在代码块之中。

如此的设计,固然有利于编译器提高效率,但也导致无法再运行时加载模块。在语法上,条件加载就不可能实现。如果 import 命令要取代 Node 的 require 方法,这就形成了一个障碍。 因为 require 是运行时加载模块,import 命令无法取代 require 的 动态加载功能。

const path = './' + fileName;

const myModual = require(path);
1
2
3

上面的语句就是动态加载,require 到底加载哪一个模块,只有运行时才知道。import 命令做不到这一点。

因此,有一个 提案 (opens new window),建议引入 import() 函数,实现动态加载。

import(module);
1

参数 module,表示指定所要加载的模块的位置。import 命令能够接受什么参数,import() 函数就能接受什么参数,两者区别主要是后者为动态加载。

import() 返回一个 Promise 对象。

const main = document.querySelector('main');

import(`./section-modules/${someVariable}.js`)
  .then((module) => {
    module.loadPageInto(main);
  })
  .catch((err) => {
    main.textContent = err.message;
  });
1
2
3
4
5
6
7
8
9

import() 函数可以用在任何地方,不仅仅是模块,非模块的脚本也可以使用。它是运行时执行,也就是说,什么时候运行到这一句,就会加载指定的模块。 另外,import() 函数与所加载的模块没有静态连接关系,这点也是与 import 语句不相同。import() 类似于 Node 的 require 方法,区别主要是前者是异步加载,后者是同步加载。

# 一. 适用场景

# 1. 按需加载

import() 可以在需要的时候,再加载某个模块。

button.addEventListener('click', (event) => {
  import('./dialogBox.js')
    .then((dialogBox) => {
      dialogBox.open();
    })
    .catch((err) => {
      /* Error handling */
    });
});
1
2
3
4
5
6
7
8
9

上面代码中,import() 方法放在 click 事件的监听函数之中,只有用户点击了按钮,才会加载这个模块。

# 2. 条件加载

import() 可以放在 if 代码块,根据不同的情况,加载不同的模块。

if (condition) {
  import('moduleA').then(...);
} else {
  import('moduleB').then(...);
}
1
2
3
4
5

上面代码中,如果满足条件,就加载模块 A,否则加载模块 B。

# 3. 动态的模块路径

import() 允许模块路径动态生成。

import(fn()).then(() => {});
1

上面代码中,根据函数 fn 的返回结果,加载不同的模块。

# 二. 注意事项

# 1. 解构赋值输出模块导入

import() 加载模块成功以后,这个模块会作为一个对象,当作 then 方法的参数。因此,可以使用对象解构赋值的语法,获取输出接口。

import('./module.js').then(({ export1, export2 }) => {
  // do something
});
1
2
3

上面代码中,export1 和 export2 都是 module.js 的输出接口,可以解构获得。

# 2. 默认模块导入

如果模块有 default 输出接口,可以用参数直接获得。

import('./module.js').then((module) => {
  console.log(module.default);
});
1
2
3

# 3. 命名模块导入

上面的代码也可以使用 具名输入 的形式。

import('./module.js').then(({ default: defaultInterface}) => {
  console.log(defaultInterface);
});
1
2
3

# 4. 并发加载多个模块

如果想 同时加载多个模块,可以采用下面的写法:

Promise.all([import('./module1.js'), import('./module2.js'), import('./module3.js')]).then(
  ([module1, module2, module3]) => {
    // do something
  }
);
1
2
3
4
5

# 5. 异步函数的模块导入

import() 也可以在 async 函数 之中。

async function main() {
  const module = await import('./module.js');
  
  const { export1, export2 } = await import('./module.js');
  
  const [module1, module2, module3] = await Promise.all([
    import('./module1.js'),
    import('./module2.js'),
    import('./module3.js'),
  ]);
};

main();
1
2
3
4
5
6
7
8
9
10
11
12
13
#JavaScript 模块化
上次更新: 2022/07/08, 18:18:02
跨模块常量
正则表达式

← 跨模块常量 正则表达式→

Theme by Vdoing | Copyright © 2017-2023 Jamey | blog 闽ICP备19022664号
  • 跟随系统
  • 浅色模式
  • 深色模式
  • 阅读模式