Originally posted here: GoogleCloudPlatform/buildpacks#621
Was asked by @Yuangwang to create the issue here instead.
Description
When buildCommand is set in apphosting.yaml, the Node.js buildpack's OverrideAppHostingBuildScript function in pkg/nodejs/nodejs.go reads package.json, deserializes it into the PackageJSON Go struct, adds the apphosting:build script, and writes the struct back to disk.
The PackageJSON struct does not include a workspaces field (or other fields like overrides, resolutions, optionalDependencies, peerDependencies, etc.), so these are silently dropped when the file is rewritten.
This causes npm ci to install only root-level dependencies (844 packages in our case) instead of the full workspace dependency tree (~3900 packages). Workspace-local binaries are unavailable and the build fails.
Steps to reproduce
- Create an npm workspace monorepo with
workspaces defined in the root package.json
- Set up Firebase App Hosting with the root as the app directory
- Set
buildCommand in apphosting.yaml to any value (e.g. npm run build)
- Trigger a build
Expected behavior
package.json should be preserved as-is, with all fields intact. npm ci should resolve workspaces and install the full dependency tree.
Actual behavior
package.json is rewritten without the workspaces field. npm ci installs only root-level dependencies. The build fails because workspace binaries (e.g. nuxi, vite, tsc) are missing.
Workaround
Don't set buildCommand in apphosting.yaml. Instead, define the apphosting:build script directly in package.json. The buildpack picks it up without rewriting the file.
Originally posted here: GoogleCloudPlatform/buildpacks#621
Was asked by @Yuangwang to create the issue here instead.
Description
When
buildCommandis set inapphosting.yaml, the Node.js buildpack'sOverrideAppHostingBuildScriptfunction inpkg/nodejs/nodejs.goreadspackage.json, deserializes it into thePackageJSONGo struct, adds theapphosting:buildscript, and writes the struct back to disk.The
PackageJSONstruct does not include aworkspacesfield (or other fields likeoverrides,resolutions,optionalDependencies,peerDependencies, etc.), so these are silently dropped when the file is rewritten.This causes
npm cito install only root-level dependencies (844 packages in our case) instead of the full workspace dependency tree (~3900 packages). Workspace-local binaries are unavailable and the build fails.Steps to reproduce
workspacesdefined in the rootpackage.jsonbuildCommandinapphosting.yamlto any value (e.g.npm run build)Expected behavior
package.jsonshould be preserved as-is, with all fields intact.npm cishould resolve workspaces and install the full dependency tree.Actual behavior
package.jsonis rewritten without theworkspacesfield.npm ciinstalls only root-level dependencies. The build fails because workspace binaries (e.g.nuxi,vite,tsc) are missing.Workaround
Don't set
buildCommandinapphosting.yaml. Instead, define theapphosting:buildscript directly inpackage.json. The buildpack picks it up without rewriting the file.