Node.js后端程序打包问题汇总(webpack、rsbuild、fastify、knex、objection、sqlite3、svg-captcha)

239 阅读2分钟

背景说明

场景 使用 node.js 进行后端开发,部署时通常需要打包为单文件,然后放到服务器运行。 这里记录我在打包过程中,碰到的各类问题及解决方案,希望能够帮助到更多道友😄

提示 此文持续更新,可以收藏⭐或者点个关注❤

技术栈

打包工具rsbuild
WEB框架fastify
数据库ORMObjection.js/Knex
node版本v22.x
操作系统windows 11

涉及的库

名称说明
knex为 PostgreSQL、MySQL、CockroachDB、SQL Server、SQLite3 和 Oracle 设计的查询构建器,灵活、可移植且使用愉快
svg-captcha一个用于在后端生成图片验证码的库
isolated-vm安全且隔离的 JavaScript 环境

问题汇总

排除 knex 依赖的数据库驱动

使用 Objection.js 和 Knex 时,Knex 会尝试加载其他数据库的依赖(如 pg、mysql 等),即使你只使用了 sqlite3。这些数据库驱动默认在 Knex 的代码中被 require,但未实际安装,导致在使用打包工具(如 webpack、 rsbuild)时报错。此时我们可以配置打包工具排除用不到的驱动。

//根据事情依赖填写
externals:['pg', 'pg-query-stream','oracledb', 'tedious', 'sqlite3', 'mysql']

COMMONJS 模式下 knex 报 is not a function

const knex = require('knex')

//以下方法在开发模式正常,打包后就报 knex is not a function 错误
knex({})

这是因为require('knex')返回的 default,需要转换:

const { default : KnexBuilder, Knex } = require('knex')

KnexBuilder({})

找不到 sqlite3 的二进制文件

这个错误通常是因为 sqlite3 或其他原生模块(如 better-sqlite3)在打包过程中丢失了必要的二进制文件(bindings)。这些二进制文件在运行时需要加载,但打包工具(如 rsbuild)默认不会包含它们。

解决思路是打包时,将必要的.node文件拷贝出来,然后告之工具库使用。我没研究如何在sqlite3中实现,而是选择了better-sqlite3

  1. 在代码中指定nativeBinding参数
if(process.env.NODE_ENV === 'production'){
    connection.options = {
        nativeBinding: "assets/better_sqlite3.node"
    }
}
  1. 配置 rsbuild 拷贝文件
output:{
    copy:[{ 
            from: "./node_modules/better-sqlite3/build/Release/better_sqlite3.node", 
            to:"assets"
    }]
}

svg-captcha 字体文件

svg-captcha初始化时,会引入位于 fonts 目录的 Comismsh.ttf 字体文件。 不出意外,打包后运行程序,会报找不到文件的错误😄,这是因为代码写死的路径,解决方案有:

  1. 将字体文件放置在正确的路径(入口文件的上层,可看报错信息)
  2. 修改代码 node_modules\svg-captcha\lib\option-manager.js,此方法每次 npm i 后都要修改😂
const fontPath = path.join(
    __dirname,
    process.env.NODE_ENV === 'production'?
        './assets/Comismsh.ttf' //这里填写实际的地址
        :
        '../fonts/Comismsh.ttf'
);

isolated-vm

使用 rsbuild 构建时,会报错Module not found: Can't resolve './out/isolated_vm',相关 issue 见:github

解决思路:

  1. 排除 ./out/isolated_vm
  2. 将目标文件拷贝到 dist 目录下即可(通常是 node_modules/isolated-vm/out)