Skip to content

Record package manager in package.json engines field#229

Open
iclanton wants to merge 8 commits intoSharePoint:mainfrom
iclanton:iclanton/pm-engines-field
Open

Record package manager in package.json engines field#229
iclanton wants to merge 8 commits intoSharePoint:mainfrom
iclanton:iclanton/pm-engines-field

Conversation

@iclanton
Copy link
Copy Markdown
Contributor

@iclanton iclanton commented Apr 3, 2026

Description

Replaces the lastPackageManager getter on SPFxScaffoldLog with a cleaner mechanism: the selected package manager is now written directly into the project's package.json "engines" field after a successful install, and read back from there on subsequent spfx create runs.

New in @microsoft/spfx-template-api (PackageManagerEnginesHelper):

  • tryReadPackageManagerFromPackageJsonEnginesAsync — reads the package manager from engines; throws if multiple known package managers are found (e.g. both npm and pnpm are listed, which is a misconfiguration).
  • writePackageManagerToPackageJsonEnginesAsync — spawns pm --version asynchronously, parses the major version, and writes "pnpm": ">=10" (or equivalent) into engines.
  • Exports VALID_PACKAGE_MANAGERS (as a const tuple) and PackageManager type alias.

Changes to CreateAction:

  • Reads the previous package manager from package.json engines instead of from the scaffold log.
  • Calls writePackageManagerToPackageJsonEnginesAsync after a successful install.

Depends on #227 (adds .spfx-scaffold.jsonl to .gitignore in all templates/examples).

How was this tested

  • Unit tests added for both new helpers in PackageManagerEnginesHelper.test.ts covering: ENOENT, missing engines, each supported pm, multiple-pm conflict error, version detection, engines write, and all warning/skip paths.
  • Existing CreateAction tests updated to mock the new API functions; snapshots regenerated.

Type of change

  • Bug fix
  • New feature
  • Template change (modifies template files or examples)
  • Docs / CI change only

🤖 Generated with Claude Code

iclanton and others added 2 commits April 2, 2026 23:49
- Remove `lastPackageManager` from `SPFxScaffoldLog`; the selected
  package manager is now stored in (and read back from) the project's
  `package.json` `"engines"` field instead of the JSONL scaffold log.
- Add `PackageManagerEnginesHelper` to `@microsoft/spfx-template-api`:
  - `tryReadPackageManagerFromPackageJsonEnginesAsync` reads the package
    manager from `engines`, throwing if multiple are found.
  - `writePackageManagerToPackageJsonEnginesAsync` detects the installed
    version via async spawn and writes a `>=MAJOR` constraint.
  - Exports `VALID_PACKAGE_MANAGERS` and `PackageManager` type.
- Update `CreateAction` to use the new helpers instead of the log.
- Add unit tests for `PackageManagerEnginesHelper`.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
@iclanton iclanton force-pushed the iclanton/pm-engines-field branch from bc88929 to edba306 Compare April 3, 2026 03:49
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 updates SPFx scaffolding to persist the chosen package manager in the generated project’s package.json "engines" field, and to read it back on subsequent spfx create runs (replacing the previous SPFxScaffoldLog.lastPackageManager mechanism).

Changes:

  • Add PackageManagerEnginesHelper to read/write the selected package manager in package.json "engines".
  • Update CreateAction to read the previously selected package manager from engines and to write it back after a successful install.
  • Update templates/examples/test fixtures to ignore .spfx-scaffold.jsonl, and update docs/snapshots/tests accordingly.

Reviewed changes

Copilot reviewed 13 out of 13 changed files in this pull request and generated 6 comments.

