• 动态 import()


    动态 import()

    https://v8.dev/features/dynamic-import

    Dynamic import() 引入了一个新的类似函数的功能,相比静态的 import 提供了新的功能。本文比较这两个特性,并提供了新功能的介绍。

    静态 import (回顾)

    在 Chrome 61 中提供了对于 ES2015 的 modulesimport 语句的支持。

    考虑如下 module,它位于地址 ./utils.mjs

    // Default export
    export default () => {
      console.log('Hi from the default export!');
    };
    
    // Named export `doStuff`
    export const doStuff = () => {
      console.log('Doing stuff…');
    };
    

    如下代码演示如何使用静态导入,并使用 ./util.mjs 模块。

    <script type="module">
      import * as module from './utils.mjs';
      module.default();
      // → logs 'Hi from the default export!'
      module.doStuff();
      // → logs 'Doing stuff…'
    </script>
    

    注意
    在上述示例中,使用了 .mjs 扩展名来表示这个一个模块,而不是常规的脚本。
    在 Web 中,文件的扩展名并不重要,只要在 Content-Type 响应头中使用了正确的 MIME 类型即可 ( 例如,对于 JavaScript 文件来说,为 text/javascript) 。

    .mjs 扩展名对于其它平台特别有用,比如 Node.js 和 d8,因为在这些环境中,没有 MIME 的支持或者其它强制的要求,例如 type="module" 来检测它到底是模块还是常规的脚本。我们这里使用 .mjs 扩展名来实现跨平台的一致性,并清楚地区分模块和常规脚本。

    这里使用的导入模块方式就是 静态 定义:它只接受一个字面字符串作为模块的指示器,通过链接过程将绑定引入到本地范围。静态的 import 语法只能用于文件的顶级。

    静态 import 支持重要的使用场景,例如静态分析,打包工具以及摇树操作。

    对于有些场景,需要支持:

    • 按需加载模块 ( 或者有条件 )
    • 在运行时得到模块的指示符
    • 从常规的脚本 ( 不是模块) 中加载模块

    这些需求都不能通过静态 import 得到。

    动态 import()

    Dynamic import() 引入了 import 的新特性来处理这些场景。import(moduleSpecifier) 返回请求模块的模块对象的一个 Promise。它将在获取之后创建,并检查该模块所有的依赖,以及该模块本身。

    这里是如何使用动态 import() 来加载 ./utils.mjs 模块。

    <script type="module">
      const moduleSpecifier = './utils.mjs';
      import(moduleSpecifier)
        .then((module) => {
          module.default();
          // → logs 'Hi from the default export!'
          module.doStuff();
          // → logs 'Doing stuff…'
        });
    </script>
    

    由于 import() 返回一个 Promise,就可以使用 async/await 来代替 Promise 的 then() 调用风格。

    <script type="module">
      (async () => {
        const moduleSpecifier = './utils.mjs';
        const module = await import(moduleSpecifier)
        module.default();
        // → logs 'Hi from the default export!'
        module.doStuff();
        // → logs 'Doing stuff…'
      })();
    </script>
    

    注意
    尽管 import() 看起来类似一个函数调用,实际上它是一个语法,只是使用了圆括号而已,类似 super()。这意味着 import() 的原型并不是 Function.prototype,所以你也不能对它使用 call() 或者 apply()
    类似语法也不能工作 const importAlias = import,甚至,import 都不是一个对象!尽管在实践中并不重要。

    这里是一个使用动态 import() 来实现延迟加载模块的示例,基于一个小型的 SPA 应用的导航。

    <!DOCTYPE html>
    <meta charset="utf-8">
    <title>My library</title>
    <nav>
      <a href="books.html" data-entry-module="books">Books</a>
      <a href="movies.html" data-entry-module="movies">Movies</a>
      <a href="video-games.html" data-entry-module="video-games">Video Games</a>
    </nav>
    <main>This is a placeholder for the content that will be loaded on-demand.</main>
    <script>
      const main = document.querySelector('main');
      const links = document.querySelectorAll('nav > a');
      for (const link of links) {
        link.addEventListener('click', async (event) => {
          event.preventDefault();
          try {
            const module = await import(`/${link.dataset.entryModule}.mjs`);
            // The module exports a function named `loadPageInto`.
            module.loadPageInto(main);
          } catch (error) {
            main.textContent = error.message;
          }
        });
      }
    </script>
    

    当正确使用的时候,使用动态 import() 来实现延迟加载可以非常强大,为了演示目的,Addy 创建了 an example Hacker News PWA,其中使用静态导入所有依赖的模块,在第一次加载的时候加载留言。更新后的版本 使用动态 import() 来延迟加载留言,避免了加载、解析和编译的代价,直到用户需要才会处理。

    参考资料

  • 相关阅读:
    Excel透视表进阶之计算字段、计算项、切片器、页面布局
    Excel透视表进阶之排序、筛选、分组、总计与分类汇总
    Excel透视表基础之字段布局与重命名、更新、数字格式设置、空值与错误值、
    Excel透视表基础之数据源、创建、基本术语、基本操作
    NumPy基础
    Python读写Excel
    逻辑判断
    打印 PRINT
    面向对象
    循环控制
  • 原文地址:https://www.cnblogs.com/haogj/p/16135673.html
Copyright © 2020-2023  润新知