【问题标题】:ES6/TypeScript Dynamic Imports - Slow launch time because of static imports (Nodejs CLI)ES6/TypeScript 动态导入 - 由于静态导入(Nodejs CLI)而导致启动时间变慢
【发布时间】:2020-10-11 17:17:12
【问题描述】:

在我的 nodejs 代码中,我已经用 ES6 import { ... } from "x" 替换了许多 require(x)。 不幸的是,这对我的 nodejs-CLI-program 的启动时间非常不利。

让我先给你一点背景:

我有一个使用大量外部包的 nodejs-CLI 程序,但大多数这些包仅在极少数情况下需要(例如,如果将特定标志传递给我的程序)。 这些导入对我的程序的启动时间造成了很大的开销。 由于这些导入,即使像 myprogram --help 这样的微不足道的命令也需要超过一秒钟的时间。

为了解决这个启动时间问题,我想对某些功能进行“动态导入”。 换句话说,我只想在给定的 CLI 命令实际需要特定功能时才导入某些包。

使用旧的require-mechanics,通过有条件地调用require 可以轻松实现。但是,我不确定如何为现代 TypeScript 代码执行此操作。

如果您对此类启动时间问题有任何建议,请告诉我。

【问题讨论】:

    标签: node.js typescript command-line-interface es6-modules


    【解决方案1】:

    你可以在 TypeScript 中使用Dynamic Import Expressions

    动态导入表达式是 ECMAScript 的一项新功能和一部分 允许用户以任意方式异步请求模块 点在你的程序中。

    这意味着你可以有条件地懒惰地导入其他模块 和图书馆。例如,这是一个只导入的异步函数 需要时的实用程序库。

    (在 JavaScript 中,仍然是一个提案:https://github.com/tc39/proposal-dynamic-import

    例子:

    你有一个主文件和两个依赖项。

    ./main.ts
    ./dependency-a.ts
    ./dependency-b.ts
    

    依赖 'a' 将快速加载。

    console.log('exporting dependency-a');
    
    export const a = () => {
      console.log('called dependency-a');
    };
    

    虽然依赖 'b' 会加载缓慢。

    console.log('exporting dependency-b');
    
    // We'll emulate a slow synchronous task with a loop to add delay
    // https://stackoverflow.com/a/38839049/4669212
    function wait(ms: number) {
      var start = Date.now(),
        now = start;
      while (now - start < ms) {
        now = Date.now();
      }
    }
    
    wait(5000);
    
    export const b = () => {
      console.log('called dependency-b');
    };
    

    在你的主文件中,你有条件地调用了导出的函数,但是由于依赖'b',启动时间会很慢,即使你只是想调用依赖'a':

    import { a } from './dependency-a';
    import { b } from './dependency-b';
    
    const run = (dep: 'a' | 'b') => {
      switch (dep) {
        case 'a':
          return a();
    
        case 'b':
          return b();
    
        default:
          console.log('do nothing');
      }
    };
    
    run();
    

    您可以像这样使用动态 import() 表达式:

    const run = (dep: 'a' | 'b') => {
      switch (dep) {
        case 'a':
          return import('./dependency-a').then(({ a }) => {
            a();
          });
        case 'b':
          return import('./dependency-b').then(({ b }) => {
            b();
          });
        default:
          console.log('do nothing');
      }
    };
    
    run('a');
    

    当您运行依赖项“a”时,将不会加载慢速依赖项“b”——它是导入语句,如果有的话。这意味着您的 CLI 将有更好的启动时间。

    【讨论】:

      猜你喜欢
      • 2018-11-19
      • 1970-01-01
      • 2019-12-18
      • 2019-02-08
      • 2018-06-03
      • 2018-05-17
      • 2019-11-13
      • 2023-02-01
      • 1970-01-01
      相关资源
      最近更新 更多