Show a summary per file
File Description
tests/spfx-template-test/test-template/.gitignore Ignore scaffold log file in test template fixture.
tests/spfx-template-test/src/tests/snapshots/templates.test.ts.snap Snapshot update reflecting added .gitignore file in generated output.
templates/webpart-react/.gitignore Ignore .spfx-scaffold.jsonl in template output.
templates/webpart-noframework/.gitignore Ignore .spfx-scaffold.jsonl in template output.
templates/webpart-minimal/.gitignore Ignore .spfx-scaffold.jsonl in template output.
templates/library/.gitignore Ignore .spfx-scaffold.jsonl in template output.
templates/extension-search-query-modifier/.gitignore Ignore .spfx-scaffold.jsonl in template output.
templates/extension-listviewcommandset/.gitignore Ignore .spfx-scaffold.jsonl in template output.
templates/extension-formcustomizer-react/.gitignore Ignore .spfx-scaffold.jsonl in template output.
templates/extension-formcustomizer-noframework/.gitignore Ignore .spfx-scaffold.jsonl in template output.
templates/extension-fieldcustomizer-react/.gitignore Ignore .spfx-scaffold.jsonl in template output.
templates/extension-fieldcustomizer-noframework/.gitignore Ignore .spfx-scaffold.jsonl in template output.
templates/extension-fieldcustomizer-minimal/.gitignore Ignore .spfx-scaffold.jsonl in template output.
templates/extension-application-customizer/.gitignore Ignore .spfx-scaffold.jsonl in template output.
templates/ace-search-card/.gitignore Ignore .spfx-scaffold.jsonl in template output.
templates/ace-generic-primarytext-card/.gitignore Ignore .spfx-scaffold.jsonl in template output.
templates/ace-generic-image-card/.gitignore Ignore .spfx-scaffold.jsonl in template output.
templates/ace-generic-card/.gitignore Ignore .spfx-scaffold.jsonl in template output.
templates/ace-data-visualization/.gitignore Ignore .spfx-scaffold.jsonl in template output.
examples/webpart-react/.gitignore Ignore .spfx-scaffold.jsonl in example output.
examples/webpart-noframework/.gitignore Ignore .spfx-scaffold.jsonl in example output.
examples/webpart-minimal/.gitignore Ignore .spfx-scaffold.jsonl in example output.
examples/test/.gitignore Ignore scaffold log file in test example.
examples/library/.gitignore Ignore .spfx-scaffold.jsonl in example output.
examples/extension-search-query-modifier/.gitignore Ignore .spfx-scaffold.jsonl in example output.
examples/extension-listviewcommandset/.gitignore Ignore .spfx-scaffold.jsonl in example output.
examples/extension-formcustomizer-react/.gitignore Ignore .spfx-scaffold.jsonl in example output.
examples/extension-formcustomizer-noframework/.gitignore Ignore .spfx-scaffold.jsonl in example output.
examples/extension-fieldcustomizer-react/.gitignore Ignore .spfx-scaffold.jsonl in example output.
examples/extension-fieldcustomizer-noframework/.gitignore Ignore .spfx-scaffold.jsonl in example output.
examples/extension-fieldcustomizer-minimal/.gitignore Ignore .spfx-scaffold.jsonl in example output.
examples/extension-application-customizer/.gitignore Ignore .spfx-scaffold.jsonl in example output.
examples/ace-search-card/.gitignore Ignore .spfx-scaffold.jsonl in example output.
examples/ace-generic-primarytext-card/.gitignore Ignore .spfx-scaffold.jsonl in example output.
examples/ace-generic-image-card/.gitignore Ignore .spfx-scaffold.jsonl in example output.
examples/ace-generic-card/.gitignore Ignore .spfx-scaffold.jsonl in example output.
examples/ace-data-visualization/.gitignore Ignore .spfx-scaffold.jsonl in example output.
common/docs/spfx-cli-architecture.md Update architecture docs to describe engines-based package manager detection.
apps/spfx-cli/src/cli/actions/tests/CreateAction.test.ts Update tests to mock engines-based package manager read.
apps/spfx-cli/src/cli/actions/tests/snapshots/CreateAction.test.ts.snap Snapshot updates for revised warning text/test names.
apps/spfx-cli/src/cli/actions/CreateAction.ts Switch from scaffold-log PM detection to package.json engines + write after install.
api/spfx-template-api/src/writing/test/PackageManagerEnginesHelper.test.ts Add unit tests for reading/writing engines-based package manager record.
api/spfx-template-api/src/writing/test/snapshots/PackageManagerEnginesHelper.test.ts.snap Snapshot for helper terminal warning output.
api/spfx-template-api/src/writing/PackageManagerEnginesHelper.ts New helper implementing engines read/write and exported PM types/tuple.
api/spfx-template-api/src/writing/index.ts Re-export new helper API from writing barrel.
api/spfx-template-api/src/logging/test/SPFxScaffoldLog.test.ts Remove tests for deleted lastPackageManager API.
api/spfx-template-api/src/logging/SPFxScaffoldLog.ts Remove cached lastPackageManager implementation from scaffold log.
api/spfx-template-api/src/index.ts Re-export new helper API from package entrypoint.
api/spfx-template-api/README.md Remove docs referencing deleted lastPackageManager.
api/spfx-template-api/etc/spfx-template-api.api.md Update API report for new exports and removal of lastPackageManager.

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Copy link
Copy Markdown
Contributor

@nick-pape nick-pape left a comment

Choose a reason for hiding this comment

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

Copilot left some valid looking comments also

iclanton and others added 6 commits April 3, 2026 14:44
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
…ar stale engines entries

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
…led in CreateAction tests

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
@iclanton iclanton enabled auto-merge (squash) April 3, 2026 23:07
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants