如何通过Rollup从CommonJS模块导出命名成员?测试报错求助
解决ES模块导入时的命名导出未找到错误
问题场景
现有以下文件:
src/infrastructure/db.ts:
@injectable() export class Database { }
src/infrastructure/index.ts:
import config from 'config'; export * from "./db"
在src/webapi/routes/api.ts中通过命名导入引用该模块:
import { StudentRepository, TeacherRepository, LoggerImpl, DatabaseTypes, Database } from "infrastructure";
执行npm run ts_test时出现如下错误,而npm run start运行正常:
Exception during run: file:///usr/src/Node.JSRestAPI/src/webapi/routes/api.ts:13 import { StudentRepository, TeacherRepository, LoggerImpl, DatabaseTypes, Database } from "infrastructure"; ^^^^^^^^ SyntaxError: Named export 'Database' not found. The requested module 'infrastructure' is a CommonJS module, which may not support all module.exports as named exports. CommonJS modules can always be imported via the default export, for example using: import pkg from 'infrastructure'; const { StudentRepository, TeacherRepository, LoggerImpl, DatabaseTypes, Database } = pkg; at ModuleJob._instantiate (node:internal/modules/esm/module_job:171:21) at async ModuleJob.run (node:internal/modules/esm/module_job:254:5) at async ModuleLoader.import (node:internal/modules/esm/loader:475:24) at async formattedImport (/usr/src/Node.JSRestAPI/node_modules/mocha/lib/nodejs/esm-utils.js:9:14) at async Object.exports.requireOrImport (/usr/src/Node.JSRestAPI/node_modules/mocha/lib/nodejs/esm-utils.js:42:28) at async Object.exports.loadFilesAsync (/usr/src/Node.JSRestAPI/node_modules/mocha/lib/nodejs/esm-utils.js:100:20) at async singleRun (/usr/src/Node.JSRestAPI/node_modules/mocha/lib/cli/run-helpers.js:125:3) at async Object.exports.handler (/usr/src/Node.JSRestAPI/node_modules/mocha/lib/cli/run.js:370:5)
相关核心配置:
package.json关键部分
{ "type": "module", "scripts": { "start": "export NODE_ENV=development&& node --experimental-specifier-resolution=node build/src/webapi/server.js", "test": "export NODE_ENV=development&& ./node_modules/.bin/mocha -r ts-node/register tests/**/*.ts --timeout 10000 --recursive --check-leaks --exit", "ts_test": "export NODE_ENV=development && ./node_modules/.bin/nyc --timeout 10000 --recursive --check-leaks --reporter=lcov --reporter=text --reporter=text-summary --reporter=html ./node_modules/.bin/mocha -r ts-node/register tests/**/*.ts --reporter mocha-junit-reporter --reporter-options mochaFile=test_reports/mocha/test-results.xml --exit" }, "workspaces": [ "src/webapi.core", "src/infrastructure", "src/webapi" ] }
根目录tsconfig.json关键部分
{ "compilerOptions": { "module": "ES2022", "moduleResolution": "node", "paths": { "infrastructure/*": ["./src/infrastructure/*"] }, "esModuleInterop": true } }
问题原因
- 项目根目录
package.json设置了"type": "module",整体采用ES模块系统,但测试脚本使用的ts-node/register默认以CommonJS模式处理TypeScript文件,导致ES模块的命名导出被转换为CommonJS的module.exports,无法被ES模块的命名导入识别。 npm run start运行的是编译后的ES模块文件,且添加了--experimental-specifier-resolution=node参数,能正确解析ES模块导出,因此无错误。
解决方案
方案1:修改测试脚本,使用ES模块加载器
将test和ts_test脚本中的-r ts-node/register替换为ES模块加载器配置,同时添加Node.js实验性参数:
"test": "export NODE_ENV=development&& node --experimental-specifier-resolution=node --loader ts-node/esm ./node_modules/.bin/mocha tests/**/*.ts --timeout 10000 --recursive --check-leaks --exit", "ts_test": "export NODE_ENV=development && ./node_modules/.bin/nyc --timeout 10000 --recursive --check-leaks --reporter=lcov --reporter=text --reporter=text-summary --reporter=html node --experimental-specifier-resolution=node --loader ts-node/esm ./node_modules/.bin/mocha tests/**/*.ts --reporter mocha-junit-reporter --reporter-options mochaFile=test_reports/mocha/test-results.xml --exit",
方案2:临时调整导入方式
按照错误提示,改用默认导入后解构的方式引用模块:
import pkg from 'infrastructure'; const { StudentRepository, TeacherRepository, LoggerImpl, DatabaseTypes, Database } = pkg;
方案3:统一workspace的模块类型
检查src/infrastructure目录下的package.json(若存在),确保添加"type": "module",和根目录保持一致,避免模块系统冲突。
内容的提问来源于stack exchange,提问作者khteh
相关产品推荐
相关产品推荐

