使用ts-node运行TS脚本无法导入three.js的NURBSCurve模块
解决ts-node无法导入three.js examples中NURBSCurve的问题
问题核心在于three.js examples/jsm目录下的模块是纯ES模块(ESM),而你的项目当前配置为CommonJS模块系统,ts-node默认处理CommonJS时无法直接兼容ESM导入,而tsx对ESM的兼容性更好。以下是两种可行的解决配置方案:
方案一:切换项目为ES模块系统(推荐)
这种方式从根本上匹配three.js examples模块的格式,避免模块系统冲突:
- 修改tsconfig.json,调整模块相关配置并启用ts-node的ESM支持:
{ "compilerOptions": { "strict": true, "module": "ESNext", // 切换为ES模块 "moduleResolution": "bundler", // 适配ES模块的解析逻辑,也可使用node16/NodeNext "jsx": "preserve", "esModuleInterop": true, "sourceMap": true, "allowJs": true, "lib": ["ES6"], "rootDir": "src", "strictPropertyInitialization": false, "allowSyntheticDefaultImports": true }, "ts-node": { "esm": true // 告诉ts-node启用ESM模式 } }
- 修改package.json,声明项目为ES模块:
{ "type": "module" }
- 使用正确的ESM导入语法:
import { NURBSCurve } from 'three/examples/jsm/curves/NURBSCurve.js';
- 运行脚本:
npx ts-node src/pipeline.ts
(若配置未生效,可显式指定ESM模式:npx ts-node --esm src/pipeline.ts)
方案二:保持CommonJS,使用动态导入兼容
如果不想切换模块系统,可在CommonJS中使用动态import()来加载ESM模块:
// 异步函数中动态导入并使用NURBSCurve async function initCurve() { const { NURBSCurve } = await import('three/examples/jsm/curves/NURBSCurve.js'); const curve = new NURBSCurve(/* 你的参数 */); // 后续业务逻辑 } // 执行异步初始化 initCurve().catch(err => console.error('初始化曲线失败:', err));
补充说明
- VS Code能识别类型是因为
@types/three提供了完整的类型定义,但运行时的模块系统不兼容才导致报错。 - 你之前尝试的几种导入方式失败的原因:
- 直接从
three导入:NURBSCurve不在three核心模块的导出中 - 省略
.js后缀:Node.js的ESM解析要求必须带完整后缀,否则无法找到模块 - CommonJS静态导入ESM:Node.js禁止在CommonJS模块中同步导入ESM,因此报错
ERR_REQUIRE_ESM
- 直接从
内容的提问来源于stack exchange,提问作者Brian Barry
相关产品推荐
相关产品推荐

