ts 中的 import() 不是动态的?原因是什么?

发布于 2025-01-11 13:22:29 字数 890 浏览 0 评论 0原文

根据 MDNimport () 是一个类似函数的动态方法。但是,我发现它在我的 ts 项目中不是动态的。

假设我有一个 appleShare.json:

{
    price: 123
}

然后,有一个 index.ts:

console.log("update the price to 456...")
// manually modify the json file content making price 456
let currentPrice = await import("./appleShare.json").then(obj=obj.price)
console.log(currentPrice)  

我直接在 vs-code 中运行 index.ts,控制台中的结果:

update the price to 456...
123

我期望 456,但得到了 123。根据我有限的知识,我猜有两个可能的原因:

  1. 我对 import() 和动态导入有误解。
  2. 我的理解是正确的,但是 vs-code 在执行之前将所有代码编译为 js 。所以,我永远不会得到新修改的价格。

我想请问一下,这个问题到底是什么原因造成的,如何解决?

According to MDN, import() is a function-like dynamic method. However, I found it not dynamic in my ts project.

Say I have an appleShare.json:

{
    price: 123
}

And then, there's an index.ts:

console.log("update the price to 456...")
// manually modify the json file content making price 456
let currentPrice = await import("./appleShare.json").then(obj=obj.price)
console.log(currentPrice)  

I ran index.ts directly in vs-code, the result in console:

update the price to 456...
123

I expect 456, but got 123. From my limited knowledge I guess there are two possible reasons:

  1. I have a misunderstanding in import() and dynamic importing.
  2. My understanding is right but vs-code compiled all the code to js before executing them. So, I will never get the newly modified price.

I want to ask, what's exactly the cause of the issue, and how to resolve it?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

老子叫无熙 2025-01-18 13:22:29

“动态”import() 与通常称为“静态”导入的常规 import 具有以下不同的行为。

  1. 您可以在代码中构造一个模块文件名,然后可以从您构建的文件名加载该模块。您无法使用常规导入动态构建模块文件名。常规导入的文件名必须静态指定,以便解析该文件但不运行其中代码的任何人都知道它们。此静态声明支持对诸如树摇动和捆绑之类的事情进行代码分析。动态导入不能有效地与此类功能一起使用。
  2. import() 可以发生在代码中的任何位置(不仅在模块的顶部)。常规 import 不能只出现在代码中的任何位置。从这个意义上说,它是根据需要“动态”加载的,而不仅仅是在模块的开头。
  3. 动态 import() 语句可用于将 ESM 模块加载到 CommonJS 模块中。常规 import 语句根本不能在 CommonJS 模块中使用。

模块,甚至动态加载的模块都会被缓存。加载后,使用相同文件名的后续 import() 语句只会从缓存中加载模块,而不会重新读取文件。这就是为什么您的后续 import() 不会获取修改后的 JSON。

如果您想重新读取文件,请不要使用 import - 使用 fs.promises.readFile() 之类的东西,然后解析 JSON。每次调用时都会读取数据的新副本。

The "dynamic" import() has the following different behaviors from the regular import which is often referred to as the "static" import.

  1. You can construct a module filename in code and can then load that module from the filename you built. You cannot dynamically build module filenames with the regular import. Filenames for the regular import must be statically specified so they are known by anyone who parses the file, but does not run the code in it. This static declaration enables code analysis for things like tree-shaking and bundling. The dynamic import cannot be used as effectively with features like that.
  2. The import() can happen anywhere in your code (not only at the top of your module). The regular import cannot be just anywhere in your code. In this sense, it is "dynamically" loaded upon demand, not only at the beginning of the module.
  3. A dynamic import() statement can be used to load an ESM module into a CommonJS module. The regular import statement cannot be used in a CommonJS Module at all.

Modules, even dynamically loaded ones are cached. Once they are loaded, subsequent import() statements using the same filename just load the module from the cache, they do not re-read the file. That's why your subsequent import() is not picking up the modified JSON.

If you want to re-read the file, then don't use import - use something like fs.promises.readFile() and then parse the JSON. This will read a fresh copy of the data each time you call it.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文