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

Expo+Drizzle ORM/Convex报错:Cannot use import statement outside a module

Expo + Drizzle ORM/Convex DB: "Cannot use import statement outside a module" 错误解决

问题背景

在Expo项目中搭配Expo SQLite使用Drizzle ORM时,执行npx drizzle-kit generate出现报错,提示react-native模块中的import语句无法在CommonJS环境中运行。后续使用Convex DB执行npx convex dev时也出现完全相同的错误,且Convex命令最初可正常运行,后续突发问题。

Drizzle配置文件drizzle.config.ts内容:

import  { Config } from "drizzle-kit"

export default {
  schema: "./lib/db/schema",
  out: "./lib/db/migrations",
  dialect: "sqlite",
  driver: "expo",
} satisfies Config

报错日志:

No config path provided, using default 'drizzle.config.ts'
Reading config file '/Users/jay/Documents/personal/Code/Expo/pretty-budgeter/drizzle.config.ts'
/Users/jay/Documents/personal/Code/Expo/pretty-budgeter/node_modules/react-native/index.js:14
import typeof ActionSheetIOS from './Libraries/ActionSheetIOS/ActionSheetIOS';
^^^^^^

SyntaxError: Cannot use import statement outside a module
    at wrapSafe (node:internal/modules/cjs/loader:1281:20)
    at Module._compile (node:internal/modules/cjs/loader:1321:27)
    at Module._extensions..js (node:internal/modules/cjs/loader:1416:10)
    at newLoader (/Users/jay/Documents/personal/Code/Expo/pretty-budgeter/node_modules/drizzle-kit/bin.cjs:14724:13)
    at Object.newLoader (/Users/jay/Documents/personal/Code/Expo/pretty-budgeter/node_modules/drizzle-kit/bin.cjs:14724:13)
    at extensions..js (/Users/jay/Documents/personal/Code/Expo/pretty-budgeter/node_modules/drizzle-kit/bin.cjs:17252:28)
    at Module.load (node:internal/modules/cjs/loader:1208:32)
    at Module._load (node:internal/modules/cjs/loader:1024:12)
    at Module.require (node:internal/modules/cjs/loader:1233:19)
    at require (node:internal/modules/helpers:179:18

已知信息:配置符合Drizzle官方文档要求,在项目外生成迁移文件再导入可正常使用。

错误原因

核心问题是CLI工具(Drizzle Kit/Convex)以CommonJS模式运行,但加载到了项目中的ES模块代码。当CLI解析你的schema文件时,间接引入了react-native模块,而react-native使用ES模块的import语法,CommonJS加载器无法识别,因此触发语法错误。

解决办法

1. 彻底隔离schema与Expo依赖

这是最稳妥的方案:将数据库schema做成纯结构定义文件,完全不引入任何Expo/React Native相关代码。需要使用Expo SQLite的逻辑,单独拆分到运行时文件中。

示例:

  • lib/db/schema.ts(纯数据库结构,无Expo依赖):
import { sqliteTable, text, integer } from "drizzle-orm/sqlite-core";

export const expenses = sqliteTable("expenses", {
  id: integer("id").primaryKey({ autoIncrement: true }),
  amount: integer("amount").notNull(),
  description: text("description"),
  createdAt: text("created_at").default("CURRENT_TIMESTAMP"),
});
  • lib/db/db.ts(Expo运行时专用,负责连接数据库):
import { drizzle } from "drizzle-orm/expo-sqlite";
import { openDatabaseSync } from "expo-sqlite";
import * as schema from "./schema";

const dbInstance = openDatabaseSync("budget.db");
export const db = drizzle(dbInstance, { schema });

这样Drizzle Kit生成迁移时只会加载纯schema文件,不会触发react-native的模块加载逻辑。

2. 调整项目的模块类型

将项目切换为ES模块模式,让Node.js使用ES模块加载器处理所有文件:

  1. 在项目根目录的package.json中添加"type": "module":
{
  "name": "pretty-budgeter",
  "type": "module",
  // 其他项目配置...
}
  1. 将drizzle.config.ts重命名为drizzle.config.mjs,确保语法符合ES模块规范:
import { Config } from "drizzle-kit";

export default {
  schema: "./lib/db/schema",
  out: "./lib/db/migrations",
  dialect: "sqlite",
  driver: "expo",
} satisfies Config;

3. 用环境变量强制CLI启用ES模块

执行CLI命令时,通过NODE_OPTIONS参数指定启用ES模块支持:

# Drizzle生成迁移命令
NODE_OPTIONS="--experimental-modules --es-module-specifier-resolution=node" npx drizzle-kit generate

# Convex启动开发服务命令
NODE_OPTIONS="--experimental-modules --es-module-specifier-resolution=node" npx convex dev

4. 清理依赖缓存(针对Convex突发错误)

如果Convex之前可正常运行,突然报错,大概率是依赖缓存异常导致:

# 删除node_modules和包管理器锁文件
rm -rf node_modules
rm package-lock.json # 使用yarn则删除yarn.lock,pnpm则删除pnpm-lock.yaml

# 重新安装依赖
npm install # 或 yarn install / pnpm install

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.17 15:00:07