NestJS+TypeScript+TypeORM迁移报错:无法在模块外使用import语句
TypeORM迁移执行失败问题解决
报错信息
执行迁移时出现如下错误,仅能创建迁移,无法生成或运行:
> @punch-list-api/source@0.0.0 migration:run > npm run typeorm migration:run > @punch-list-api/source@0.0.0 typeorm > typeorm-ts-node-commonjs -d ./ormconfig.ts migration:run Error during migration run: Error: Unable to open file: "path of the ormconfig". Cannot use import statement outside a module at Function.loadDataSource (/home/snuc/Documents/IOET_TT_Projects/punch-list-api/node_modules/src/commands/CommandUtils.ts:22:19) at async Object.handler (/home/snuc/Documents/IOET_TT_Projects/punch-list-api/node_modules/src/commands/MigrationRunCommand.ts:42:26)
当前配置文件
ormconfig.ts
import { DataSource } from 'typeorm'; const connectionSource = new DataSource({ type: 'postgres', host: process.env.RDS_HOSTNAME, port: parseInt(process.env.RDS_PORT || '5432'), username: process.env.RDS_USERNAME, password: process.env.RDS_PASSWORD, database: process.env.RDS_DB_NAME, entities: [__dirname + '/dist/**/*.entity.js'], migrations: [__dirname + '/dist/database/migrations/*.js'], }); export default connectionSource;
package.json 脚本
"typeorm": "typeorm-ts-node-commonjs -d ./ormconfig.ts", "migration:create": "typeorm-ts-node-commonjs migration:create", "migration:generate": "npm run typeorm migration:generate", "migration:run": "npm run typeorm migration:run"
tsconfig.json
{ "compilerOptions": { "rootDir": ".", "sourceMap": true, "declaration": false, "moduleResolution": "node", "emitDecoratorMetadata": true, "experimentalDecorators": true, "importHelpers": true, "target": "es2015", "module": "esnext", "lib": [ "es2020", "dom" ], "skipLibCheck": true, "skipDefaultLibCheck": true, "baseUrl": ".", "paths": {}, "esModuleInterop": true, "resolveJsonModule": true }, "files": [], "include": [], "references": [ { "path": "./tsconfig.app.json" }, { "path": "./tsconfig.spec.json" } ], "exclude": [ "node_modules", "tmp" ] }
问题原因
核心错误Cannot use import statement outside a module是因为:
- 使用的
typeorm-ts-node-commonjs命令强制以CommonJS模块模式加载代码 - 但
ormconfig.ts使用了ES模块的import/export语法,同时主tsconfig.json的module设置为esnext,导致模块加载机制冲突
解决方案
方案一:修改ormconfig.ts为CommonJS导出
将ormconfig.ts的导出方式替换为CommonJS格式,ts-node会自动编译ES模块语法为CommonJS:
import { DataSource } from 'typeorm'; const connectionSource = new DataSource({ type: 'postgres', host: process.env.RDS_HOSTNAME, port: parseInt(process.env.RDS_PORT || '5432'), username: process.env.RDS_USERNAME, password: process.env.RDS_PASSWORD, database: process.env.RDS_DB_NAME, entities: [__dirname + '/dist/**/*.entity.js'], migrations: [__dirname + '/dist/database/migrations/*.js'], }); // 替换export default为module.exports module.exports = connectionSource;
方案二:切换为ES模块模式运行TypeORM
如果希望保留ES模块语法,按以下步骤调整:
- 在
package.json中添加"type": "module"声明 - 修改
ormconfig.ts,手动获取__dirname(ES模块中默认不提供):
import { DataSource } from 'typeorm'; import { fileURLToPath } from 'url'; import { dirname } from 'path'; const __filename = fileURLToPath(import.meta.url); const __dirname = dirname(__filename); const connectionSource = new DataSource({ type: 'postgres', host: process.env.RDS_HOSTNAME, port: parseInt(process.env.RDS_PORT || '5432'), username: process.env.RDS_USERNAME, password: process.env.RDS_PASSWORD, database: process.env.RDS_DB_NAME, entities: [__dirname + '/dist/**/*.entity.js'], migrations: [__dirname + '/dist/database/migrations/*.js'], }); export default connectionSource;
- 更新
package.json中的脚本,使用ES模块版本的命令:
"typeorm": "typeorm-ts-node-esm -d ./ormconfig.ts", "migration:create": "typeorm-ts-node-esm migration:create", "migration:generate": "npm run typeorm migration:generate", "migration:run": "npm run typeorm migration:run"
方案三:为TypeORM命令单独配置tsconfig
创建tsconfig-cli.json文件,继承主配置并指定CommonJS模块:
{ "extends": "./tsconfig.json", "compilerOptions": { "module": "commonjs", "target": "es2017" }, "include": ["ormconfig.ts"] }
然后更新package.json中的TypeORM脚本,指定使用该配置文件:
"typeorm": "typeorm-ts-node-commonjs -d ./ormconfig.ts --tsconfig ./tsconfig-cli.json",
内容的提问来源于stack exchange,提问作者Freddy Valverde Gallardo
相关产品推荐
相关产品推荐

