我也有这样的情况。它们是动态的原因是为了防止加载执行某个命令行任务所需的 10 倍的代码量。
if (diagnostics) {
require('./lib/cli-commands/run-diagnostics').run(sumanOpts);
}
else if (script) {
require('./lib/cli-commands/run-scripts').run(sumanConfig, sumanOpts);
}
else if (tscMultiWatch) {
require('./lib/cli-commands/run-tscmultiwatch').run(sumanOpts);
}
else if (repair) {
require('./lib/cli-commands/run-repair').run(sumanOpts);
}
else if (postinstall) {
require('./lib/cli-commands/postinstall').run(sumanOpts);
}
else{
// etc etc
}
如果我尝试动态加载导入调用,我会得到以下结果:
它显然会返回
Promise
而不是 module.exports
值。
有没有一种方法可以使用动态导入语法而不需要异步加载或没有?
只是为了添加 Unional 的正确答案,使用
Promise
返回动态导入语法非常容易。
(async function () {
if (diagnostics) {
const run = await import('./lib/cli-commands/run-diagnostics');
run(sumanOpts);
}
else if (script) {
const run = await import('./lib/cli-commands/run-scripts');
run(sumanConfig, sumanOpts);
}
}());
请注意,如果您使用
--module commonjs
模块,那么最好坚持使用 require。然而,上面的内容非常适合--module amd
、--module system
,当然还有--module esnext
。
动态导入的本质是异步的。
require()
是同步的,因为它位于服务器端。您可以使用(例如)fs.readFileSync()
同步读取文件。
对于新的动态导入,它被设计为在客户端工作,因此将有一个ajax请求返回到服务器以执行导入。
因此它必须是异步的。
纯异步动态
import()
是ECMAScript功能,TypeScript演变的趋势是尽可能坚持使用ECMAScript。
TypeScript 可以配置为以不同的方式输出 JS,并适应不同的模块系统。确实,这些选项之一是将您的 TS 项目全部转译为使用 AMD 的单个 JS 文件,在这种情况下,TypeScript 会将所有导入转换为同步
require()
,这意味着您 可以 有一个同步 import()
功能。然而,这只是所有可能的转译目标中的“一个”。您可以看到,如果 TypeScript 不想引入一种新的 import()
方式(与 ECMAScript 不兼容!)作为仅一种可能的转译模式的特例,这是可以理解的。
这可能有助于此用例。
npm:esm的包装器,支持从 ES6 和基于 CJS 的 NodeJS 项目导入 ESM。 我还没有对 TS 动态导入进行广泛的实验,但从我的尝试/测试来看,它确实可以运行
ts-node
。
例如,// const importSync = require('import-sync');
import importSync from 'import-sync');
if (diagnostics) {
importSync('./lib/cli-commands/run-diagnostics').run(sumanOpts);
}
else if (script) {
importSync('./lib/cli-commands/run-scripts').run(sumanConfig, sumanOpts);
}
else if (tscMultiWatch) {
importSync('./lib/cli-commands/run-tscmultiwatch').run(sumanOpts);
}
else if (repair) {
importSync('./lib/cli-commands/run-repair').run(sumanOpts);
}
else if (postinstall) {
importSync('./lib/cli-commands/postinstall').run(sumanOpts);
}
else{
// etc etc
}