ts 中的 import() 不是动态的?原因是什么?
根据 MDN,import ()
是一个类似函数的动态方法。但是,我发现它在我的 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。根据我有限的知识,我猜有两个可能的原因:
- 我对
import()
和动态导入有误解。 - 我的理解是正确的,但是
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:
- I have a misunderstanding in
import()
and dynamic importing. - My understanding is right but
vs-code
compiled all the code tojs
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 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(1)
“动态”
import()
与通常称为“静态”导入的常规import
具有以下不同的行为。导入
动态构建模块文件名。常规导入
的文件名必须静态指定,以便解析该文件但不运行其中代码的任何人都知道它们。此静态声明支持对诸如树摇动和捆绑之类的事情进行代码分析。动态导入不能有效地与此类功能一起使用。import()
可以发生在代码中的任何位置(不仅在模块的顶部)。常规import
不能只出现在代码中的任何位置。从这个意义上说,它是根据需要“动态”加载的,而不仅仅是在模块的开头。import()
语句可用于将 ESM 模块加载到 CommonJS 模块中。常规import
语句根本不能在 CommonJS 模块中使用。模块,甚至动态加载的模块都会被缓存。加载后,使用相同文件名的后续
import()
语句只会从缓存中加载模块,而不会重新读取文件。这就是为什么您的后续import()
不会获取修改后的 JSON。如果您想重新读取文件,请不要使用
import
- 使用fs.promises.readFile()
之类的东西,然后解析 JSON。每次调用时都会读取数据的新副本。The "dynamic"
import()
has the following different behaviors from the regularimport
which is often referred to as the "static" import.import
. Filenames for the regularimport
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.import()
can happen anywhere in your code (not only at the top of your module). The regularimport
cannot be just anywhere in your code. In this sense, it is "dynamically" loaded upon demand, not only at the beginning of the module.import()
statement can be used to load an ESM module into a CommonJS module. The regularimport
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 subsequentimport()
is not picking up the modified JSON.If you want to re-read the file, then don't use
import
- use something likefs.promises.readFile()
and then parse the JSON. This will read a fresh copy of the data each time you call it.