Skip to content

Add a package_manager option with pnpm support - #676

Merged
tricknotes merged 4 commits into
mainfrom
support-pnpm
Sep 9, 2026
Merged

Add a package_manager option with pnpm support#676
tricknotes merged 4 commits into
mainfrom
support-pnpm

Conversation

@tricknotes

@tricknotes tricknotes commented Sep 8, 2026

Copy link
Copy Markdown
Owner

Summary

Adds pnpm as a package manager for installing an Ember application's NodeJS dependencies, behind a new package_manager option, and deprecates the yarn option in its favour.

  • package_manager option (740648e): :npm (the default), :yarn, or :pnpm. pnpm_path implies pnpm the way yarn_path implies yarn, so existing configurations keep their meaning. EmberCli::Shell#install runs pnpm install for a pnpm application (there is no pnpm prune beside it: pnpm install already removes the packages package.json no longer lists), EmberCli::PathSet#pnpm resolves the executable from pnpm_path or $PATH and raises DependencyError pointing at https://pnpm.io/installation when it is missing, and EmberCli::App#package_manager / #pnpm? expose the choice.
  • Heroku (df35d2c): rails generate ember:heroku writes an empty root-level pnpm-lock.yaml for a pnpm project (Heroku's NodeJS buildpack selects the package manager by lockfile) and copies the packageManager the Ember applications declare (the new EmberCli::App#package_manager_spec) into the generated package.json, so the buildpack pins that version instead of falling back to pnpm@latest. The generator spec now registers only the application under test instead of mutating the shared configuration.
  • yarn: true deprecated (fd614d9): it still selects yarn, with a deprecation warning through the new EmberCli.deprecator (an ActiveSupport::Deprecation with a 1.0 horizon, registered with the application's deprecators on Rails 7.1 and later), printed once per application. The README documents package_manager only; the yarn option is kept for compatibility and is no longer listed.
  • CI coverage for Yarn and pnpm (4283396): PACKAGE_MANAGER=yarn bin/setup and PACKAGE_MANAGER=pnpm bin/setup install the dummy application with Yarn 1 or pnpm and register it with the matching package_manager (npm stays the default, any other value fails early), and CI runs one such job per package manager and blueprint (Vite-based 7.0.0 and classic 5.12.0), so that a node_modules laid out by each package manager is exercised through the whole suite rather than only by the stand-in executables in Shell#install's spec.

Test plan

  • bin/setup && bin/rake with ember-new-output v7.0.0 (Vite), npm: 192 examples, of which the 186 that do not drive a browser pass; the 6 browser-driven examples could not run in that environment (no chromedriver)
  • PACKAGE_MANAGER=yarn bin/setup_ember && PACKAGE_MANAGER=yarn bin/rake with v7.0.0: the same 186 pass, same 6 could not run
  • Each commit passes bin/rspec spec/lib spec/generators on its own (apart from the browser-driven EmberCli::App#test example)
  • CI: all 16 matrix jobs green on 4283396, including the two yarn and two pnpm jobs

Follow-ups (not in this PR)

  • Detecting the package manager from packageManager / the lockfile when no option is given

The gem only knew how to install an Ember application's dependencies with
npm or, behind the `yarn` option, Yarn. `ember-cli` has generated
pnpm-based applications since `ember new --pnpm` landed in 5.1, and
those applications carry a `pnpm-lock.yaml` that `npm install` ignores,
so a Rails project could not deploy one through `assets:precompile`
without installing its dependencies by hand first.

Introduce a `package_manager` option (`:npm`, `:yarn`, or `:pnpm`) rather
than a `pnpm: true` flag next to `yarn: true`: two booleans can both be
set at once, and every further package manager would repeat the
conflict. `yarn: true` stays as shorthand for `package_manager: :yarn`,
and `pnpm_path` implies pnpm the way `yarn_path` implies yarn, so no
existing configuration changes meaning. The package manager is read
through the new `EmberCli::App#package_manager` and `EmberCli::App#pnpm?`.

There is no `pnpm prune` beside `pnpm install`, unlike the npm branch:
`pnpm install` already drops the packages `package.json` no longer lists.

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
Heroku's NodeJS buildpack picks its package manager from the lockfile at
the project root, so `rails generate ember:heroku` now writes an empty
`pnpm-lock.yaml` for a pnpm project, the way it writes `yarn.lock` for a
Yarn one, and copies the `packageManager` field the Ember applications
declare (read through the new `EmberCli::App#package_manager_spec`) into
the generated `package.json`, since the buildpack otherwise installs the
latest pnpm release with a warning.

The generator spec's `configure_application` now registers only the
application under test instead of adding it to the shared configuration,
so that the dummy project's own applications take no part in the
generator's `EmberCli.any?` checks.

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
@tricknotes tricknotes changed the title Install NodeJS dependencies with pnpm Add a package_manager option with pnpm support Sep 9, 2026
`yarn: true` still selects yarn, but now warns through the new
`EmberCli.deprecator` (an `ActiveSupport::Deprecation` with a `1.0`
horizon, registered with the application's deprecators on Rails 7.1 and
later so that `config.active_support.deprecation` applies to it) and
points at `package_manager: :yarn`. `yarn_path` alone keeps implying yarn
without a warning, as `pnpm_path` implies pnpm.

`PathSet#package_manager` memoizes its answer so that the warning is
printed once per application rather than on every query. The specs that
are not about the shorthand configure yarn through `package_manager`.

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
`PACKAGE_MANAGER` selects the package manager `bin/setup_ember` installs
the dummy application's dependencies with: `npm` (the default), `yarn`,
or `pnpm`, with any other value failing early. `yarn install` and `pnpm
install` serve the Vite-based blueprint, and `yarn add --dev` and `pnpm
add --save-dev` the classic one, where they install the rest of the
dependencies alongside `ember-cli-rails-addon` the way `npm install`
does. The dummy application's initializer registers the same package
manager, so that `ember-cli-rails` runs against the `node_modules` that
package manager laid out.

CI adds one Yarn and one pnpm job per blueprint (Vite-based `7.0.0` and
classic `5.12.0`), installing Yarn 1 and pnpm 10 explicitly, so that the
`yarn` and `pnpm` branches of `Shell#install` run against a real
`node_modules` rather than only against the stand-in executables in its
spec.

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
@tricknotes
tricknotes force-pushed the support-pnpm branch 2 times, most recently from 3879c7e to 4283396 Compare September 9, 2026 15:44
@tricknotes
tricknotes marked this pull request as ready for review September 9, 2026 16:24
@tricknotes
tricknotes merged commit fb603c3 into main Sep 9, 2026
16 checks passed
@tricknotes
tricknotes deleted the support-pnpm branch September 9, 2026 16:25
@tricknotes tricknotes mentioned this pull request Sep 9, 2026
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.

2 participants