You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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编译两种格式的产物:

  1. 创建两个TS配置文件:
    • tsconfig.cjs.json(输出CommonJS)
    • tsconfig.esm.json(输出ES模块)
  2. 修改package.json的scripts和exports字段,分别指定两种格式的入口。

内容的提问来源于stack exchange,提问作者Jimmy Breck-McKye

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.22 08:23:25