TypeScript+Node+ESNext模块编排失败问题及解决方法
发布TypeScript模块的导出/导入两难问题与解决方案
更新:现已附上解决方案!
我想要发布一个TypeScript模块,但遇到了两难问题——要么无法导入所需模块,要么无法正确导出当前模块。
以下是我尝试过的几种配置的最小复现案例:
1. 测试用例(简单JavaScript文件)
import { fileType } from "@m87/hello"; console.log(fileType("../file1.jpg"));
2. 示例模块(位于hello目录下)
import { Mime } from 'mime' export const fileType = async (file: string): string => { const mime = new Mime(); return mime.getType(file) || ""; }
3. 配置选项及对应错误
配置一:package.json 设置type = module
package.json:
{ "name": "@m87/hello", "version": "1.0.0", "main": "dist/index.js", "types": "dist/index.d.ts", "type": "module", "scripts": { "build": "tsc" }, "dependencies": { "mime": "4.0.4" }, "devDependencies": { "@types/node": "^22.5.4", "typescript": "^5.6.2" } }
tsconfig.json(已移除默认注释):
{ "compilerOptions": { "target": "es2023", "module": "commonjs", "outDir": "./dist", "esModuleInterop": true, "forceConsistentCasingInFileNames": true, "strict": true, "skipLibCheck": true } }
该配置下代码可编译,但运行时报错:
import { fileType } from "@m87/hello"; ^^^^^^^^ SyntaxError: The requested module '@m87/hello' does not provide an export named 'fileType'
补充说明:测试文件的package.json中也设置了"type":"module",编译后的index.js输出如下:
"use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.fileType = void 0; const mime_1 = require("mime"); const fileType = async (file) => { const mime = new mime_1.Mime(); return mime.getType(file) || ""; }; exports.fileType = fileType;
我不清楚为何fileType会被定义两次,但最后一次定义看起来是正确的?
配置变体1:关闭"type":"module"
若在hello模块的package.json中关闭"type":"module",代码可编译,但运行时无法导入mime模块:
const mime_1 = require("mime"); ^ Error [ERR_REQUIRE_ESM]: require() of ES Module /code/hello/node_modules/mime/dist/src/index.js from /code/hello/dist/index.js not supported.
配置变体2:将tsconfig中的module设为ES6而非commonjs
此时编译失败,报错:
lib/index.ts:1:22 - error TS2792: Cannot find module 'mime'. Did you mean to set the 'moduleResolution' option to 'nodenext', or to add aliases to the 'paths' option? 1 import { Mime } from 'mime'
配置变体3:设置moduleResolution = nodenext
这同时需要在tsconfig中设置"module": "NodeNext"……
而这正是解决方案。
经过数小时的谷歌搜索、ChatGPT咨询和文档阅读……我终于找到了答案,希望能帮助到其他开发者。
内容的提问来源于stack exchange,提问作者Blunt Jackson
相关产品推荐
相关产品推荐

