mirror of
https://github.com/pnpm/pnpm.git
synced 2026-01-09 23:48:28 -05:00
fix: multiple Jest versions in a single workspace should work (#6138)
close #5176 close #6213
This commit is contained in:
6
.changeset/clean-chefs-approve.md
Normal file
6
.changeset/clean-chefs-approve.md
Normal file
@@ -0,0 +1,6 @@
|
||||
---
|
||||
"@pnpm/link-bins": patch
|
||||
"pnpm": patch
|
||||
---
|
||||
|
||||
Command shim should not set higher priority to the `node_modules/.pnpm/node_modules` directory through the `NODE_PATH` env variable, then the command's own `node_modules` directory [#5176](https://github.com/pnpm/pnpm/issues/5176).
|
||||
17
pkg-manager/core/test/fixtures/tooling-that-needs-node-path/.babelrc
vendored
Normal file
17
pkg-manager/core/test/fixtures/tooling-that-needs-node-path/.babelrc
vendored
Normal file
@@ -0,0 +1,17 @@
|
||||
{
|
||||
"presets": [
|
||||
[
|
||||
"env",
|
||||
{
|
||||
"targets": {
|
||||
"browsers": [
|
||||
"last 2 versions",
|
||||
"IE >= 9"
|
||||
]
|
||||
}
|
||||
}
|
||||
],
|
||||
"stage-0",
|
||||
"react"
|
||||
]
|
||||
}
|
||||
0
pkg-manager/core/test/fixtures/tooling-that-needs-node-path/index.es6.js
vendored
Normal file
0
pkg-manager/core/test/fixtures/tooling-that-needs-node-path/index.es6.js
vendored
Normal file
103
pkg-manager/core/test/install/setExtraNodePath.ts
Normal file
103
pkg-manager/core/test/install/setExtraNodePath.ts
Normal file
@@ -0,0 +1,103 @@
|
||||
import fs from 'fs'
|
||||
import path from 'path'
|
||||
import { preparePackages, tempDir } from '@pnpm/prepare'
|
||||
import { fixtures } from '@pnpm/test-fixtures'
|
||||
import {
|
||||
MutatedProject,
|
||||
mutateModules,
|
||||
install,
|
||||
} from '@pnpm/core'
|
||||
import { sync as loadJsonFile } from 'load-json-file'
|
||||
import { testDefaults } from '../utils'
|
||||
|
||||
const f = fixtures(__dirname)
|
||||
|
||||
test('jest CLI should print the right version when multiple instances of jest are used in a workspace', async () => {
|
||||
preparePackages([
|
||||
{
|
||||
location: 'project-1',
|
||||
package: { name: 'project-1' },
|
||||
},
|
||||
{
|
||||
location: 'project-2',
|
||||
package: { name: 'project-2' },
|
||||
},
|
||||
])
|
||||
const importers: MutatedProject[] = [
|
||||
{
|
||||
mutation: 'install',
|
||||
rootDir: path.resolve('project-1'),
|
||||
},
|
||||
{
|
||||
mutation: 'install',
|
||||
rootDir: path.resolve('project-2'),
|
||||
},
|
||||
]
|
||||
const allProjects = [
|
||||
{
|
||||
buildIndex: 0,
|
||||
manifest: {
|
||||
name: 'project-1',
|
||||
version: '1.0.0',
|
||||
scripts: {
|
||||
postinstall: 'jest --version | json-append output.json',
|
||||
},
|
||||
|
||||
dependencies: {
|
||||
jest: '27.5.1',
|
||||
'json-append': '1.1.1',
|
||||
},
|
||||
},
|
||||
rootDir: path.resolve('project-1'),
|
||||
},
|
||||
{
|
||||
buildIndex: 0,
|
||||
manifest: {
|
||||
name: 'project-2',
|
||||
version: '1.0.0',
|
||||
scripts: {
|
||||
postinstall: 'jest --version | json-append output.json',
|
||||
},
|
||||
|
||||
dependencies: {
|
||||
jest: '24.9.0',
|
||||
'json-append': '1.1.1',
|
||||
},
|
||||
},
|
||||
rootDir: path.resolve('project-2'),
|
||||
},
|
||||
]
|
||||
await mutateModules(importers, await testDefaults({
|
||||
allProjects,
|
||||
extendNodePath: true,
|
||||
fastUnpack: false,
|
||||
hoistPattern: '*',
|
||||
}))
|
||||
|
||||
{
|
||||
const [jestVersion] = loadJsonFile<string[]>('project-1/output.json')
|
||||
expect(jestVersion.trim()).toStrictEqual('27.5.1')
|
||||
}
|
||||
{
|
||||
const [jestVersion] = loadJsonFile<string[]>('project-2/output.json')
|
||||
expect(jestVersion.trim()).toStrictEqual('24.9.0')
|
||||
}
|
||||
})
|
||||
|
||||
test('drupal-js-build should find plugins inside the hidden node_modules directory', async () => {
|
||||
const tmp = tempDir()
|
||||
f.copy('tooling-that-needs-node-path', tmp)
|
||||
await install({
|
||||
dependencies: {
|
||||
'drupal-js-build': 'github:pnpm-e2e/drupal-js-build#f766801580f10543c24ba8bfa59046a776848097',
|
||||
},
|
||||
scripts: {
|
||||
prepare: 'drupal-js-build',
|
||||
},
|
||||
}, await testDefaults({
|
||||
extendNodePath: true,
|
||||
fastUnpack: false,
|
||||
hoistPattern: '*',
|
||||
}))
|
||||
expect(fs.existsSync(path.join(tmp, 'index.js'))).toBeTruthy()
|
||||
})
|
||||
@@ -1,4 +1,5 @@
|
||||
import { promises as fs, existsSync } from 'fs'
|
||||
import Module from 'module'
|
||||
import path from 'path'
|
||||
import { PnpmError } from '@pnpm/error'
|
||||
import { logger, globalWarn } from '@pnpm/logger'
|
||||
@@ -222,9 +223,18 @@ async function linkBin (cmd: CommandInfo, binsDir: string, opts?: LinkBinOptions
|
||||
}
|
||||
|
||||
try {
|
||||
let nodePath: string[] | undefined
|
||||
if (opts?.extraNodePaths?.length) {
|
||||
nodePath = []
|
||||
for (const modulesPath of await getBinNodePaths(cmd.path)) {
|
||||
if (opts.extraNodePaths.includes(modulesPath)) break
|
||||
nodePath.push(modulesPath)
|
||||
}
|
||||
nodePath.push(...opts.extraNodePaths)
|
||||
}
|
||||
await cmdShim(cmd.path, externalBinPath, {
|
||||
createPwshFile: cmd.makePowerShellShim,
|
||||
nodePath: opts?.extraNodePaths,
|
||||
nodePath,
|
||||
nodeExecPath: cmd.nodeExecPath,
|
||||
})
|
||||
} catch (err: any) { // eslint-disable-line
|
||||
@@ -253,6 +263,21 @@ function getExeExtension (): string {
|
||||
return cmdExtension ?? '.exe'
|
||||
}
|
||||
|
||||
async function getBinNodePaths (target: string): Promise<string[]> {
|
||||
const targetDir = path.dirname(target)
|
||||
try {
|
||||
const targetRealPath = await fs.realpath(targetDir)
|
||||
// @ts-expect-error
|
||||
return Module['_nodeModulePaths'](targetRealPath)
|
||||
} catch (err: any) { // eslint-disable-line
|
||||
if (err.code !== 'ENOENT') {
|
||||
throw err
|
||||
}
|
||||
// @ts-expect-error
|
||||
return Module['_nodeModulePaths'](targetDir)
|
||||
}
|
||||
}
|
||||
|
||||
async function safeReadPkgJson (pkgDir: string): Promise<DependencyManifest | null> {
|
||||
try {
|
||||
return await readPackageJsonFromDir(pkgDir) as DependencyManifest
|
||||
|
||||
Reference in New Issue
Block a user