Files
pnpm/cli/cli-utils/test/getConfig.test.ts
Zoltan Kochan de561a55fa fix: prefer .pnpmfile.mjs by default (#10683)
* fix: prefer .pnpmfile.mjs by default

* fix: handle ERR_MODULE_NOT_FOUND for missing optional .pnpmfile.mjs

Node's dynamic import() throws ERR_MODULE_NOT_FOUND (not MODULE_NOT_FOUND
like require()) when a file doesn't exist. This caused a hard error when
tryLoadDefaultPnpmfile was enabled and .pnpmfile.mjs was absent.

* fix: load only .pnpmfile.mjs when it exists, not both .mjs and .cjs

When both .pnpmfile.mjs and .pnpmfile.cjs exist, only the .mjs file
is now loaded. Previously both were loaded and their hooks combined.
Also adds .mjs support for config dependency plugins.
2026-03-01 17:00:33 +01:00

77 lines
2.3 KiB
TypeScript

/// <reference path="../../../__typings__/index.d.ts"/>
import fs from 'fs'
import path from 'path'
import { calcPnpmfilePathsOfPluginDeps, getConfig } from '@pnpm/cli-utils'
import { prepare } from '@pnpm/prepare'
import { jest } from '@jest/globals'
beforeEach(() => {
jest.spyOn(console, 'warn')
})
afterEach(() => {
jest.mocked(console.warn).mockRestore()
})
test('console a warning when the .npmrc has an env variable that does not exist', async () => {
prepare()
fs.writeFileSync('.npmrc', 'registry=${ENV_VAR_123}', 'utf8')
await getConfig({
json: false,
}, {
workspaceDir: '.',
excludeReporter: false,
rcOptionsTypes: {},
})
expect(console.warn).toHaveBeenCalledWith(expect.stringContaining('Failed to replace env in config: ${ENV_VAR_123}'))
})
describe('calcPnpmfilePathsOfPluginDeps', () => {
test('yields pnpmfile.mjs when it exists', () => {
const tmpDir = fs.mkdtempSync(path.join(import.meta.dirname, '.tmp-'))
try {
const pluginDir = path.join(tmpDir, 'pnpm-plugin-foo')
fs.mkdirSync(pluginDir, { recursive: true })
fs.writeFileSync(path.join(pluginDir, 'pnpmfile.mjs'), '')
fs.writeFileSync(path.join(pluginDir, 'pnpmfile.cjs'), '')
const paths = [...calcPnpmfilePathsOfPluginDeps(tmpDir, { 'pnpm-plugin-foo': '1.0.0' })]
expect(paths).toEqual([path.join(pluginDir, 'pnpmfile.mjs')])
} finally {
fs.rmSync(tmpDir, { recursive: true })
}
})
test('falls back to pnpmfile.cjs when pnpmfile.mjs does not exist', () => {
const tmpDir = fs.mkdtempSync(path.join(import.meta.dirname, '.tmp-'))
try {
const pluginDir = path.join(tmpDir, 'pnpm-plugin-foo')
fs.mkdirSync(pluginDir, { recursive: true })
fs.writeFileSync(path.join(pluginDir, 'pnpmfile.cjs'), '')
const paths = [...calcPnpmfilePathsOfPluginDeps(tmpDir, { 'pnpm-plugin-foo': '1.0.0' })]
expect(paths).toEqual([path.join(pluginDir, 'pnpmfile.cjs')])
} finally {
fs.rmSync(tmpDir, { recursive: true })
}
})
})
test('hoist: false removes hoistPattern', async () => {
prepare()
const config = await getConfig({
hoist: false,
}, {
workspaceDir: '.',
excludeReporter: false,
rcOptionsTypes: {},
})
expect(config.hoist).toBe(false)
expect(config.hoistPattern).toBeUndefined()
})