[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

@@ -61,8 +61,13 @@ function fetchWithRetry(url, opts = {}) {
function createResolver() {
let resolver;
const p = new Promise(res => (resolver = res));
let rejector;
const p = new Promise((resolve, reject) => {
resolver = resolve;
rejector = reject;
});
p.resolve = resolver;
p.reject = rejector;
return p;
}
@@ -274,7 +279,13 @@ async function testFixture(directory, opts = {}, args = []) {
function testFixtureStdio(
directory,
fn,
{ expectedCode = 0, skipDeploy, isExample, projectSettings } = {}
{
expectedCode = 0,
skipDeploy,
isExample,
projectSettings,
readyTimeout = 0,
} = {}
) {
return async () => {
const nodeMajor = Number(process.versions.node.split('.')[0]);
@@ -385,6 +396,18 @@ function testFixtureStdio(
const readyResolver = createResolver();
const exitResolver = createResolver();
// By default, tests will wait 6 minutes for the dev server to be ready and
// perform the tests, however a `readyTimeout` can be used to reduce the
// wait time if the dev server is expected to fail to start or hang
let readyTimer = null;
if (readyTimeout > 0) {
readyTimer = setTimeout(() => {
readyResolver.reject(
new Error('Dev server timed out while waiting to be ready')
);
}, readyTimeout);
}
try {
let printedOutput = false;
@@ -424,6 +447,7 @@ function testFixtureStdio(
stderr += data;
if (stripAnsi(data).includes('Ready! Available at')) {
clearTimeout(readyTimer);
readyResolver.resolve();
}
@@ -507,5 +531,6 @@ module.exports = {
shouldSkip,
fixture,
fetch,
fetchWithRetry,
validateResponseHeaders,
};