Skip to content

[Infra] Enable NX monorepo for Backpack#4258

Closed
Gert-Jan Vercauteren (gert-janvercauteren) wants to merge 2 commits intomainfrom
gert-janvercauteren/nx-monorepo-setup
Closed

[Infra] Enable NX monorepo for Backpack#4258
Gert-Jan Vercauteren (gert-janvercauteren) wants to merge 2 commits intomainfrom
gert-janvercauteren/nx-monorepo-setup

Conversation

@gert-janvercauteren
Copy link
Copy Markdown
Contributor

Summary

Enable NX monorepo infrastructure for Backpack design system with minimal disruption to existing build pipelines and development workflows.

Key changes:

  • 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 with NX via run-commands executors (all npm scripts preserved)
  • Update CI/CD workflows to use single lock file and NX computation cache
  • Add convenience nx:* scripts and nx:affected:* commands for future multi-project workflows

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 build passes
  • npm run jest - 343 test suites pass (1786 tests)
  • npx nx build backpack - executes build successfully
  • Cache hit verified on second run
  • npx nx test backpack - tests pass with cache
  • npx nx show projects - shows backpack project
  • GitHub Actions caching updated

🤖 Generated with Claude Code

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>
Copy link
Copy Markdown
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

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.json and packages/node_modules/, add "workspaces": ["packages"] to root package.json, remove postinstall script
  • Add NX infrastructure: nx.json (workspace config), packages/project.json (project config wrapping existing npm scripts), and nx devDependency with convenience nx:* scripts
  • Update CI/CD workflows to use the consolidated package-lock.json and add .nx/cache to 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.

Comment thread .github/workflows/pr.yml
Comment on lines 37 to 44
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' }}
Copy link

Copilot AI Mar 4, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

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') }}.

Copilot uses AI. Check for mistakes.
Comment on lines 59 to +63
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') }}
Copy link

Copilot AI Mar 4, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

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') }}.

Copilot uses AI. Check for mistakes.
Comment thread nx.json Outdated
"!{projectRoot}/**/*-test.tsx",
"!{projectRoot}/**/*-test.ts",
"!{projectRoot}/**/*-test.js",
"!{projectRoot}/**/*.stories.tsx"
Copy link

Copilot AI Mar 4, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

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.

Suggested change
"!{projectRoot}/**/*.stories.tsx"
"!{projectRoot}/**/*.stories.tsx",
"!{projectRoot}/**/accessibility-test.tsx"

Copilot uses AI. Check for mistakes.
@skyscanner-backpack-bot
Copy link
Copy Markdown

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>
@skyscanner-backpack-bot
Copy link
Copy Markdown

Visit https://backpack.github.io/storybook-prs/4258 to see this build running in a browser.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

DON'T MERGE minor Non breaking change

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants