[cli] Add node_modules/.bin to PATH instead of running npx/yarn run (#8890)

`runDevCommand()` assumes the dev command is an npm package and thus uses `npx` or `yarn run` to execute it. In the case of a Hugo-based app, there is no npm package, so we want spawn to find Hugo in the `PATH`. Then for Node-based apps, instead of `npx`, spawn should find the command since `node_modules/.bin` has been added to the `PATH`.

### Related Issues

> https://github.com/vercel/customer-issues/issues/871

Note: This PR is a recreation of https://github.com/vercel/vercel/pull/8864 because prettier changed a bunch of Hugo files, which was bloating the original PR.

### 📋 Checklist

<!--
  Please keep your PR as a Draft until the checklist is complete
-->

#### Tests

- [x] The code changed/added as part of this PR has been covered with tests
- [x] All tests pass locally with `yarn test-unit`

#### Code Review

- [ ] This PR has a concise title and thorough description useful to a reviewer
- [ ] Issue from task tracker has a link to this PR
This commit is contained in:
Chris Barber
2022-11-14 09:26:27 -06:00
committed by GitHub
parent b572ef5d71
commit f283b3b106
5 changed files with 68 additions and 31 deletions

View File

@@ -18,7 +18,6 @@ import directoryTemplate from 'serve-handler/src/directory';
import getPort from 'get-port';
import isPortReachable from 'is-port-reachable';
import deepEqual from 'fast-deep-equal';
import which from 'which';
import npa from 'npm-package-arg';
import type { ChildProcess } from 'child_process';
@@ -33,6 +32,7 @@ import {
Builder,
cloneEnv,
Env,
getNodeBinPath,
StartDevServerResult,
FileFsRef,
PackageJson,
@@ -2238,6 +2238,10 @@ export default class DevServer {
}
);
// add the node_modules/.bin directory to the PATH
const nodeBinPath = await getNodeBinPath({ cwd });
env.PATH = `${nodeBinPath}${path.delimiter}${env.PATH}`;
// This is necesary so that the dev command in the Project
// will work cross-platform (especially Windows).
let command = devCommand
@@ -2252,22 +2256,6 @@ export default class DevServer {
})}`
);
const isNpxAvailable = await which('npx')
.then(() => true)
.catch(() => false);
if (isNpxAvailable) {
command = `npx --no-install ${command}`;
} else {
const isYarnAvailable = await which('yarn')
.then(() => true)
.catch(() => false);
if (isYarnAvailable) {
command = `yarn run --silent ${command}`;
}
}
this.output.debug(`Spawning dev command: ${command}`);
const proxyPort = new RegExp(port.toString(), 'g');