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

使用AWS CDK仅用mssql却遇knex相关打包错误,求解决

解决AWS CDK打包Knex仅依赖MSSQL时的缺失依赖错误

我仅使用mssql客户端,但执行cdk synth时出现如下打包错误:

环境版本信息

  • Node.js - v18.16.0
  • CDK - 2.95.1
  • knex - 2.5.1

错误日志

dirname /.../my-repo/cdk/my-app/lib/lambda
Bundling asset api---app/get-last-sales-no/Code/Stage...
✘ [ERROR] Could not resolve "sqlite3"

    node_modules/knex/lib/dialects/sqlite3/index.js:42:19:
      42 │     return require('sqlite3');
         ╵                    ~~~~~~~~~

  You can mark the path "sqlite3" as external to exclude it from the bundle, which will remove this
  error. You can also surround this "require" call with a try/catch block to handle this failure at
  run-time instead of bundle-time.

✘ [ERROR] Could not resolve "pg"

    node_modules/knex/lib/dialects/pgnative/index.js:13:19:
      13 │     return require('pg').native;
         ╵                    ~~~~

  You can mark the path "pg" as external to exclude it from the bundle, which will remove this
  error. You can also surround this "require" call with a try/catch block to handle this failure at
  run-time instead of bundle-time.

✘ [ERROR] Could not resolve "mysql2"

    node_modules/knex/lib/dialects/mysql2/index.js:15:19:
      15 │     return require('mysql2');
         ╵                    ~~~~~~~~

  You can mark the path "mysql2" as external to exclude it from the bundle, which will remove this
  error. You can also surround this "require" call with a try/catch block to handle this failure at
  run-time instead of bundle-time.

✘ [ERROR] Could not resolve "pg"

    node_modules/knex/lib/dialects/redshift/index.js:44:19:
      44 │     return require('pg');
         ╵                    ~~~~

  You can mark the path "pg" as external to exclude it from the bundle, which will remove this
  error. You can also surround this "require" call with a try/catch block to handle this failure at
  run-time instead of bundle-time.

查阅资料发现,部分用户通过为esbuild标记knex或客户端依赖为外部依赖解决了问题,但并未直接使用esbuild,推测AWS CDK在底层使用它,请问有什么解决办法?


解决办法

AWS CDK的NodejsFunction默认使用esbuild进行打包,你可以通过以下方式配置打包选项,将未使用的数据库驱动标记为外部依赖,让esbuild跳过它们的解析和打包:

方法1:在NodejsFunction中配置externalModules

直接在Lambda函数定义里添加打包配置,指定不需要打包的依赖:

import { NodejsFunction } from 'aws-cdk-lib/aws-lambda-nodejs';

new NodejsFunction(this, 'GetLastSalesNoFunction', {
  entry: './lib/lambda/get-last-sales-no.ts',
  bundling: {
    // 将未安装的数据库驱动以及knex本身标记为外部依赖
    externalModules: ['sqlite3', 'pg', 'mysql2', 'knex']
  }
});

方法2:通过esbuild配置文件全局设置

在项目根目录创建esbuild.config.js,添加外部依赖配置,CDK的NodejsFunction会自动读取该文件:

module.exports = {
  external: ['sqlite3', 'pg', 'mysql2']
};

方法3:自定义Bundling配置(适用于非NodejsFunction场景)

如果使用的是基础的Function类配合资产打包,可在BundlingOptions中通过命令传递esbuild参数:

import { Function, Code, Runtime } from 'aws-cdk-lib/aws-lambda';

new Function(this, 'GetLastSalesNoFunction', {
  runtime: Runtime.NODEJS_18_X,
  code: Code.fromAsset('./lib/lambda', {
    bundling: {
      image: Runtime.NODEJS_18_X.bundlingImage,
      command: [
        'bash', '-c',
        'npm install && npx esbuild index.ts --bundle --external:sqlite3 --external:pg --external:mysql2 --outfile=/asset-output/index.js'
      ]
    }
  }),
  handler: 'index.handler'
});

原理说明

Knex在源码中包含了所有数据库驱动的导入逻辑,即使你只使用MSSQL,esbuild打包时会扫描所有require语句并尝试解析依赖。将未安装的驱动标记为外部依赖后,esbuild会跳过这些依赖的打包,运行时Knex会动态加载你实际使用的MSSQL驱动,不会影响功能。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.10 16:15:01