vscode点运行报err_require_esm或unexpected token 'export',根本原因是其默认用node script.js以commonjs模式执行含import/export的文件;须确保node≥14、.mjs文件路径正确、launch.json中"type": "node"且不加冲突参数,并用await import()或createrequire在cjs中加载esm模块。

VSCode点运行就报ERR_REQUIRE_ESM或Unexpected token 'export'
这不是代码写错了,而是VSCode默认用node script.js执行,把含import/export的文件当CommonJS解析。Node在解析阶段就拦截——require('./utils.mjs')直接炸,export default被当成非法token。
- 确认Node版本:
node -v必须≥14(推荐≥18),旧版本连.mjs都识别不了 - 别信“改后缀就行”:只把文件改成
.mjs但没配好VSCode启动方式,F5调试照样失败 - 别在
package.json里加"type": "module"然后继续用require()——所有.js文件立刻变ESM,旧调用全挂
让VSCode真正按ESM运行.mjs文件
VSCode的Code Runner插件或调试器不会自动识别.mjs,必须显式告诉它这是ES模块入口。
-
launch.json中确保"type": "node",不是pwa-node或chrome -
"program"字段必须指向真实存在的.mjs路径,比如"${workspaceFolder}/cli/main.mjs" - 删掉
launch.json里手动加的--loader或--input-type=module——VSCode会自己注入,加了反而冲突 - 如果断点变灰,八成是
type字段写错,或者工作目录不对(检查"cwd"是否指向项目根)
CommonJS主入口里想加载.mjs怎么办
require('./utils.mjs')永远不行,但Node提供了两个合法出口:异步的import()和同步的createRequire。
详细的 Three.js 3D 图形参考,涵盖场景设置、相机、几何体、材质、光照、动画、控制器、加载器、数学工具和调试。
- 能异步就用
const mod = await import('./utils.mjs');——这是标准方案,兼容性好,不破坏现有CJS结构 - 必须同步?比如CLI参数解析要在顶层执行:用
createRequire构造一个CJS加载器,但注意它仍不能加载.mjs,只能加载.cjs或未设type: module的.js - 第三方包升级成ESM(如
execa@8+)时,别硬require,查文档看它是否提供.cjs入口,或改用import()
混用.mjs和.js时最易踩的坑
后缀和package.json的type字段优先级不同,混用等于给自己埋雷。
-
.mjs优先级最高,Node无视package.json里的type,强制ESM;.js才看type字段 - 项目里既有
index.mjs又有config.js,后者若写了import但package.json没设type: module,立刻SyntaxError - 统一策略比混用安全:全用
.mjs就删掉type字段;想留.js就只靠package.json控制,别掺.mjs
真正麻烦的不是语法,是加载链路断裂——Node模块系统在解析阶段就做硬隔离,绕不开,只能分层适配。










