From 1a68ab5157a984968daf98bc9ae73d6483da07d4 Mon Sep 17 00:00:00 2001 From: Niklas Mischkulnig <4586894+mischnic@users.noreply.github.com> Date: Tue, 24 Jan 2023 14:45:06 +0100 Subject: [PATCH 1/3] pnpm 7 changed the meaning of -W --- packages/core/package-manager/src/Pnpm.js | 13 +++++++++---- 1 file changed, 9 insertions(+), 4 deletions(-) diff --git a/packages/core/package-manager/src/Pnpm.js b/packages/core/package-manager/src/Pnpm.js index ef61ff2673d..20d465a1afb 100644 --- a/packages/core/package-manager/src/Pnpm.js +++ b/packages/core/package-manager/src/Pnpm.js @@ -2,6 +2,8 @@ import type {PackageInstaller, InstallerOptions} from './types'; +import path from 'path'; +import fs from 'fs'; import commandExists from 'command-exists'; import spawn from 'cross-spawn'; import logger from '@parcel/logger'; @@ -84,7 +86,10 @@ export class Pnpm implements PackageInstaller { }: InstallerOptions): Promise { let args = ['add', '--reporter', 'ndjson']; if (saveDev) { - args.push('-D', '-W'); + args.push('-D'); + } + if (fs.existsSync(path.join(cwd, '.pnpm_workspaces'))) { + args.push('-w'); } args = args.concat(modules.map(npmSpecifierFromModuleRequest)); @@ -148,9 +153,9 @@ export class Pnpm implements PackageInstaller { if (addedCount > 0 || removedCount > 0) { logger.log({ origin: '@parcel/package-manager', - message: `Added ${addedCount} and ${ - removedCount > 0 ? `removed ${removedCount}` : '' - } packages via pnpm`, + message: `Added ${addedCount} ${ + removedCount > 0 ? `and removed ${removedCount} ` : '' + }packages via pnpm`, }); } From 4a8ad179050a483b06c9aa17d035e37b3c2658d0 Mon Sep 17 00:00:00 2001 From: Niklas Mischkulnig <4586894+mischnic@users.noreply.github.com> Date: Fri, 24 Mar 2023 12:43:20 +0100 Subject: [PATCH 2/3] Check pnpm version --- packages/core/package-manager/src/Pnpm.js | 19 ++++++++++++++++--- packages/core/package-manager/src/Yarn.js | 5 +---- packages/core/package-manager/src/utils.js | 8 ++++++++ 3 files changed, 25 insertions(+), 7 deletions(-) diff --git a/packages/core/package-manager/src/Pnpm.js b/packages/core/package-manager/src/Pnpm.js index 20d465a1afb..932983feaee 100644 --- a/packages/core/package-manager/src/Pnpm.js +++ b/packages/core/package-manager/src/Pnpm.js @@ -11,7 +11,7 @@ import split from 'split2'; import JSONParseStream from './JSONParseStream'; import promiseFromProcess from './promiseFromProcess'; import {registerSerializableClass} from '@parcel/core'; -import {npmSpecifierFromModuleRequest} from './utils'; +import {exec, npmSpecifierFromModuleRequest} from './utils'; // $FlowFixMe import pkg from '../package.json'; @@ -64,6 +64,8 @@ type PNPMResults = {| |}; let hasPnpm: ?boolean; +let pnpmVersion: ?number; + export class Pnpm implements PackageInstaller { static async exists(): Promise { if (hasPnpm != null) { @@ -84,12 +86,23 @@ export class Pnpm implements PackageInstaller { cwd, saveDev = true, }: InstallerOptions): Promise { + if (pnpmVersion == null) { + let version = await exec('pnpm --version'); + pnpmVersion = parseInt(version.stdout, 10); + } + let args = ['add', '--reporter', 'ndjson']; if (saveDev) { args.push('-D'); } - if (fs.existsSync(path.join(cwd, '.pnpm_workspaces'))) { - args.push('-w'); + if (pnpmVersion >= 7) { + if (fs.existsSync(path.join(cwd, 'pnpm-workspace.yaml'))) { + // installs in workspace root (regardless of cwd) + args.push('-w'); + } + } else { + // ignores workspace root check + args.push('-W'); } args = args.concat(modules.map(npmSpecifierFromModuleRequest)); diff --git a/packages/core/package-manager/src/Yarn.js b/packages/core/package-manager/src/Yarn.js index 24d33e431f8..b541ecb3ca1 100644 --- a/packages/core/package-manager/src/Yarn.js +++ b/packages/core/package-manager/src/Yarn.js @@ -4,20 +4,17 @@ import type {PackageInstaller, InstallerOptions} from './types'; import commandExists from 'command-exists'; import spawn from 'cross-spawn'; -import {exec as _exec} from 'child_process'; -import {promisify} from 'util'; import logger from '@parcel/logger'; import split from 'split2'; import JSONParseStream from './JSONParseStream'; import promiseFromProcess from './promiseFromProcess'; import {registerSerializableClass} from '@parcel/core'; -import {npmSpecifierFromModuleRequest} from './utils'; +import {exec, npmSpecifierFromModuleRequest} from './utils'; // $FlowFixMe import pkg from '../package.json'; const YARN_CMD = 'yarn'; -const exec = promisify(_exec); type YarnStdOutMessage = | {| diff --git a/packages/core/package-manager/src/utils.js b/packages/core/package-manager/src/utils.js index 9d90f58c507..27a752cb67f 100644 --- a/packages/core/package-manager/src/utils.js +++ b/packages/core/package-manager/src/utils.js @@ -7,6 +7,14 @@ import type {FileSystem} from '@parcel/fs'; import invariant from 'assert'; import ThrowableDiagnostic from '@parcel/diagnostic'; import {resolveConfig} from '@parcel/utils'; +import {exec as _exec} from 'child_process'; +import {promisify} from 'util'; + +export const exec: ( + command: string, + options?: child_process$execOpts, +) => Promise<{|stdout: string | Buffer, stderr: string | Buffer|}> = + promisify(_exec); export function npmSpecifierFromModuleRequest( moduleRequest: ModuleRequest, From 56cefd8f92fbef41181a0a47139756bf2115f454 Mon Sep 17 00:00:00 2001 From: Niklas Mischkulnig <4586894+mischnic@users.noreply.github.com> Date: Fri, 24 Mar 2023 19:09:22 +0100 Subject: [PATCH 3/3] Invalidate resolvers after autoinstall --- packages/utils/node-resolver-core/src/Wrapper.js | 3 +++ 1 file changed, 3 insertions(+) diff --git a/packages/utils/node-resolver-core/src/Wrapper.js b/packages/utils/node-resolver-core/src/Wrapper.js index 05a308013d1..0e199457c54 100644 --- a/packages/utils/node-resolver-core/src/Wrapper.js +++ b/packages/utils/node-resolver-core/src/Wrapper.js @@ -281,6 +281,9 @@ export default class NodeResolver { }, ); + // Need to clear the resolver caches after installing the package + this.resolversByEnv.clear(); + // Re-resolve return this.resolve({ ...options,