如何在NestJS的CommonJS构建中动态导入@octokit/rest?
在CommonJS模式的NestJS项目中兼容使用ES模块@octokit/rest的解决方案
核心问题原因
你遇到的ERR_REQUIRE_ESM错误,本质是TypeScript默认会把代码中的动态import()编译成CommonJS的require()调用,但@octokit/rest是纯ES模块,不支持被require()导入。要解决这个问题,关键是让动态import()保留原生形式,由Node.js在运行时处理ES模块加载。
方法一:调整TypeScript配置,阻止动态import被编译
修改项目根目录的tsconfig.json,确保以下配置项正确设置:
{ "compilerOptions": { "module": "CommonJS", // 保持项目原有CommonJS构建模式 "moduleResolution": "NodeNext", // 启用Node.js原生模块解析逻辑,支持混合模块场景 "target": "ES2020", // 动态import是ES2020特性,需指定对应或更高版本 "esModuleInterop": true, // 优化ES模块与CommonJS的互操作性 "allowSyntheticDefaultImports": true, "skipLibCheck": true // 跳过第三方库类型检查,避免ES模块类型冲突报错 // 保留你原有配置中的其他项 } }
配置修改后,TypeScript会保留代码中的动态import()语法,不会转译为require(),Node.js运行时会自动处理ES模块的加载逻辑。
方法二:确保NestJS构建工具不篡改动态import
如果使用Nest CLI构建,默认的webpack配置可能会对模块导入做额外处理,需确保webpack保留原生动态import:
- 在项目根目录创建
webpack.config.js文件 - 添加以下配置:
module.exports = function (options) { return { ...options, target: 'node', experiments: { topLevelAwait: true // 若代码中用到顶层await,需开启此项 }, module: { ...options.module, rules: [ ...options.module.rules, { test: /\.ts$/, loader: 'ts-loader', options: { compilerOptions: { module: 'ESNext' // 让ts-loader保留ES模块语法,由webpack后续处理 } } } ] } }; };
然后在nest-cli.json中指定使用这个webpack配置:
{ "compilerOptions": { "webpackConfig": "webpack.config.js" } }
方法三:临时应急方案(不推荐)
如果你不想调整项目配置,可以尝试使用octokit的旧版本(v18及之前),这些版本同时提供CommonJS和ES模块分发。但此方法会错过新版本的功能更新与安全修复,仅作为临时应急选项。
验证修改效果
调整配置后,重新构建并运行项目,你的原有代码即可正常工作:
async createRepository(accessToken: string, repositoryName: string) { const { Octokit } = await import('@octokit/rest'); const octokit = new Octokit({ auth: accessToken, }); const response = await octokit.repos.createForAuthenticatedUser({ name: repositoryName, }); return response.data; }
内容的提问来源于stack exchange,提问作者Misha Nesteruk
相关产品推荐
相关产品推荐

