NestJS部署到Google App Engine报Module not found错误
这个Module not found报错本质是部署流程的构建上下文不一致、配置缺失导致的,具体问题点:
- 你在Cloud Build前三个步骤执行的
npm install、npm run build产物,默认不会被后续gcloud app deploy步骤复用。gcloud部署App Engine时,会在GAE专属构建环境里重新拉取源码、单独执行依赖安装和启动流程,不会读取之前Cloud Build步骤里生成的node_modules、dist目录。 - 现有
app.yaml没有显式配置启动入口,Node.js14运行时默认会找根目录的server.js/app.js启动,不会识别NestJS编译输出的dist/main.js入口;加上GAE默认执行npm install --production只安装生产依赖,如果你把运行时需要的包错放在devDependencies里,或者构建步骤没在GAE侧触发,必然报模块找不到。 - 大概率根目录下的
.gcloudignore默认排除了dist构建产物目录,就算你本地提前编译完成,部署时也根本不会把编译后的文件传到GAE运行环境。
先调整
package.json配置
把所有业务运行时需要用到的包(包括NestJS核心包、Stripe、Firebase SDK这类)从devDependencies移到dependencies下,仅把TypeScript、ESLint、测试工具这类仅开发/编译阶段用的包留在devDependencies。同时补全GAE识别的构建钩子和生产启动脚本:{ "scripts": { "build": "nest build", "start:prod": "node dist/main.js", "gcp-build": "npm run build" } }其中
gcp-build是GAE Node.js运行时的内置钩子,部署时会在依赖安装完成后自动执行,不需要你在Cloud Build流程里提前构建。修正
app.yaml配置
显式声明启动入口和生产环境变量,替换原有内容:runtime: nodejs14 service: backend entrypoint: npm run start:prod env_variables: NODE_ENV: production配置后GAE不会再用默认规则查找启动文件,直接走NestJS生产启动流程。
精简
cloudbuild.yaml逻辑
去掉冗余的提前构建步骤,避免构建上下文不一致,调整后配置:steps: - name: node:14.15.1 entrypoint: npm args: ["install"] - name: node:14.15.1 entrypoint: npm args: ["run", "create-env"] env: - "_APP_LUNE_DEV_TOKEN=${_APP_LUNE_DEV_TOKEN}" - "_BUCKET_NAME=${_BUCKET_NAME}" - "_FIREBASE_API_KEY=${_FIREBASE_API_KEY}" - "_FIREBASE_APP_ID=${_FIREBASE_APP_ID}" - "_FIREBASE_AUTH_DOMAIN=${_FIREBASE_AUTH_DOMAIN}" - "_FIREBASE_MESSAGING_SENDER_ID=${_FIREBASE_MESSAGING_SENDER_ID}" - "_FIREBASE_PROJECT_ID=${_FIREBASE_PROJECT_ID}" - "_FIREBASE_STORAGE_BUCKET=${_FIREBASE_STORAGE_BUCKET}" - "_GOOGLE_APPLICATION_CREDENTIALS=${_GOOGLE_APPLICATION_CREDENTIALS}" - "_LUNE_API_BASE_URL=${_LUNE_API_BASE_URL}" - "_STRIPE_SECRET_KEY=${_STRIPE_SECRET_KEY}" - name: "gcr.io/cloud-builders/gcloud" args: ["app", "deploy"] timeout: "1600s" options: logging: CLOUD_LOGGING_ONLY检查根目录
.gcloudignore规则
确认文件中没有排除dist目录、create-env生成的环境变量文件,避免部署时必要文件被过滤不上传。
改完配置后先在本地执行npm run build && npm run start:prod,确认本地生产模式启动无模块缺失报错,再触发Cloud Build或者本地执行gcloud app deploy即可,两种部署方式都会走GAE侧统一的依赖安装、构建、启动流程,不会再出现上下文不一致问题。
额外提示:Node.js14已经结束官方维护,条件允许的话建议把runtime和Cloud Build用的Node镜像升级到18或20长期支持版本,避免后续出现运行时兼容问题。
内容的提问来源于stack exchange,提问作者Anas Kasmi

