From 2dd8712c8704766a55798394f19faa740514e109 Mon Sep 17 00:00:00 2001 From: Zoltan Kochan Date: Fri, 17 Apr 2026 14:30:28 +0200 Subject: [PATCH] fix: pnpm init skips devEngines.packageManager in workspace subpackages (#11285) The devEngines.packageManager field should only live at the workspace root. When init runs inside a subpackage, the field is now omitted. --- .../init-skip-dev-engines-in-subpackage.md | 6 ++++ workspace/commands/src/init.ts | 8 +++-- workspace/commands/test/init.test.ts | 32 +++++++++++++++++++ 3 files changed, 44 insertions(+), 2 deletions(-) create mode 100644 .changeset/init-skip-dev-engines-in-subpackage.md diff --git a/.changeset/init-skip-dev-engines-in-subpackage.md b/.changeset/init-skip-dev-engines-in-subpackage.md new file mode 100644 index 0000000000..0002403e0d --- /dev/null +++ b/.changeset/init-skip-dev-engines-in-subpackage.md @@ -0,0 +1,6 @@ +--- +"@pnpm/workspace.commands": patch +"pnpm": patch +--- + +`pnpm init` no longer adds the `devEngines.packageManager` field when run inside a workspace subpackage. The field is only added to the workspace root's `package.json`. diff --git a/workspace/commands/src/init.ts b/workspace/commands/src/init.ts index 38df7d92bd..433f10ba40 100644 --- a/workspace/commands/src/init.ts +++ b/workspace/commands/src/init.ts @@ -59,6 +59,7 @@ export type InitOptions = & Partial> & { bare?: boolean initAuthorName?: string @@ -77,10 +78,13 @@ export async function handler (opts: InitOptions, params?: string[]): Promise { expect(manifest).not.toHaveProperty('devEngines') }) +test('init a new package.json in a workspace subpackage does not add devEngines', async () => { + prepareEmpty() + const workspaceDir = process.cwd() + const subpackageDir = path.join(workspaceDir, 'packages/foo') + fs.mkdirSync(subpackageDir, { recursive: true }) + await init.handler({ + cliOptions: { dir: subpackageDir }, + initPackageManager: true, + workspaceDir, + }) + const manifest = loadJsonFileSync(path.join(subpackageDir, 'package.json')) + expect(manifest).toBeTruthy() + expect(manifest).not.toHaveProperty('devEngines') + expect(manifest).not.toHaveProperty('packageManager') +}) + +test('init a new package.json at the workspace root adds devEngines', async () => { + prepareEmpty() + const workspaceDir = process.cwd() + await init.handler({ + cliOptions: {}, + initPackageManager: true, + workspaceDir, + }) + const manifest = loadJsonFileSync(path.resolve('package.json')) + expect(manifest.devEngines?.packageManager).toEqual({ + name: 'pnpm', + version: expect.stringMatching(/^\^\d+\.\d+\.\d+/), + onFail: 'download', + }) +}) + test('init a new package.json with init-type=module', async () => { prepareEmpty() await init.handler({ cliOptions: {}, initType: 'module' })