Compare commits

..

11 Commits

Author SHA1 Message Date
Steven
fb4f477325 Publish Stable
- vercel@27.0.2
 - @vercel/fs-detectors@1.0.2
 - @vercel/node@2.4.2
2022-07-11 16:21:30 -04:00
P.B. To
016bff848e [fs-detectors] process detectFramework in parallel (#8128)
The Vercel API's `detect-framework` API contacts GitHub's API using its own file adapter. 

However, currently the `detectFramework` function in the Vercel CLI (on which the API depends) calls the file system adapter in series using a `for` loop. This results in large amounts of lag when in a networked situation such as calling GitHub's API as each API call takes a couple hundred milliseconds.

I propose changing `detectFramework` to process the directories it scans in parallel.

### 📋 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

- [x] This PR has a concise title and thorough description useful to a reviewer
- [x] Issue from task tracker has a link to this PR
2022-07-11 20:16:04 +00:00
Steven
183e411f7c [cli] Remove DEBUG=corepack env var (#8131)
This debug log was originally added in #7871 because corepack has no output by default. In particular, it was nice to see the first deployment was not stalled when the package manager is being installed.

That being said, this gets noisy really fast because cache detections also print a log line.
For example, here's a deployment that prints 3 times:

```
Detected ENABLE_EXPERIMENTAL_COREPACK=1 and "npm@8.10.0" in package.json
Running "install" command: `npm install --prefix=.. --no-audit --engine-strict=false`...
2022-07-11T18:27:00.696Z corepack Reusing npm@8.10.0
356 packages are looking for funding
Running "npm run vercel-build"
2022-07-11T18:27:06.664Z corepack Reusing npm@8.10.0
> front@0.0.0 vercel-build
> npm run buildonly && npm run build:rss
2022-07-11T18:27:07.088Z corepack Reusing npm@8.10.0
> front@0.0.0 buildonly
> next build
```

I think its best to let users add this env var themselves if they want to debug what corepack is doing, so this PR removes that environment variable.
2022-07-11 19:31:04 +00:00
Sean Massa
070e300148 [node] add links to edge error messages (#8048)
Add links to some Edge errors.

---

Follow up to: https://github.com/vercel/vercel/pull/8007
2022-07-11 18:50:15 +00:00
Steven
cbdf9b4a88 [cli] Fix beta label (#8129)
This PR is a follow up to #7991 which incorrectly used a the empty string instead of empty array

- Maybe related to #8125
2022-07-11 18:05:36 +00:00
Steven
ec9b55dc81 Publish Stable
- vercel@27.0.1
 - @vercel/remix@1.0.7
2022-07-10 15:04:09 -04:00
Leon Salsiccia
06829bc21a [remix] fix monorepo support (#8077)
Co-authored-by: Steven <steven@ceriously.com>
2022-07-10 13:28:39 -04:00
Matthew Stanciu
628071f659 [cli] Debug log error messages in create-git-meta (#8112)
This is a follow-up to #8094 which debug logs errors.

### 📋 Checklist

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

#### Tests

- [ ] The code changed/added as part of this PR has been covered with tests
- [ ] 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
2022-07-08 19:30:28 +00:00
Matthew Stanciu
5a7461dfe3 [cli] Explicitly use vc project vs. vc projects (#8113)
This is a follow-up to #8091 which:

- Makes `vc project` the default command, with `vc projects` aliased to `vc project` (previously it was not clear in the code which one was the "real" command)
- Makes some helper names for `ls` more specific

### 📋 Checklist

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

#### Tests

- [ ] The code changed/added as part of this PR has been covered with tests
- [ ] 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
2022-07-08 18:56:35 +00:00
Sean Massa
599f8f675c [tests] remove commented code (#8109)
Removes a leftover commented line.
2022-07-08 16:52:55 +00:00
Steven
0a8bc494fc [tests] Try building with ENABLE_VC_BUILD (#8110)
This will dogfood `vc build` which happens to improve this deployment time from 4 min down to 2 min.
2022-07-08 12:30:03 -04:00
23 changed files with 130 additions and 94 deletions

View File

@@ -5,7 +5,8 @@
"description": "API for the vercel/vercel repo", "description": "API for the vercel/vercel repo",
"main": "index.js", "main": "index.js",
"scripts": { "scripts": {
"vercel-build": "node ../utils/run.js build all" "//TODO": "We should add this pkg to yarn workspaces",
"vercel-build": "cd .. && yarn install && yarn vercel-build"
}, },
"dependencies": { "dependencies": {
"@sentry/node": "5.11.1", "@sentry/node": "5.11.1",

View File

@@ -1,6 +1,6 @@
{ {
"name": "vercel", "name": "vercel",
"version": "27.0.0", "version": "27.0.2",
"preferGlobal": true, "preferGlobal": true,
"license": "Apache-2.0", "license": "Apache-2.0",
"description": "The command-line interface for Vercel", "description": "The command-line interface for Vercel",
@@ -46,10 +46,10 @@
"@vercel/go": "2.0.5", "@vercel/go": "2.0.5",
"@vercel/hydrogen": "0.0.2", "@vercel/hydrogen": "0.0.2",
"@vercel/next": "3.1.4", "@vercel/next": "3.1.4",
"@vercel/node": "2.4.1", "@vercel/node": "2.4.2",
"@vercel/python": "3.0.5", "@vercel/python": "3.0.5",
"@vercel/redwood": "1.0.6", "@vercel/redwood": "1.0.6",
"@vercel/remix": "1.0.6", "@vercel/remix": "1.0.7",
"@vercel/ruby": "1.3.13", "@vercel/ruby": "1.3.13",
"@vercel/static-build": "1.0.5", "@vercel/static-build": "1.0.5",
"update-notifier": "5.1.0" "update-notifier": "5.1.0"
@@ -98,7 +98,7 @@
"@types/yauzl-promise": "2.1.0", "@types/yauzl-promise": "2.1.0",
"@vercel/client": "12.1.0", "@vercel/client": "12.1.0",
"@vercel/frameworks": "1.1.0", "@vercel/frameworks": "1.1.0",
"@vercel/fs-detectors": "1.0.1", "@vercel/fs-detectors": "1.0.2",
"@vercel/ncc": "0.24.0", "@vercel/ncc": "0.24.0",
"@zeit/fun": "0.11.2", "@zeit/fun": "0.11.2",
"@zeit/source-map-support": "0.6.2", "@zeit/source-map-support": "0.6.2",

View File

@@ -336,8 +336,7 @@ export default async function main(client: Client): Promise<number> {
const buildResults: Map<Builder, BuildResult> = new Map(); const buildResults: Map<Builder, BuildResult> = new Map();
const overrides: PathOverride[] = []; const overrides: PathOverride[] = [];
const repoRootPath = cwd; const repoRootPath = cwd;
const rootPackageJsonPath = repoRootPath || workPath; const corepackShimDir = await initCorepack({ repoRootPath });
const corepackShimDir = await initCorepack({ cwd, rootPackageJsonPath });
for (const build of builds) { for (const build of builds) {
if (typeof build.src !== 'string') continue; if (typeof build.src !== 'string') continue;

View File

@@ -25,8 +25,8 @@ export default new Map([
['logout', 'logout'], ['logout', 'logout'],
['logs', 'logs'], ['logs', 'logs'],
['ls', 'list'], ['ls', 'list'],
['project', 'projects'], ['project', 'project'],
['projects', 'projects'], ['projects', 'project'],
['pull', 'pull'], ['pull', 'pull'],
['remove', 'remove'], ['remove', 'remove'],
['rm', 'remove'], ['rm', 'remove'],

View File

@@ -173,7 +173,7 @@ const main = async () => {
const targetOrSubcommand = argv._[2]; const targetOrSubcommand = argv._[2];
// Currently no beta commands - add here as needed // Currently no beta commands - add here as needed
const betaCommands: string[] = ['']; const betaCommands: string[] = [];
if (betaCommands.includes(targetOrSubcommand)) { if (betaCommands.includes(targetOrSubcommand)) {
console.log( console.log(
`${chalk.grey( `${chalk.grey(
@@ -653,7 +653,7 @@ const main = async () => {
case 'logout': case 'logout':
func = require('./commands/logout').default; func = require('./commands/logout').default;
break; break;
case 'projects': case 'project':
func = require('./commands/project').default; func = require('./commands/project').default;
break; break;
case 'pull': case 'pull':

View File

@@ -6,11 +6,9 @@ import { VERCEL_DIR } from '../projects/link';
import readJSONFile from '../read-json-file'; import readJSONFile from '../read-json-file';
export async function initCorepack({ export async function initCorepack({
cwd, repoRootPath,
rootPackageJsonPath,
}: { }: {
cwd: string; repoRootPath: string;
rootPackageJsonPath: string;
}): Promise<string | null> { }): Promise<string | null> {
if (process.env.ENABLE_EXPERIMENTAL_COREPACK !== '1') { if (process.env.ENABLE_EXPERIMENTAL_COREPACK !== '1') {
// Since corepack is experimental, we need to exit early // Since corepack is experimental, we need to exit early
@@ -18,7 +16,7 @@ export async function initCorepack({
return null; return null;
} }
const pkg = await readJSONFile<PackageJson>( const pkg = await readJSONFile<PackageJson>(
join(rootPackageJsonPath, 'package.json') join(repoRootPath, 'package.json')
); );
if (pkg instanceof CantParseJSONFile) { if (pkg instanceof CantParseJSONFile) {
console.warn( console.warn(
@@ -32,16 +30,13 @@ export async function initCorepack({
console.log( console.log(
`Detected ENABLE_EXPERIMENTAL_COREPACK=1 and "${pkg.packageManager}" in package.json` `Detected ENABLE_EXPERIMENTAL_COREPACK=1 and "${pkg.packageManager}" in package.json`
); );
const corepackRootDir = join(cwd, VERCEL_DIR, 'cache', 'corepack'); const corepackRootDir = join(repoRootPath, VERCEL_DIR, 'cache', 'corepack');
const corepackHomeDir = join(corepackRootDir, 'home'); const corepackHomeDir = join(corepackRootDir, 'home');
const corepackShimDir = join(corepackRootDir, 'shim'); const corepackShimDir = join(corepackRootDir, 'shim');
await fs.mkdirp(corepackHomeDir); await fs.mkdirp(corepackHomeDir);
await fs.mkdirp(corepackShimDir); await fs.mkdirp(corepackShimDir);
process.env.COREPACK_HOME = corepackHomeDir; process.env.COREPACK_HOME = corepackHomeDir;
process.env.PATH = `${corepackShimDir}${delimiter}${process.env.PATH}`; process.env.PATH = `${corepackShimDir}${delimiter}${process.env.PATH}`;
process.env.DEBUG = process.env.DEBUG
? `corepack,${process.env.DEBUG}`
: 'corepack';
const pkgManagerName = pkg.packageManager.split('@')[0]; const pkgManagerName = pkg.packageManager.split('@')[0];
// We must explicitly call `corepack enable npm` since `corepack enable` // We must explicitly call `corepack enable npm` since `corepack enable`
// doesn't work with npm. See https://github.com/nodejs/corepack/pull/24 // doesn't work with npm. See https://github.com/nodejs/corepack/pull/24
@@ -72,11 +67,4 @@ export function cleanupCorepack(corepackShimDir: string) {
'' ''
); );
} }
if (process.env.DEBUG) {
if (process.env.DEBUG === 'corepack') {
delete process.env.DEBUG;
} else {
process.env.DEBUG = process.env.DEBUG.replace('corepack,', '');
}
}
} }

View File

@@ -9,11 +9,11 @@ import { Output } from '../output';
export function isDirty(directory: string, output: Output): Promise<boolean> { export function isDirty(directory: string, output: Output): Promise<boolean> {
return new Promise(resolve => { return new Promise(resolve => {
exec('git status -s', { cwd: directory }, function (err, stdout, stderr) { exec('git status -s', { cwd: directory }, function (err, stdout, stderr) {
if (err) return resolve(false); let debugMessage = `Failed to determine if Git repo has been modified:`;
if (stderr) { if (err || stderr) {
output.debug( if (err) debugMessage += `\n${err}`;
`Failed to determine if git repo has been modified: ${stderr.trim()}` if (stderr) debugMessage += `\n${stderr.trim()}`;
); output.debug(debugMessage);
return resolve(false); return resolve(false);
} }
resolve(stdout.trim().length > 0); resolve(stdout.trim().length > 0);
@@ -64,7 +64,10 @@ export async function createGitMeta(
return; return;
} }
const [commit, dirty] = await Promise.all([ const [commit, dirty] = await Promise.all([
getLastCommit(directory).catch(() => { getLastCommit(directory).catch(err => {
output.debug(
`Failed to get last commit. The directory is likely not a Git repo, there are no latest commits, or it is corrupted.\n${err}`
);
return; return;
}), }),
isDirty(directory, output), isDirty(directory, output),

View File

@@ -1,4 +1,4 @@
export function getDataFromIntro(output: string): { export function pluckIdentifiersFromDeploymentList(output: string): {
project: string | undefined; project: string | undefined;
org: string | undefined; org: string | undefined;
} { } {
@@ -11,7 +11,7 @@ export function getDataFromIntro(output: string): {
}; };
} }
export function parseTable(output: string): string[] { export function parseSpacedTableRow(output: string): string[] {
return output return output
.trim() .trim()
.replace(/ {1} +/g, ',') .replace(/ {1} +/g, ',')

View File

@@ -0,0 +1,23 @@
import { MockClient } from '../mocks/client';
export function readOutputStream(
client: MockClient,
length: number = 3
): Promise<string> {
return new Promise((resolve, reject) => {
const chunks: Buffer[] = [];
const timeout = setTimeout(() => {
reject();
}, 3000);
client.stderr.resume();
client.stderr.on('data', chunk => {
chunks.push(chunk);
if (chunks.length === length) {
clearTimeout(timeout);
resolve(chunks.toString().replace(/,/g, ''));
}
});
client.stderr.on('error', reject);
});
}

View File

@@ -1323,12 +1323,7 @@ test('[vc projects] should create a project successfully', async t => {
Math.random().toString(36).split('.')[1] Math.random().toString(36).split('.')[1]
}`; }`;
const vc = execa(binaryPath, [ const vc = execa(binaryPath, ['project', 'add', projectName, ...defaultArgs]);
'projects',
'add',
projectName,
...defaultArgs,
]);
await waitForPrompt(vc, chunk => await waitForPrompt(vc, chunk =>
chunk.includes(`Success! Project ${projectName} added`) chunk.includes(`Success! Project ${projectName} added`)
@@ -1339,7 +1334,7 @@ test('[vc projects] should create a project successfully', async t => {
// creating the same project again should succeed // creating the same project again should succeed
const vc2 = execa(binaryPath, [ const vc2 = execa(binaryPath, [
'projects', 'project',
'add', 'add',
projectName, projectName,
...defaultArgs, ...defaultArgs,

View File

@@ -35,7 +35,6 @@ export class MockClient extends Client {
scenario: Scenario; scenario: Scenario;
mockServer?: Server; mockServer?: Server;
private app: Express; private app: Express;
private mockOutput: jest.Mock<void, Parameters<Output['print']>>;
constructor() { constructor() {
super({ super({
@@ -53,13 +52,6 @@ export class MockClient extends Client {
output: new Output(new PassThrough()), output: new Output(new PassThrough()),
}); });
this.mockOutput = jest.fn();
const _print = this.output.print.bind(this.output);
this.output.print = s => {
_print(s);
this.mockOutput(s);
};
this.app = express(); this.app = express();
this.app.use(express.json()); this.app.use(express.json());
@@ -99,13 +91,7 @@ export class MockClient extends Client {
this._createPromptModule(); this._createPromptModule();
this.mockOutput.mockReset();
this.output = new Output(this.stderr); this.output = new Output(this.stderr);
const _print = this.output.print.bind(this.output);
this.output.print = s => {
_print(s);
this.mockOutput(s);
};
this.argv = []; this.argv = [];
this.authConfig = {}; this.authConfig = {};
@@ -115,10 +101,6 @@ export class MockClient extends Client {
this.scenario = Router(); this.scenario = Router();
} }
get outputBuffer() {
return this.mockOutput.mock.calls.map(c => c[0]).join('');
}
async startMockServer() { async startMockServer() {
this.mockServer = createServer(this.app); this.mockServer = createServer(this.app);
await listen(this.mockServer, 0); await listen(this.mockServer, 0);

View File

@@ -25,8 +25,6 @@ type GetMatcherType<TP, TResult> = TP extends PromiseFunction
? (...args: Tail<Parameters<TP>>) => TResult ? (...args: Tail<Parameters<TP>>) => TResult
: TP; : TP;
//type T = GetMatcherType<typeof matchers['toOutput'], void>;
type GetMatchersType<TMatchers, TResult> = { type GetMatchersType<TMatchers, TResult> = {
[P in keyof TMatchers]: GetMatcherType<TMatchers[P], TResult>; [P in keyof TMatchers]: GetMatcherType<TMatchers[P], TResult>;
}; };

View File

@@ -5,7 +5,11 @@ import { join } from 'path';
import { useTeams } from '../../mocks/team'; import { useTeams } from '../../mocks/team';
import { defaultProject, useProject } from '../../mocks/project'; import { defaultProject, useProject } from '../../mocks/project';
import { useDeployment } from '../../mocks/deployment'; import { useDeployment } from '../../mocks/deployment';
import { parseTable, getDataFromIntro } from '../../helpers/parse-table'; import { readOutputStream } from '../../helpers/read-output-stream';
import {
parseSpacedTableRow,
pluckIdentifiersFromDeploymentList,
} from '../../helpers/parse-table';
const fixture = (name: string) => const fixture = (name: string) =>
join(__dirname, '../../fixtures/unit/commands/list', name); join(__dirname, '../../fixtures/unit/commands/list', name);
@@ -31,10 +35,11 @@ describe('list', () => {
await list(client); await list(client);
const [line0, , line2, line3] = client.outputBuffer.split('\n'); const output = await readOutputStream(client);
const { org } = getDataFromIntro(line0);
const header: string[] = parseTable(line2); const { org } = pluckIdentifiersFromDeploymentList(output.split('\n')[0]);
const data: string[] = parseTable(line3); const header: string[] = parseSpacedTableRow(output.split('\n')[2]);
const data: string[] = parseSpacedTableRow(output.split('\n')[3]);
data.splice(2, 1); data.splice(2, 1);
expect(org).toEqual(team[0].slug); expect(org).toEqual(team[0].slug);
@@ -72,10 +77,11 @@ describe('list', () => {
client.setArgv(deployment.name); client.setArgv(deployment.name);
await list(client); await list(client);
const [line0, , line2, line3] = client.outputBuffer.split('\n'); const output = await readOutputStream(client);
const { org } = getDataFromIntro(line0);
const header: string[] = parseTable(line2); const { org } = pluckIdentifiersFromDeploymentList(output.split('\n')[0]);
const data: string[] = parseTable(line3); const header: string[] = parseSpacedTableRow(output.split('\n')[2]);
const data: string[] = parseSpacedTableRow(output.split('\n')[3]);
data.splice(2, 1); data.splice(2, 1);
expect(org).toEqual(teamSlug); expect(org).toEqual(teamSlug);

View File

@@ -4,9 +4,13 @@ import { useTeams } from '../../mocks/team';
import { defaultProject, useProject } from '../../mocks/project'; import { defaultProject, useProject } from '../../mocks/project';
import { client } from '../../mocks/client'; import { client } from '../../mocks/client';
import { Project } from '../../../src/types'; import { Project } from '../../../src/types';
import { getDataFromIntro, parseTable } from '../../helpers/parse-table'; import { readOutputStream } from '../../helpers/read-output-stream';
import {
pluckIdentifiersFromDeploymentList,
parseSpacedTableRow,
} from '../../helpers/parse-table';
describe('projects', () => { describe('project', () => {
describe('list', () => { describe('list', () => {
it('should list deployments under a user', async () => { it('should list deployments under a user', async () => {
const user = useUser(); const user = useUser();
@@ -17,10 +21,10 @@ describe('projects', () => {
client.setArgv('project', 'ls'); client.setArgv('project', 'ls');
await projects(client); await projects(client);
const [line0, , line2, line3] = client.outputBuffer.split('\n'); const output = await readOutputStream(client, 2);
const { org } = getDataFromIntro(line0); const { org } = pluckIdentifiersFromDeploymentList(output.split('\n')[0]);
const header: string[] = parseTable(line2); const header: string[] = parseSpacedTableRow(output.split('\n')[2]);
const data: string[] = parseTable(line3); const data: string[] = parseSpacedTableRow(output.split('\n')[3]);
data.pop(); data.pop();
expect(org).toEqual(user.username); expect(org).toEqual(user.username);
@@ -38,10 +42,10 @@ describe('projects', () => {
client.setArgv('project', 'ls'); client.setArgv('project', 'ls');
await projects(client); await projects(client);
const [line0, , line2, line3] = client.outputBuffer.split('\n'); const output = await readOutputStream(client, 2);
const { org } = getDataFromIntro(line0); const { org } = pluckIdentifiersFromDeploymentList(output.split('\n')[0]);
const header: string[] = parseTable(line2); const header: string[] = parseSpacedTableRow(output.split('\n')[2]);
const data: string[] = parseTable(line3); const data: string[] = parseSpacedTableRow(output.split('\n')[3]);
data.pop(); data.pop();
expect(org).toEqual(team[0].slug); expect(org).toEqual(team[0].slug);

View File

@@ -135,7 +135,15 @@ describe('createGitMeta', () => {
await fs.copy(directory, tmpDir); await fs.copy(directory, tmpDir);
await fs.rename(join(tmpDir, 'git'), join(tmpDir, '.git')); await fs.rename(join(tmpDir, 'git'), join(tmpDir, '.git'));
client.output.debugEnabled = true;
const data = await createGitMeta(tmpDir, client.output); const data = await createGitMeta(tmpDir, client.output);
await expect(client.stderr).toOutput(
`Failed to get last commit. The directory is likely not a Git repo, there are no latest commits, or it is corrupted.`
);
await expect(client.stderr).toOutput(
`Failed to determine if Git repo has been modified:`
);
expect(data).toBeUndefined(); expect(data).toBeUndefined();
} finally { } finally {
await fs.remove(tmpDir); await fs.remove(tmpDir);

View File

@@ -1,6 +1,6 @@
{ {
"name": "@vercel/fs-detectors", "name": "@vercel/fs-detectors",
"version": "1.0.1", "version": "1.0.2",
"description": "Vercel filesystem detectors", "description": "Vercel filesystem detectors",
"main": "./dist/index.js", "main": "./dist/index.js",
"types": "./dist/index.d.ts", "types": "./dist/index.d.ts",

View File

@@ -80,11 +80,13 @@ export async function detectFramework({
fs, fs,
frameworkList, frameworkList,
}: DetectFrameworkOptions): Promise<string | null> { }: DetectFrameworkOptions): Promise<string | null> {
for (const framework of frameworkList) { const result = await Promise.all(
if (await matches(fs, framework)) { frameworkList.map(async frameworkMatch => {
return framework.slug; if (await matches(fs, frameworkMatch)) {
} return frameworkMatch.slug;
} }
return null;
return null; })
);
return result.find(res => res !== null) ?? null;
} }

View File

@@ -252,6 +252,19 @@ describe('DetectorFilesystem', () => {
expect(await detectFramework({ fs, frameworkList })).toBe('nextjs'); expect(await detectFramework({ fs, frameworkList })).toBe('nextjs');
}); });
it('Detect frameworks based on ascending order in framework list', async () => {
const fs = new VirtualFilesystem({
'package.json': JSON.stringify({
dependencies: {
next: '9.0.0',
gatsby: '4.18.0',
},
}),
});
expect(await detectFramework({ fs, frameworkList })).toBe('nextjs');
});
it('Detect Nuxt.js', async () => { it('Detect Nuxt.js', async () => {
const fs = new VirtualFilesystem({ const fs = new VirtualFilesystem({
'package.json': JSON.stringify({ 'package.json': JSON.stringify({

View File

@@ -1,6 +1,6 @@
{ {
"name": "@vercel/node", "name": "@vercel/node",
"version": "2.4.1", "version": "2.4.2",
"license": "MIT", "license": "MIT",
"main": "./dist/index", "main": "./dist/index",
"homepage": "https://vercel.com/docs/runtimes#official-runtimes/node-js", "homepage": "https://vercel.com/docs/runtimes#official-runtimes/node-js",

View File

@@ -193,7 +193,7 @@ async function compileUserCode(entrypoint: string) {
let edgeHandler = module.exports.default; let edgeHandler = module.exports.default;
if (!edgeHandler) { if (!edgeHandler) {
throw new Error('No default export was found. Add a default export to handle requests.'); throw new Error('No default export was found. Add a default export to handle requests. Learn more: https://vercel.link/creating-edge-middleware');
} }
let response = await edgeHandler(event.request, event); let response = await edgeHandler(event.request, event);
@@ -305,7 +305,7 @@ function parseRuntime(
throw new Error( throw new Error(
`Invalid function runtime "${runtime}" for "${entrypoint}". Valid runtimes are: ${JSON.stringify( `Invalid function runtime "${runtime}" for "${entrypoint}". Valid runtimes are: ${JSON.stringify(
validRuntimes validRuntimes
)}` )}. Learn more: https://vercel.link/creating-edge-functions`
); );
} }

View File

@@ -1,6 +1,6 @@
{ {
"name": "@vercel/remix", "name": "@vercel/remix",
"version": "1.0.6", "version": "1.0.7",
"license": "MIT", "license": "MIT",
"main": "./dist/index.js", "main": "./dist/index.js",
"homepage": "https://vercel.com/docs", "homepage": "https://vercel.com/docs",

View File

@@ -187,6 +187,17 @@ export const build: BuildV2 = async ({
// Explicit directory path the server output will be // Explicit directory path the server output will be
serverBuildPath = join(remixConfig.serverBuildDirectory, 'index.js'); serverBuildPath = join(remixConfig.serverBuildDirectory, 'index.js');
} }
// Also check for whether were in a monorepo.
// If we are, prepend the app root directory from config onto the build path.
// e.g. `/apps/my-remix-app/api/index.js`
const isMonorepo = repoRootPath && repoRootPath !== workPath;
if (isMonorepo && config.projectSettings?.rootDirectory) {
serverBuildPath = join(
config.projectSettings.rootDirectory,
serverBuildPath
);
}
} catch (err: any) { } catch (err: any) {
// Ignore error if `remix.config.js` does not exist // Ignore error if `remix.config.js` does not exist
if (err.code !== 'MODULE_NOT_FOUND') throw err; if (err.code !== 'MODULE_NOT_FOUND') throw err;
@@ -196,6 +207,7 @@ export const build: BuildV2 = async ({
glob('**', join(entrypointFsDirname, 'public')), glob('**', join(entrypointFsDirname, 'public')),
createRenderFunction( createRenderFunction(
entrypointFsDirname, entrypointFsDirname,
repoRootPath,
serverBuildPath, serverBuildPath,
needsHandler, needsHandler,
nodeVersion nodeVersion
@@ -230,6 +242,7 @@ function hasScript(scriptName: string, pkg: PackageJson | null) {
} }
async function createRenderFunction( async function createRenderFunction(
entrypointDir: string,
rootDir: string, rootDir: string,
serverBuildPath: string, serverBuildPath: string,
needsHandler: boolean, needsHandler: boolean,
@@ -250,6 +263,7 @@ async function createRenderFunction(
// Trace the handler with `@vercel/nft` // Trace the handler with `@vercel/nft`
const trace = await nodeFileTrace([handlerPath], { const trace = await nodeFileTrace([handlerPath], {
base: rootDir, base: rootDir,
processCwd: entrypointDir,
}); });
for (const warning of trace.warnings) { for (const warning of trace.warnings) {

View File

@@ -20,7 +20,7 @@
], ],
"build": { "build": {
"env": { "env": {
"ENABLE_FILE_SYSTEM_API": "1" "ENABLE_VC_BUILD": "1"
} }
}, },
"github": { "github": {