[Infra] Enable NX monorepo for Backpack#4258
[Infra] Enable NX monorepo for Backpack#4258Gert-Jan Vercauteren (gert-janvercauteren) wants to merge 2 commits intomainfrom
Conversation
Convert Backpack from manual monorepo to NX-managed monorepo with minimal disruption: - Consolidate to npm workspaces: single package-lock.json, remove postinstall hook - Add NX configuration: nx.json for workspace settings, packages/project.json for backpack library project - Wrap existing build system: all NX targets use nx:run-commands to call existing npm scripts (build, test, lint, typecheck, transpile, storybook) - Update CI/CD: GitHub Actions cache paths now use single lock file and .nx/cache for NX computation caching - Add convenience scripts: nx:* prefix commands and nx:affected:* for future multi-project workflows - Fix package hoisting: update copy-normal_css.sh path from packages/node_modules to node_modules This approach preserves all existing functionality while enabling NX benefits: task caching, affected detection, and scalability for future NX projects. All existing npm run * commands still work unchanged. Co-Authored-By: Claude Haiku 4.5 <noreply@anthropic.com>
There was a problem hiding this comment.
Pull request overview
This PR introduces NX monorepo tooling to the Backpack design system, consolidating npm dependency management to a single workspace and adding NX task orchestration with caching on top of the existing build system. The goal is zero breaking changes to existing workflows while enabling NX's task caching, affected detection, and scalability benefits.
Changes:
- Consolidate npm to workspace mode: remove
packages/package-lock.jsonandpackages/node_modules/, add"workspaces": ["packages"]to rootpackage.json, removepostinstallscript - Add NX infrastructure:
nx.json(workspace config),packages/project.json(project config wrapping existing npm scripts), andnxdevDependency with conveniencenx:*scripts - Update CI/CD workflows to use the consolidated
package-lock.jsonand add.nx/cacheto the cache paths
Reviewed changes
Copilot reviewed 8 out of 11 changed files in this pull request and generated 3 comments.
Show a summary per file
| File | Description |
|---|---|
scripts/scss/copy-normal_css.sh |
Updates normalize.css copy path from packages/node_modules/ to root node_modules/ (correct with workspace hoisting) |
packages/project.json |
New NX project descriptor wrapping all existing npm build/test/lint/transpile scripts as cacheable targets |
packages/package-lock.json |
Deleted; dependencies now managed in the root package-lock.json via npm workspaces |
package.json |
Adds npm workspaces config, removes postinstall script, simplifies clean:node_modules, adds nx devDependency and nx:* convenience scripts |
nx.json |
New NX workspace configuration with named inputs, target defaults, and cache directory |
.gitignore |
Adds .nx/cache and .nx/workspace-data to gitignore |
.github/workflows/release.yml |
Updates most cache path/key references; ReleaseWeb job not updated (bug) |
.github/workflows/pr.yml |
Updates most cache path/key references; StorybookDeploy job not updated (bug) |
.github/workflows/main.yml |
Updates all cache path/key references correctly |
.github/workflows/_build.yml |
Updates all cache path/key references correctly |
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
| with: | ||
| path: | | ||
| node_modules/ | ||
| packages/node_modules/ | ||
| key: ${{ env.CACHE_NAME }}-${{ hashFiles('package-lock.json', 'packages/package-lock.json') }} | ||
| .nx/cache | ||
| key: ${{ env.CACHE_NAME }}-${{ hashFiles('package-lock.json') }} | ||
|
|
||
| - name: Install dependencies | ||
| if: ${{ steps.npm-cache.outputs.cache-hit != 'true' }} |
There was a problem hiding this comment.
The PR updated the Create-NPM-Cache and Create-Build-Cache jobs to use the new cache paths (node_modules/, .nx/cache) and key (hashFiles('package-lock.json')), but the StorybookDeploy job's "Restore npm Cache" step (lines 106–113) was not updated. It still specifies packages/node_modules/ in the path (which no longer exists after consolidating to npm workspaces) and uses hashFiles('package-lock.json', 'packages/package-lock.json') as the key (but packages/package-lock.json was deleted in this PR). This will cause a permanent cache miss on the StorybookDeploy job, requiring it to reinstall all dependencies on every run. The step should be updated to match the other jobs: path node_modules/ + .nx/cache, key ${{ env.CACHE_NAME }}-${{ hashFiles('package-lock.json') }}.
| with: | ||
| path: | | ||
| node_modules/ | ||
| packages/node_modules/ | ||
| key: ${{ env.CACHE_NAME }}-${{ hashFiles('package-lock.json', 'packages/package-lock.json') }} | ||
| .nx/cache | ||
| key: ${{ env.CACHE_NAME }}-${{ hashFiles('package-lock.json') }} |
There was a problem hiding this comment.
The PR updated the Create-NPM-Cache and Create-Build-Cache jobs to use the new cache paths and key, but the ReleaseWeb job's "Restore Cache" step (lines 105–112) was not updated. It still specifies packages/node_modules/ in the path (which no longer exists after consolidating to npm workspaces) and uses hashFiles('package-lock.json', 'packages/package-lock.json') as the key (but packages/package-lock.json was deleted in this PR). This cache step precedes the npm run transpile and npm publish commands in the release pipeline, so a cache miss here means node_modules will be absent during NPM publishing, causing the release to fail. The step should be updated to match the other jobs: path node_modules/ + .nx/cache, key ${{ env.CACHE_NAME }}-${{ hashFiles('package-lock.json') }}.
| "!{projectRoot}/**/*-test.tsx", | ||
| "!{projectRoot}/**/*-test.ts", | ||
| "!{projectRoot}/**/*-test.js", | ||
| "!{projectRoot}/**/*.stories.tsx" |
There was a problem hiding this comment.
The production named input in nx.json excludes test files using the patterns *-test.tsx, *-test.ts, and *-test.js. However, the project also has accessibility-test.tsx files (e.g., packages/bpk-component-badge/src/accessibility-test.tsx, packages/bpk-component-button/src/BpkButtonV2/accessibility-test.tsx). These do not match the excluded patterns since they don't end in -test.tsx — they have a different prefix. As a result, changes to accessibility test files will unnecessarily invalidate the build cache. The exclusion pattern should also include !{projectRoot}/**/accessibility-test.tsx (or a broader pattern like !{projectRoot}/**/*test*) to properly exclude these test files from production inputs.
| "!{projectRoot}/**/*.stories.tsx" | |
| "!{projectRoot}/**/*.stories.tsx", | |
| "!{projectRoot}/**/accessibility-test.tsx" |
|
Visit https://backpack.github.io/storybook-prs/4258 to see this build running in a browser. |
- Fix StorybookDeploy job in pr.yml: update cache path/key to use unified lock file (was still referencing packages/node_modules) - Fix ReleaseWeb job in release.yml: update cache path/key (critical for npm publish to work) - Add accessibility-test.tsx to NX production input exclusions to prevent unnecessary build cache invalidation Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
|
Visit https://backpack.github.io/storybook-prs/4258 to see this build running in a browser. |
Summary
Enable NX monorepo infrastructure for Backpack design system with minimal disruption to existing build pipelines and development workflows.
Key changes:
Impact: Zero breaking changes. All existing
npm run *commands continue to work. NX provides optional benefits: task caching, affected detection, and scalability for future projects.Test plan
npm run buildpassesnpm run jest- 343 test suites pass (1786 tests)npx nx build backpack- executes build successfullynpx nx test backpack- tests pass with cachenpx nx show projects- shows backpack project🤖 Generated with Claude Code