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

TypeScript库兼容ESM与CommonJS:如何实现通用的__dirname?

兼容CommonJS和ESM的TypeScript脚本路径获取方案

我维护一个用TypeScript编写的库,希望同时支持CommonJS和ESM格式,因此会执行两次构建,这要求编写的TypeScript代码需兼容两种模块规范。其中一个问题是:CommonJS中存在__dirname变量,我用它来相对加载文件,但ESM中没有该变量。于是我尝试编写如下代码:

const _mydirname = typeof __dirname !== 'undefined'
  ? __dirname
  : path.dirname(url.fileURLToPath(import.meta.url));

// Example usage
const file =  fs.readFileSync(path.join(_mydirname, '../README.md'), 'utf-8')

不幸的是,用TypeScript构建时出现如下错误:

Error: src/application.ts(22,36): error TS1343: The 'import.meta' meta-property is only allowed when the '--module' option is 'es2020', 'es2022', 'esnext', 'system', 'node16', or 'nodenext'.

以下是几种可行的解决方案:

方案一:TypeScript条件编译区分环境

利用TypeScript的条件编译指令,根据不同的模块配置生成对应代码,避免语法检查冲突:

import * as path from 'path';
import * as url from 'url';

let _mydirname: string;

// CommonJS环境分支
#if module === "CommonJS"
_mydirname = __dirname;
#else
// ESM环境分支
_mydirname = path.dirname(url.fileURLToPath(import.meta.url));
#endif

// 示例用法
const file = fs.readFileSync(path.join(_mydirname, '../README.md'), 'utf-8');

需要在tsconfig.json中启用条件编译支持:

{
  "compilerOptions": {
    "allowConditionalCompilation": true
  }
}

方案二:动态导入+全局变量判断

通过动态导入url模块,规避CommonJS环境下对import.meta的语法检查:

import * as path from 'path';

let _mydirname: string;

if (typeof __dirname !== 'undefined') {
  _mydirname = __dirname;
} else {
  // 动态导入url模块,仅在ESM环境执行
  const { fileURLToPath } = await import('url');
  _mydirname = path.dirname(fileURLToPath(import.meta.url));
}

// 示例用法
const file = fs.readFileSync(path.join(_mydirname, '../README.md'), 'utf-8');

方案三:拆分模块分别实现

针对两种模块规范单独编写路径工具文件,通过构建流程切换导入:

  1. path-utils.cjs(CommonJS版本)
const path = require('path');
module.exports = { getDirname: () => __dirname };
  1. path-utils.mjs(ESM版本)
import path from 'path';
import { fileURLToPath } from 'url';
export const getDirname = () => path.dirname(fileURLToPath(import.meta.url));

在主代码中根据构建目标导入对应模块,或通过构建工具(如Rollup、Webpack)在不同构建流程中替换文件。

内容的提问来源于stack exchange,提问作者Evert

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.01 16:41:02