ARTICLE DETAIL

建站实战干货

来自一线的建站与推广经验沉淀,每一条都经过真实交付验证。

MikroORM 使用指南:基于 sql.js 的纯内存 WebAssembly SQLite 驱动(@mikro-orm/sql-js)

2026/9/29 6:19:10 拓冰建站 浏览量
MikroORM 使用指南:基于 sql.js 的纯内存 WebAssembly SQLite 驱动(@mikro-orm/sql-js) 后端【免费下载链接】mikro-ormTypeScript ORM for Node.js based on Data Mapper, Unit of Work and Identity Map patterns. Supports MongoDB, MySQL, MariaDB, MS SQL Server, PostgreSQL and SQLite/libSQL databases.项目地址https://gitcode.com/gh_mirrors/mi/mikro-orm点击查看免费下载本篇指南围绕 MikroORM 7.2 的mikro-orm/sql-js驱动展开它把 SQLite 编译为 WebAssembly 后运行在内存中既可在浏览器也可在 Node.js 中使用且无需任何原生绑定。读完本文你将掌握该驱动的安装、配置、WASM 定位、数据库镜像导出与恢复、原生客户端访问以及它的四项关键限制与对应的规避方案并能用源码与测试证据印证每一项行为。概览sql.js 是什么为什么值得关注sql.js 是 SQLite 的 WebAssembly 移植版数据库完全驻留在内存中因此浏览器端可用不依赖服务器数据可持久化到localStorage、IndexedDB 等客户端存储Node.js 可用不需要better-sqlite3、node-sqlite3这类需要编译原生模块的依赖安装与部署更省心特性与mikro-orm/sqlite对齐mikro-orm/sql-js驱动复用了与mikro-orm/sqlite相同的 SQLite 平台实现功能支持面与常规 SQLite 驱动一致。从源码看这一对齐是结构性的SqlJsDriver 直接继承自AbstractSqlDriver并传入SqlitePlatform意味着 Schema Generator、QueryBuilder、Migrations、Kysely、流式查询等 SQL 平台能力天然可用而不是 sql.js 专属的阉割实现。安装npm install mikro-orm/core mikro-orm/sql-jsmikro-orm/sql-js包本身会带出sql.js及其 WASM 二进制作为依赖package.json 的exports字段中声明了sql.js/dist/sql-wasm.wasm的导出路径这是打包器解析 WASM 资源的依据。配置无需指定 dbName数据库永远活在内存中因此dbName默认就是:memory:你完全不需要传它。使用defineConfig即可import { defineConfig } from mikro-orm/sql-js; export default defineConfig({ entities: [./dist/entities], entitiesTs: [./src/entities], });这个默认值并不是硬编码在文档里的说法而是有源码支撑的在 defineSqlJsConfig 中驱动会主动defineConfig({ driver: SqlJsDriver, dbName: :memory:, ...options })既满足了 MikroORM 对dbName的校验又免去每个用户手动书写。测试 sql-js.test.ts 也验证了defineConfig({}).dbName与orm.config.get(dbName)均为:memory:。生命周期连接关闭即数据清零内存数据库的生命周期与连接绑定orm.close()会释放 WASM 数据库再次orm.connect()会从空数据库或driverOptions.data传入的镜像重新开始因此每次重建连接后连 schema 都需要重新创建。测试 reconnecting after close creates a fresh empty database 完整复现了这一流程写入一条数据 →close()→connect()→ 重新orm.schema.create()→ 数据计数为 0。如果需要跨会话保留数据请使用下文driverOptions.datadb.export()自行持久化与恢复。Driver options控制 WASM 的加载方式driverOptions中除sqlJs与data两个保留键之外其余一切配置都会被转发给initSqlJs()——这正是 sql.js 定位 WASM 二进制的方式。源码中的类型定义对此有明确注释SqlJsDriverOptions 把driverOptions定义为SqlJsConfig { sqlJs?, data? }而 SqlJsConfig 是一个开放 bag[key: string]: unknown专门用来透传 emscripten 模块的各类参数。locateFile让打包器找到 WASM在 Node.js 中sql.js的 WASM 文件会被自动发现无需配置。但在浏览器打包场景webpack/rspack/vite 等中你需要用locateFile指向打包器实际产出的sql.js/dist/sql-wasm.wasm资源 URLimport { defineConfig } from mikro-orm/sql-js; // webpack/rspack: emits the wasm as an asset and resolves its URL const wasmUrl new URL(sql.js/dist/sql-wasm.wasm, import.meta.url); // vite: import wasmUrl from sql.js/dist/sql-wasm.wasm?url; export default defineConfig({ entities: [...], driverOptions: { locateFile: () wasmUrl.href, }, });另一种方式是直接把编译好的二进制传进来wasmBinary类型为ArrayBuffer | Uint8Array。测试 driverOptions are forwarded to initSqlJs 通过 spy 验证了locateFile与wasmBinary都会被原样转交给initSqlJs()。一个进程内只初始化一次 WASM需要注意sql.js 每个进程只初始化其 WASM 模块一次之后任何initSqlJs()调用传入的配置都会被忽略。因此这些选项只对进程内创建的第一个 ORM 实例生效。如果你需要精确控制模块的初始化时机应当自行初始化后通过driverOptions.sqlJs传入见下一节。sqlJs复用预初始化的 sql.js 模块当你的应用已经初始化过 sql.js例如要与非 ORM 代码共享 WASM 模块或要自行控制加载时机时把解析好的SqlJsStatic或一个返回它的工厂函数放进driverOptions.sqlJsimport initSqlJs from sql.js; import { MikroORM } from mikro-orm/sql-js; const SQL await initSqlJs({ locateFile: file /${file} }); const orm await MikroORM.init({ entities: [...], driverOptions: { sqlJs: SQL }, });在 createKyselyDialect 中可以看到sqlJs既可以是静态对象也可以是函数typeof sqlJs function ? await sqlJs() : sqlJs然后以new SQL.Database(data)构造数据库实例。测试 driverOptions.sqlJs is used instead of initializing sql.js again 验证了工厂只会被调用一次且返回的原生数据库确实属于传入的SQL.Database。data打开一份已有的数据库镜像driverOptions.data接受一份现成的 SQLite 文件镜像Uint8Array、Buffer或任意ArrayLikenumber并以此打开数据库而不是新建空库。它与db.export()配合就是跨会话持久化数据的完整闭环——可以存到localStorage、IndexedDB、文件或服务器const orm await MikroORM.init({ entities: [...], driverOptions: { data: await loadSavedDatabase() }, });测试 the database image can be exported and reopened via driverOptions.data 演示了完整流程写入Jon Snow→getNativeClient().export()导出 →close()→ 用data重新初始化 → 数据完好可查。访问 sql.js 原生数据库getNativeClient()对应文档 Accessing the Native Client返回 sql.js 的Database实例导出当前状态就靠它const db await orm.em.getConnection().getNativeClient(); const data db.export(); // Uint8Array, the SQLite file image它的生命周期归属 ORM——请让orm.close()来关闭它而不是直接调用close()。源码中 getNativeClient 会先ensureConnection()再返回内部持有的#database而 close 在 kysely 关闭底层数据库后会主动把#database置空确保重连时重建一个全新实例。Schema、迁移与查询与 SQLite 驱动完全同构sql.js 是标准的 SQLite 构建因此以下能力与mikro-orm/sqlite完全一致Schema Generatororm.schema.create()直接建表Migrations测试 migrations work against the in-memory database 验证了migrator.create()与migrator.up()在内存库上正常工作QueryBuilderKysely 集成测试 kysely queries run through the sql.js connection 证明orm.em.getKysely()的插入与查询都走 sql.js 连接流式查询。值得一提的底层适配SqlJsDatabase 把 sql.js 的原生 API 包装成 kysely 期望的SqliteStatement/SqliteDatabase形状其中coerceParams专门处理了两类 sql.js 无法原生绑定的值——bigint安全整数范围内转number超出范围转字符串由 INTEGER 列亲和性还原精度与undefined归一为null。测试 bigints beyond the safe integer range keep their precision 验证了9007199254740993n这类超出安全整数范围的值在往返后精度不丢。存储例程Stored routines存储例程 同样受支持带bodyJs兜底的函数会通过 sql.js 的create_function()注册为用户自定义函数UDF。源码 callRoutine 展示了细节type: procedure直接抛错SQLite 没有存储过程概念函数缺少bodyJs兜底时抛错注册时会把位置参数按routine.params顺序映射为具名参数对象传给 JS 实现并通过Object.defineProperty(udf, length, ...)修正函数声明长度让 sql.js 推导出正确的 SQL 元数用#registeredRoutines做引用比对HMR 或闭包重绑导致引用变化时会自动重新注册。测试 stored-routines/sql-js.test.ts 验证了 UDF 分派、引用切换后的重注册、procedure 抛错与无bodyJs抛错四类行为。四项限制与规避方案1. 仅内存无文件系统没有磁盘因此dbName不产生任何效果连接一关数据即失。规避方式就是db.export()driverOptions.data自行持久化见上文。2. 不支持附加数据库ATTACHattachDatabases选项会直接抛错——没有数据库文件可供附加。源码 validateAttachSupport 在connect()阶段就会拦截并抛出明确错误测试 attachDatabases is rejected 验证了orm.connect()会以ATTACH DATABASE is not supported by the sql.js driver拒绝。错误信息同时给出建议把附加数据直接加载进这块单一的内存库。3. 每条查询只允许一条语句sql.js 只会 prepare 字符串中的第一条语句并静默丢弃其余部分因此驱动像 better-sqlite3 一样主动拒绝多语句 SQL。这个检查在 SqlJsStatementAdapter 中实现取stmt.getSQL()之后的尾部内容剔除注释--行注释与/* */块注释与分号后仍有内容即抛错。测试覆盖了 多语句拒绝 与 注释尾不误判select 1 as val; -- trailing comment可以正常执行。需要跑脚本时请使用executeDump()——SqlJsConnection.executeDump 直接调用原生db.exec(dump)执行多语句文本测试 executeDump runs a multi-statement script 验证了它能一次性插入两条记录。4. 无 FTS5 全文检索官方发布的 sql.js 构建没有编译 FTS5 模块因此$fulltext查询需要自定义构建。测试 the published sql.js build has no FTS5 module 以create virtual table book using fts5(title)的no such module: fts5错误证实了这一点。小结mikro-orm/sql-js是一个零原生依赖、浏览器/Node 通吃的 SQLite 内存驱动配置只需entitiesdbName自动默认为:memory:通过driverOptions你可以控制 WASM 加载locateFile/wasmBinary、复用预初始化的模块sqlJs以及恢复历史镜像datagetNativeClient()暴露原生Database用于export()持久化。由于底层复用了SqlitePlatformSchema Generator、Migrations、QueryBuilder、Kysely、流式查询与带bodyJs的存储例程全部可用。需要牢记的边界是仅内存、不支持 ATTACH、单语句查询限制脚本用executeDump()、无 FTS5。若你的场景需要文件落盘或更完整的 SQLite 特性应改用 mikro-orm/sqlite 驱动若追求浏览器端可运行、零原生依赖sql.js 驱动则是理想的选型。赞分享后端【免费下载链接】mikro-ormTypeScript ORM for Node.js based on Data Mapper, Unit of Work and Identity Map patterns. Supports MongoDB, MySQL, MariaDB, MS SQL Server, PostgreSQL and SQLite/libSQL databases.项目地址https://gitcode.com/gh_mirrors/mi/mikro-orm点击查看免费下载相关推荐MikroORM 与 sql.js 实战在浏览器与 Node.js 中运行纯内存 SQLiteWASMMikroORM 与 sql.js 实战在浏览器与 Node.js 中运行纯内存 SQLiteWASM 本文围绕 MikroORM 的 mikro or后端MikroORM 使用 SQL 数据库驱动指南MySQL、MariaDB、PostgreSQL 与 SQLite 集成实战MikroORM 使用 SQL 数据库驱动指南MySQL、MariaDB、PostgreSQL 与 SQLite 集成实战 本篇技术指南聚焦 MikroORM后端ArcherySec API开发指南打造自动化安全测试流水线ArcherySec API开发指南打造自动化安全测试流水线 ArcherySec是一款强大的ASOC应用安全编排与协调和ASPM应用安全发布管理工具后端网络安全应用安全上一篇StarRocks SET ROLE 命令完全指南会话级角色激活与权限切换实战下一篇告别语言障碍KISS Translator 双语翻译插件终极指南创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考