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

Expo项目中TypeORM迁移命令报Cannot use import outside a module错误

Expo + TypeORM + expo-sqlite 迁移命令报错排查与解决

项目配置信息

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标签模板搭建。

报错情况

  1. 执行以下命令时:
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执行,报错相同。

  1. 将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)

问题根源

  1. 环境不兼容:TypeORM CLI运行在Node.js环境,但expo-sqlite是Expo/React Native专属模块,Node环境无法加载它;同时Expo的TS配置和Node的模块解析逻辑存在冲突,导致CLI无法正确处理ES模块语法。
  2. 模块语法冲突:改成CommonJS的data-source.js后,项目中实体文件仍使用ES模块的export语法,加载时出现语法错误。

解决方法

方法一:在Expo应用启动时执行迁移

TypeORM CLI无法直接处理Expo环境的数据库,可将迁移逻辑放到应用启动流程中:

  1. 在应用入口文件(如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 (/* ... */);
}
  1. 生成迁移文件:临时打开data-source.ts中的synchronize: true,启动应用让TypeORM自动创建表结构,之后关闭synchronize,手动编写迁移文件或使用兼容的CLI配置生成(见方法二)。

方法二:创建Node兼容的CLI专用数据源

单独配置一个适配Node环境的数据源,用于生成和测试迁移:

  1. 安装Node版SQLite依赖:
npm install sqlite3 --save-dev
  1. 在项目根目录创建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;
  1. 修改tsconfig.json,确保支持ES模块解析:
{
  "compilerOptions": {
    // ... 原有配置
    "module": "ESNext",
    "moduleResolution": "NodeNext"
  }
}
  1. 在package.json中添加:
"type": "module"
  1. 使用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
  1. 迁移文件生成后,在Expo应用启动时执行迁移(同方法一的启动逻辑),确保应用数据库同步结构。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.13 17:18:13