firebase / firebase/apphosting-adapters

Node.js buildpack: setting buildCommand in apphosting.yaml silently strips npm workspaces from package.json

Open
#569 2 comments 2 reactions 0 assignees View on GitHub
Dominant language
TypeScript
Stars
478
Forks
1.5k
Avg merge
3d 22h
Merged PRs (30d)
2

Description

Originally posted here: https://github.com/GoogleCloudPlatform/buildpacks/issues/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`](https://github.com/GoogleCloudPlatform/buildpacks/blob/main/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

1. Create an npm workspace monorepo with `workspaces` defined in the root `package.json`
2. Set up Firebase App Hosting with the root as the app directory
3. Set `buildCommand` in `apphosting.yaml` to any value (e.g. `npm run build`)
4. 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.

Contributor guide

Open the contributing guide

Assessment

This issue has not been assessed yet.

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.