使用Lerna构建TypeScript包时遇require()不支持ES模块错误求助
为何使用Lerna构建的TypeScript包引入ES模块Got时出现require()不支持错误?
项目结构
root -- packages // 存放独立包的文件夹 -- learn.json -- package.json -- tsconfig.json -- server.ts
根目录package.json依赖配置
"dependencies": { "@test1-plugins/got": "file:packages/test1", }
server.ts 导出逻辑
import test1 from './packages/test1/index' ... export default { test1, ..... }
main.ts 加载代码
import allPlugins from '../root/server.ts'; console.log('allPlugins',allPlugins);
报错信息
Error: require() of ES Module node_modules/_got@13.0.0@got/dist/source/index.js from root/packages/test1/index.ts not supported.
注:test1包基于TypeScript编写,且Got库为支持ES6的最新版本。
test1包详情
结构
packages └── test1 ├── index.ts ├── package.json └── tsconfig.json
index.ts 代码
import got, { Headers } from 'got'; export default class TestQueryService{ async run(apiKey){ const response = await got(`https://api.airtable.com/v0/xxxxx`, { method: 'get', headers: this.authHeader(apiKey), }); return response; } }
package.json 配置
{ "name": "@test-plugins/got", "version": "1.0.0", "main": "dist/index.js", "types": "dist/index.d.ts", "directories": { "lib": "lib", "test": "__tests__" }, "files": [ "lib" ], "scripts": { "test": "echo \"Error: run tests from root\" && exit 1", "build": "tsc -b", "clean": "rimraf ./dist && rimraf tsconfig.tsbuildinfo" }, "dependencies": { "got": "^13.0.0", "nock": "^13.3.0", "react": "^17.0.2", "rimraf": "^3.0.2" }, "type":"module" }
tsconfig.json 配置
{ "compilerOptions": { "baseUrl": ".", "declaration": true, "declarationMap": true, "sourceMap": true, "strict": false, "skipLibCheck": true, "outDir": "./dist", "esModuleInterop": true, "module": "commonjs", "moduleResolution": "node", "target": "es2015", "composite": true, "resolveJsonModule": true, "outDir": "dist", "rootDir": "lib" }, "exclude": [ "node_modules", "dist" ] }
已尝试的操作
- 将tsconfig中的
module和moduleResolution改为"module": "esnext", "moduleResolution": "node" - 尝试
"module": "Node16", "moduleResolution": "NodeNext" - 每次修改后删除旧node_modules并重新执行
npm i
以上操作均无效,仍出现相同错误。
问题分析与解决方案
核心问题
- 模块格式冲突:test1包
package.json设置了"type": "module"(声明为ES模块),但原TS编译配置module: commonjs会将TS编译为CommonJS格式文件,Node会因type: module把这些文件当作ES模块处理,导致加载逻辑混乱。即便修改了module配置,根目录未同步设置模块格式,也会引发混合加载问题。 - 源码引用错误:server.ts直接引用
./packages/test1/index(源码文件),而非test1包main字段指定的编译后文件dist/index.js,Node直接加载TS文件时,若根目录未配置正确的TS模块处理规则,会触发错误加载方式。 - Lerna链接缓存:使用
file:packages/test1链接本地包时,模块格式的修改可能未被Lerna同步,存在缓存问题。
分步解决
统一项目模块格式
- 根目录
package.json添加"type": "module",保持全局模块格式一致。 - 修正test1的tsconfig.json,确保编译输出ES模块:
{ "compilerOptions": { "module": "ESNext", "moduleResolution": "NodeNext", "target": "ES2020", "outDir": "./dist", "rootDir": "./", // 原配置rootDir为lib,但index.ts在包根目录,需修正 "esModuleInterop": true, "skipLibCheck": true, "declaration": true, "declarationMap": true, "sourceMap": true, "composite": true, "resolveJsonModule": true }, "exclude": ["node_modules", "dist"] }
- 根目录
修正文件引用路径
推荐直接引用包名(已在根目录依赖声明),或指向编译后文件:// 方式1(推荐) import test1 from '@test-plugins/got'; // 方式2 import test1 from './packages/test1/dist/index.js';清理并重新构建
- 在test1包目录执行:
npm run clean npm run build - 在根目录执行:
rm -rf node_modules npm install npx lerna clean -y npx lerna bootstrap
- 在test1包目录执行:
跳过类型检查冲突
根目录tsconfig.json添加"skipLibCheck": true,避免Got的ES模块类型与项目配置冲突。
内容的提问来源于stack exchange,提问作者user824624
相关产品推荐
相关产品推荐

