mirror of
https://github.com/LukeHagar/vercel.git
synced 2025-12-08 21:07:46 +00:00
The `getNodeBinPath()` function is problematic because it assumes that commands are installed in the `node_modules` directory alongside the detected lockfile. This works fine the majority of the time, but ends up not being the case when using a monorepo that uses a package manager in "linked" mode (i.e. pnpm by default). Consider the following: ``` . ├── pnpm-lock.yaml ├── node_modules ├── blog │ ├── node_modules │ │ ├── hexo -> .pnpm/hexo@3.9.0/node_modules/hexo ``` In this setup, adding the root-level `node_modules/.bin` would not make the `hexo` command be visible in the `$PATH`. To solve this issue, the new `getNodeBinPaths()` function returns an array of all directories up to the specified `root`, which can then be placed into the `$PATH`. It's also more efficient (synchronous) since it does not need to scan for a lockfile anymore (the `root` needs to be specified explicitly). The new function is being used in `@vercel/next` and `@vercel/static-build`. The `traverseUpDirectories()` function from CLI was moved to `build-utils` to implement this function. Consequently, that makes the implementations of `walkParentDirs()` and `walkParentDirsMulti()` simpler, since it's using this generator now.
47 lines
1.7 KiB
TypeScript
Vendored
47 lines
1.7 KiB
TypeScript
Vendored
import { join, parse } from 'path';
|
|
import { getNodeBinPath } from '../src';
|
|
|
|
describe('Test `getNodeBinPath()`', () => {
|
|
it('should work with npm7', async () => {
|
|
const cwd = join(__dirname, 'fixtures', '20-npm-7');
|
|
const result = await getNodeBinPath({ cwd });
|
|
expect(result).toBe(join(cwd, 'node_modules', '.bin'));
|
|
});
|
|
|
|
it('should work with yarn', async () => {
|
|
const cwd = join(__dirname, 'fixtures', '19-yarn-v2');
|
|
const result = await getNodeBinPath({ cwd });
|
|
expect(result).toBe(join(cwd, 'node_modules', '.bin'));
|
|
});
|
|
|
|
it('should work with npm 6', async () => {
|
|
const cwd = join(__dirname, 'fixtures', '08-yarn-npm/with-npm');
|
|
const result = await getNodeBinPath({ cwd });
|
|
expect(result).toBe(join(cwd, 'node_modules', '.bin'));
|
|
});
|
|
|
|
it('should work with npm workspaces', async () => {
|
|
const cwd = join(__dirname, 'fixtures', '21-npm-workspaces/a');
|
|
const result = await getNodeBinPath({ cwd });
|
|
expect(result).toBe(join(cwd, '..', 'node_modules', '.bin'));
|
|
});
|
|
|
|
it('should work with pnpm', async () => {
|
|
const cwd = join(__dirname, 'fixtures', '22-pnpm');
|
|
const result = await getNodeBinPath({ cwd });
|
|
expect(result).toBe(join(cwd, 'node_modules', '.bin'));
|
|
});
|
|
|
|
it('should work with pnpm workspaces', async () => {
|
|
const cwd = join(__dirname, 'fixtures', '23-pnpm-workspaces/c');
|
|
const result = await getNodeBinPath({ cwd });
|
|
expect(result).toBe(join(cwd, '..', 'node_modules', '.bin'));
|
|
});
|
|
|
|
it('should fallback to cwd if no lockfile found', async () => {
|
|
const cwd = parse(process.cwd()).root;
|
|
const result = await getNodeBinPath({ cwd });
|
|
expect(result).toBe(join(cwd, 'node_modules', '.bin'));
|
|
});
|
|
});
|