You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

导入JavaScript模块时何时需要添加文件扩展名?

关于JS导入语句是否带文件扩展名的差异说明

这种写法差异确实和ES Modules(ESM)与CommonJS(CJS)的规范区别直接相关,同时也会受运行环境、构建工具配置的影响,具体规则可以拆成三类场景说明:

  • CommonJS 环境的原生解析逻辑
    CommonJS 是 Node.js 早期默认的模块系统,它的require()导入语法原生支持自动补全文件扩展名的解析逻辑。当你写require('./foo')时,运行时会按顺序做以下查找:
    1. 先匹配是否为Node内置核心模块
    2. 查找当前路径下是否存在名为foo的文件,不存在则依次尝试补全.js、.json、.node后缀匹配
    3. 以上都没命中时,会将foo视为目录,查找目录下的index.js/index.json等默认入口文件
      因此在纯CommonJS环境中,导入语句写不写扩展名都能正常解析,多数传统CJS项目也形成了省略扩展名的编码习惯。
  • 原生ES Modules 环境的强制要求
    按照TC39发布的ESM官方规范,不管是浏览器原生ESM,还是Node.js的稳定版原生ESM,默认都不会做自动补全文件扩展名的处理,要求导入路径必须明确写全文件后缀。
    也就是说在原生ESM环境下,下面的写法会直接触发模块找不到的错误:
    // 错误写法,原生ESM无法解析
    import { myFunc } from './foo';
    
    必须显式标注扩展名才能正常加载:
    // 正确写法
    import { myFunc } from './foo.js';
    
    Node为了区分两类模块,还额外约定:.cjs后缀文件永远按CommonJS解析,.mjs后缀文件永远按ESM解析;如果package.json中声明了"type": "module",则目录下的.js文件都会被视为ESM处理,这时候所有ESM导入语句都必须遵守写全扩展名的规范。
  • 构建工具带来的兼容例外
    现在很多前端项目里写ESM导入也能省略扩展名,这不是原生ESM的特性,是Webpack、Rollup、Vite、TypeScript编译器等构建/转译工具做的兼容处理:这些工具默认复刻了CommonJS的路径解析逻辑,在构建阶段会自动帮你补全省略的文件后缀,甚至支持自定义配置.jsx、.ts、.vue等非标准JS后缀的自动匹配。
    要注意的是,如果你的代码不需要经过构建,要直接跑在浏览器原生ESM环境、或者Node原生ESM环境下,就必须写全文件扩展名,否则一定会出现加载失败的问题。

内容的提问来源于stack exchange,提问作者sal3jfc

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.09.03 10:21:39