TypeScript编写的Express中间件兼容TS/JS Node项目配置问题
我之前在开发跨兼容的TS/JS Node.js模块时踩过不少坑,给你一套经过验证的配置方案,保证你的Express中间件能完美支持两种调用方式:
核心思路
要同时支持require()(JS项目)和import(TS项目)且都直接拿到函数类型,关键是让TypeScript编译后的CommonJS模块能被两种模块系统正确识别,同时生成完整的类型声明文件。
1. 编写TS中间件代码
确保你的中间件通过默认导出暴露,示例代码如下:
// src/index.ts import { Request, Response, NextFunction } from 'express'; // 你的Express中间件逻辑 const myGreatFunction = (req: Request, res: Response, next: NextFunction) => { console.log('执行自定义中间件'); // 这里添加你的业务逻辑 next(); }; // 关键:使用默认导出 export default myGreatFunction;
2. 配置tsconfig.json
这是兼容的核心配置,重点关注esModuleInterop和declaration选项:
{ "compilerOptions": { "target": "ES2020", // 兼容Node.js 14+版本,可按需调整 "module": "CommonJS", // 输出CommonJS格式,适配Node.js默认模块系统 "declaration": true, // 生成.d.ts类型声明文件,供TS项目识别类型 "outDir": "./dist", // 编译产物输出目录 "strict": true, "esModuleInterop": true, // 关键!让TS默认导出能被CommonJS的require直接识别 "skipLibCheck": true, "forceConsistentCasingInFileNames": true }, "include": ["src/**/*"], "exclude": ["node_modules", "dist"] }
解释
esModuleInterop: true:这个选项会让TS在编译时,把默认导出同时挂载到module.exports和module.exports.default,这样JS项目用require()时不用额外加.default就能拿到函数。
3. 配置package.json
让包管理器和TS编译器能正确找到入口文件:
{ "name": "myGreatFunction", "version": "1.0.0", "main": "./dist/index.js", // JS项目require()的入口 "types": "./dist/index.d.ts", // TS项目的类型声明入口 "exports": { ".": { "require": "./dist/index.js", "import": "./dist/index.js" // 若需支持ES模块import,可后续扩展多格式输出 } }, "scripts": { "build": "tsc" // 执行编译命令 }, "dependencies": { "express": "^4.18.2" }, "devDependencies": { "@types/express": "^4.17.17", "typescript": "^5.2.2" } }
4. 验证效果
执行npm run build编译后,就能在其他项目中测试:
JS项目调用
const express = require('express'); const myGreatFunction = require('myGreatFunction'); const app = express(); app.use(myGreatFunction); // 直接作为中间件使用,typeof myGreatFunction === 'function'
TS项目调用
import express from 'express'; import myGreatFunction from 'myGreatFunction'; const app = express(); app.use(myGreatFunction); // 类型自动识别,typeof myGreatFunction符合Express中间件类型
进阶:同时支持CommonJS和ES模块
如果需要适配更多场景(比如TS项目使用ES模块),可以配置TS编译两种格式的产物:
- 创建两个TS配置文件:
tsconfig.cjs.json(输出CommonJS)tsconfig.esm.json(输出ES模块)
- 修改
package.json的scripts和exports字段,分别指定两种格式的入口。
内容的提问来源于stack exchange,提问作者Jimmy Breck-McKye
相关产品推荐
相关产品推荐

