Expo项目中TypeORM迁移命令报Cannot use import outside a module错误
项目配置信息
package.json
{ "name": "testproject", "main": "expo-router/entry", //... "dependencies": { //... "expo-sqlite": "~11.3.2", //... "reflect-metadata": "^0.1.13", "typeorm": "^0.3.17" }, "devDependencies": { //... "babel-plugin-transform-typescript-metadata": "^0.3.2", "ts-node": "^10.9.1", //... }, //... }
tsconfig.json
{ "extends": "expo/tsconfig.base", "compilerOptions": { "strict": true, "paths": { "@/*": [ "./*" ] }, "emitDecoratorMetadata": true, "experimentalDecorators": true, "strictPropertyInitialization": false }, "include": [ "**/*.ts", "**/*.tsx", ".expo/types/**/*.ts", "expo-env.d.ts" ], }
babel.config.js
module.exports = function (api) { api.cache(true); return { presets: ['babel-preset-expo'], plugins: [ // Required for expo-router 'expo-router/babel', '@babel/transform-react-jsx-source', 'babel-plugin-transform-typescript-metadata' ], }; };
data-source.ts
import { DataSource, DataSourceOptions } from "typeorm"; export const options: DataSourceOptions = { type: "expo", database: 'TestProject', driver: require('expo-sqlite'), entities: [ 'entities/*.ts' ], //synchronize: true migrations: ['data/migrations/*.ts'], migrationsTableName: 'migrations' }; const dataSource = new DataSource(options) export default dataSource;
实体文件存于/entities目录,迁移文件存于/data/migrations目录,基于Expo标签模板搭建。
报错情况
- 执行以下命令时:
npx typeorm migration:run -d ./data-source.ts # 或 npx typeorm migration:generate CreateTables -d ./data-source.ts
出现错误:
Error during migration run:
Error: Unable to open file: "D:\Programming\TestProject\data-source.ts". Cannot use import statement outside a module
at CommandUtils.loadDataSource (D:\Programming\TestProject\node_modules\typeorm\commands\CommandUtils.js:22:19)
at async Object.handler (D:\Programming\TestProject\node_modules\typeorm\commands\MigrationRunCommand.js:41:26)
尝试使用npx typeorm-ts-node-esm执行,报错相同。
- 将
data-source.ts改为data-source.js并改用CommonJS语法后:
const { DataSource } = require("typeorm"); const options = { type: "expo", database: 'TestProject', driver: require('expo-sqlite'), entities: [ 'entities/*.ts' ], //synchronize: true migrations: ['data/migrations/*.ts'], migrationsTableName: 'migrations' }; const dataSource = new DataSource(options); module.exports = dataSource;
执行命令出现新错误:
Error during migration run: Error: Unable to open file:
"D:\Programming\TestProject\data-source.js". Unexpected token 'export'
at CommandUtils.loadDataSource (D:\Programming\TestProject\node_modules\typeorm\commands\CommandUtils.js:22:19)
at async Object.handler (D:\Programming\TestProject\node_modules\typeorm\commands\MigrationRunCommand.js:41:26)
问题根源
- 环境不兼容:TypeORM CLI运行在Node.js环境,但
expo-sqlite是Expo/React Native专属模块,Node环境无法加载它;同时Expo的TS配置和Node的模块解析逻辑存在冲突,导致CLI无法正确处理ES模块语法。 - 模块语法冲突:改成CommonJS的data-source.js后,项目中实体文件仍使用ES模块的
export语法,加载时出现语法错误。
解决方法
方法一:在Expo应用启动时执行迁移
TypeORM CLI无法直接处理Expo环境的数据库,可将迁移逻辑放到应用启动流程中:
- 在应用入口文件(如
App.tsx)中添加数据库初始化和迁移执行代码:
import dataSource from './data-source'; import 'reflect-metadata'; import { useEffect } from 'react'; export default function App() { useEffect(() => { const initDatabase = async () => { await dataSource.initialize(); await dataSource.runMigrations(); }; initDatabase(); }, []); // 其余应用代码 return (/* ... */); }
- 生成迁移文件:临时打开
data-source.ts中的synchronize: true,启动应用让TypeORM自动创建表结构,之后关闭synchronize,手动编写迁移文件或使用兼容的CLI配置生成(见方法二)。
方法二:创建Node兼容的CLI专用数据源
单独配置一个适配Node环境的数据源,用于生成和测试迁移:
- 安装Node版SQLite依赖:
npm install sqlite3 --save-dev
- 在项目根目录创建
data-source-cli.ts:
import { DataSource, DataSourceOptions } from "typeorm"; import * as sqlite3 from 'sqlite3'; export const options: DataSourceOptions = { type: "sqlite", database: 'TestProject-cli.db', // 使用单独的测试数据库,避免影响Expo应用的数据库 driver: sqlite3, entities: ['entities/*.ts'], migrations: ['data/migrations/*.ts'], migrationsTableName: 'migrations' }; const dataSource = new DataSource(options); export default dataSource;
- 修改
tsconfig.json,确保支持ES模块解析:
{ "compilerOptions": { // ... 原有配置 "module": "ESNext", "moduleResolution": "NodeNext" } }
- 在
package.json中添加:
"type": "module"
- 使用CLI命令时指定这个专用配置文件:
# 生成迁移 npx typeorm-ts-node-esm migration:generate data/migrations/CreateTables -d ./data-source-cli.ts # 执行迁移(Node环境测试用) npx typeorm-ts-node-esm migration:run -d ./data-source-cli.ts
- 迁移文件生成后,在Expo应用启动时执行迁移(同方法一的启动逻辑),确保应用数据库同步结构。
内容的提问来源于stack exchange,提问作者MrPlow

