JavaScript import 如何找到没有扩展名的模块?

How does JavaScript import find the module without an extension?

我知道我们可以使用 import {x} from "./file" 并且变量 x 将从同一目录中的 file.js 导入。目录下存在不同扩展名的同名文件如何处理?

例如,如果同一目录中有 file.jsfile.ts,那么 import {x} from "./file" 会如何表现?是否取决于 JavaScript 的版本?

Would it depend on the version of javascript?

不是,这取决于JavaScript 运行时间的行为,也就是执行你的脚本的那个东西。

在支持 ES 模块 (ESM) 的浏览器中,不会将扩展名添加到您 import 的 URL - 例如,如果您的文件具有 .js 扩展名,你必须写import {x} from "./file.js"。浏览器没有有用的方法来查找服务器上可用的扩展名的文件。

在不支持 ESM 的浏览器中,您必须将模块转译为捆绑格式,以便 运行 在浏览器中使用。在这种情况下,这取决于您选择使用的特定捆绑器的行为(见下文)。

在支持 ESM 的 Node.js 版本中,运行time 不会搜索扩展,但会按名称解析来自 node_modules 的模块。例如 import 'lodash' 可以解析为 ./node_modules/lodash/index.mjs,而无需知道 index.mjs.

的扩展名

在 Node.js 支持 ESM 的版本中,您不能使用 import - 您必须先将模块转换为 CommonJS 格式,这将最终使用 requirerequire 有一个扩展列表,它将在文件系统中搜索。

For example, if there were file.js and file.ts in the same directory, how would import {x} from "./file" behave?

视情况而定。

当您转译或编译脚本时,识别哪些扩展名取决于编译器和您为编译提供的设置。

例如,在 webpack 中,支持扩展的预定义列表 - webpack.config.js 文件中的 '.wasm', '.mjs', '.js', '.json', but it could be changed by using resolve.extension 设置。

如果你使用 webpackts-loader 插件,.ts 文件扩展名也会被识别,但是加载程序会尝试编译它以便编译 .ts 文件进入 .js 文件,并在捆绑时尝试使用已编译的 .js 文件。

如果您使用普通的 typescript 编译器来编译您的脚本,编译器将查找扩展名为“.ts”的文件来执行类型检查,但它会生成代码来查找扩展名为“.js”的文件当您 运行 脚本时扩展。此外,如果编译了扩展名为“.ts”的文件,编译器会将生成的代码写入扩展名为“.js”的文件中,并且可能会覆盖 javascript 文件(如果有),具体取决于设置它在哪里输出'.js'文件。

@PeterT 描述对我有用。但我还是想解释更多。在开发中,所有配置和捆绑都由 webpack 设置,所以我们不需要做任何这样的事情。当我们自己用 typescript 学习模块并想尝试使用基本的 typescript 编译器时,我们肯定需要这样做。

在 typescript 文件导入中,像这样在导入部分包含 .js 扩展名

import {x} from 'X.js';//记得包含'.js'