【发布时间】:2018-11-19 05:00:33
【问题描述】:
我想问一下是否可以使用自定义 Promise 来加载模块,而不是立即解析 typescript 使用的 Promise。
如果我有
function test() {
const m: any = import("./test");
console.log(m);
}
tsc 转译为立即(几乎 ;))解析调用 require 的 Promise,类似于:
function test() {
m = Promise.resolve().then(() => require("..."));
console.log(m);
}
当模块(或更好的模块包)从 HTML 脚本标签加载时,它实际上运行良好,但我想使用自定义延迟加载器返回 Promise 并在模块(包)将由自定义加载器加载时解决它在应用程序生命周期的后期(基本上是在需要时 - 而不是在加载 html 时),然后使用 require 从加载的模块包中提供特定模块。
这是否可以通过 TS 实现,还是我需要使用不同的方法(即自定义导入功能)?我更喜欢TS方式。
目标:“esnext”,模块:“commonjs”
编辑(回答):
首先,我的想法很糟糕。
function timer(): Promise<void> {
return new Promise<void>((resolve: () => void) => {
setTimeout(resolve, 3000);
});
}
let p = Promise.resolve().then(async() => { await timer(); } )
当 .then 回调完成时得到解决。不是在它之前。所以它不会立即解决承诺,在前面提到的情况下,一旦 require 函数返回,它就会得到解决。我不知道,所以我有点困惑。
除此之外,当 TSC 模块设置为“commonjs”时,如果没有一些捆绑器或后编译器(例如 babel 或 webpack),则无法使用动态导入。当使用 babel 或 webpack 时,动态导入可以用另一个加载器/解析器替换,而不是 require 以便异步加载脚本,执行并从中解析模块。我没有在节点中进行测试,它可以开箱即用,无需额外的构建工具。
TSC模块“esnext”的import关键字由TSC保存在代码中,可以直接在支持的环境中使用。
【问题讨论】:
-
您需要使用模块类型为“esnext”而不是“commonjs”。
-
是的,我已经想通了,谢谢。无论如何,它对我没有用,因为我想将模块打包在一起。
-
但我仍然不明白为什么 typescript 会生成 Promise.resolve()。在打包器用自定义的东西替换它之前它是无用的。
标签: typescript dynamic import