在使用 Deno 进行开发时,我们经常会使用 import 语句来导入模块。在某些情况下,我们需要多次导入同一个模块,但是如果不注意,就容易出现模块重复导入的问题,导致代码运行出错。本文将介绍如何解决 Deno 中 import 多次同一模块出错的问题。
问题的根源
在 Deno 中,模块的加载遵循的是 ECMAScript 的规范,即每一个模块只会被加载一次,且在第一次加载后就会被缓存起来。这是出于性能和资源利用的考虑,避免了重复加载同一个模块的情况。所以,多次导入同一个模块其实是不必要的,而且容易出错。
例如,我们有一个 utils.ts
文件,其中定义了一个 getRandom
函数:
export function getRandom(): number { return Math.random(); }
然后在另一个文件 main.ts
中,我们希望多次使用 getRandom
函数:
import { getRandom } from "./utils.ts"; console.log(getRandom()); import { getRandom } from "./utils.ts"; // 错误的重复导入 console.log(getRandom());
在第二次 import ./utils.ts
时,就会出现错误:
error: Uncaught TypeError: getRandom is not a function
这是因为在第一次导入 ./utils.ts
时,模块已经被缓存起来了,第二次导入只是从缓存中获取,不会重新加载模块,因此第二次导入中的 getRandom
并没有被定义。
解决方法
有几种方法可以解决这个问题:
1. 只导入一次
最简单的方法是只导入一次,把需要使用的函数保存在变量中:
import { getRandom } from "./utils.ts"; console.log(getRandom()); const random = getRandom; console.log(random());
这样,就不会出现重复导入的问题了。
2. 分离导出和实现
另一种方法是分离导出和实现,把需要导出的函数单独定义在一个文件中,并在另一个文件中导入:
// utils.ts function getRandom(): number { return Math.random(); } export { getRandom };
// javascriptcn.com 代码示例 // main.ts import { getRandom } from "./utils.ts"; console.log(getRandom()); import { getRandom } from "./utils.ts"; // 正确的重复导入,因为只有导出被缓存 console.log(getRandom());
这样,只有导出被缓存,导入的时候会重新加载模块获取最新的导出项。
3. 把模块包装成函数
还有一种方法是把需要用到的模块包装成一个函数,每次调用函数时重新执行模块:
// utils.ts export function getRandom(): number { return Math.random(); }
// javascriptcn.com 代码示例 // utilsWrapper.ts import * as utils from "./utils.ts"; export function wrapUtils() { return { ...utils }; }
// javascriptcn.com 代码示例 // main.ts import { wrapUtils } from "./utilsWrapper.ts"; const { getRandom } = wrapUtils(); console.log(getRandom()); const { getRandom: getRandom2 } = wrapUtils(); console.log(getRandom2());
这样,每次调用 wrapUtils
函数返回的对象时,都会重新加载模块,避免了重复导入同一个模块的问题。
总结
在 Deno 中,import 多次同一个模块容易出现问题。我们可以采取几种方法来解决这个问题,例如只导入一次、分离导出和实现、把模块包装成函数等。在实际开发中,我们应该避免重复导入同一个模块,以避免出现不必要的错误。
来源:JavaScript中文网 ,转载请注明来源 本文地址:https://www.javascriptcn.com/post/651bb9b595b1f8cacd35a152