JavaScript import 如何找到没有扩展名的模块?
How does JavaScript import find the module without an extension?
我知道我们可以使用 import {x} from "./file"
并且变量 x
将从同一目录中的 file.js
导入。目录下存在不同扩展名的同名文件如何处理?
例如,如果同一目录中有 file.js
和 file.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 格式,这将最终使用 require
。 require
有一个扩展列表,它将在文件系统中搜索。
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 设置。
如果你使用 webpack
和 ts-loader 插件,.ts
文件扩展名也会被识别,但是加载程序会尝试编译它以便编译 .ts
文件进入 .js
文件,并在捆绑时尝试使用已编译的 .js
文件。
如果您使用普通的 typescript 编译器来编译您的脚本,编译器将查找扩展名为“.ts”的文件来执行类型检查,但它会生成代码来查找扩展名为“.js”的文件当您 运行 脚本时扩展。此外,如果编译了扩展名为“.ts”的文件,编译器会将生成的代码写入扩展名为“.js”的文件中,并且可能会覆盖 javascript 文件(如果有),具体取决于设置它在哪里输出'.js'文件。
@PeterT 描述对我有用。但我还是想解释更多。在开发中,所有配置和捆绑都由 webpack 设置,所以我们不需要做任何这样的事情。当我们自己用 typescript 学习模块并想尝试使用基本的 typescript 编译器时,我们肯定需要这样做。
在 typescript 文件导入中,像这样在导入部分包含 .js 扩展名
import {x} from 'X.js';//记得包含'.js'
我知道我们可以使用 import {x} from "./file"
并且变量 x
将从同一目录中的 file.js
导入。目录下存在不同扩展名的同名文件如何处理?
例如,如果同一目录中有 file.js
和 file.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 格式,这将最终使用 require
。 require
有一个扩展列表,它将在文件系统中搜索。
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 设置。
如果你使用 webpack
和 ts-loader 插件,.ts
文件扩展名也会被识别,但是加载程序会尝试编译它以便编译 .ts
文件进入 .js
文件,并在捆绑时尝试使用已编译的 .js
文件。
如果您使用普通的 typescript 编译器来编译您的脚本,编译器将查找扩展名为“.ts”的文件来执行类型检查,但它会生成代码来查找扩展名为“.js”的文件当您 运行 脚本时扩展。此外,如果编译了扩展名为“.ts”的文件,编译器会将生成的代码写入扩展名为“.js”的文件中,并且可能会覆盖 javascript 文件(如果有),具体取决于设置它在哪里输出'.js'文件。
@PeterT 描述对我有用。但我还是想解释更多。在开发中,所有配置和捆绑都由 webpack 设置,所以我们不需要做任何这样的事情。当我们自己用 typescript 学习模块并想尝试使用基本的 typescript 编译器时,我们肯定需要这样做。
在 typescript 文件导入中,像这样在导入部分包含 .js 扩展名
import {x} from 'X.js';//记得包含'.js'