mirror of
https://github.com/LukeHagar/vercel.git
synced 2025-12-06 12:57:46 +00:00
[cli] Use Builder importing logic from vc build in vc dev (#8485)
This makes `vc dev` utilize the same Builder installing and importing logic that `vc build` uses. So now the Builders will be installed locally on a per-project basis, rather than being installed to a shared global installation directory.
This commit is contained in:
@@ -1,4 +1,3 @@
|
||||
import ms from 'ms';
|
||||
import url, { URL } from 'url';
|
||||
import http from 'http';
|
||||
import fs from 'fs-extra';
|
||||
@@ -62,11 +61,6 @@ import { devRouter, getRoutesTypes } from './router';
|
||||
import getMimeType from './mime-type';
|
||||
import { executeBuild, getBuildMatches, shutdownBuilder } from './builder';
|
||||
import { generateErrorMessage, generateHttpStatusDescription } from './errors';
|
||||
import {
|
||||
installBuilders,
|
||||
updateBuilders,
|
||||
builderDirPromise,
|
||||
} from './builder-cache';
|
||||
|
||||
// HTML templates
|
||||
import errorTemplate from './templates/error';
|
||||
@@ -171,8 +165,6 @@ export default class DevServer {
|
||||
private vercelConfigWarning: boolean;
|
||||
private getVercelConfigPromise: Promise<VercelConfig> | null;
|
||||
private blockingBuildsPromise: Promise<void> | null;
|
||||
private updateBuildersPromise: Promise<void> | null;
|
||||
private updateBuildersTimeout: NodeJS.Timeout | undefined;
|
||||
private startPromise: Promise<void> | null;
|
||||
|
||||
private systemEnvValues: string[];
|
||||
@@ -211,7 +203,6 @@ export default class DevServer {
|
||||
this.vercelConfigWarning = false;
|
||||
this.getVercelConfigPromise = null;
|
||||
this.blockingBuildsPromise = null;
|
||||
this.updateBuildersPromise = null;
|
||||
this.startPromise = null;
|
||||
|
||||
this.watchAggregationId = null;
|
||||
@@ -493,33 +484,6 @@ export default class DevServer {
|
||||
);
|
||||
}
|
||||
|
||||
async invalidateBuildMatches(
|
||||
vercelConfig: VercelConfig,
|
||||
updatedBuilders: string[]
|
||||
): Promise<void> {
|
||||
if (updatedBuilders.length === 0) {
|
||||
this.output.debug('No builders were updated');
|
||||
return;
|
||||
}
|
||||
|
||||
// Delete any build matches that have the old builder required already
|
||||
for (const buildMatch of this.buildMatches.values()) {
|
||||
const {
|
||||
src,
|
||||
builderWithPkg: { package: pkg },
|
||||
} = buildMatch;
|
||||
if (isOfficialRuntime('static', pkg.name)) continue;
|
||||
if (pkg.name && updatedBuilders.includes(pkg.name)) {
|
||||
shutdownBuilder(buildMatch, this.output);
|
||||
this.buildMatches.delete(src);
|
||||
this.output.debug(`Invalidated build match for "${src}"`);
|
||||
}
|
||||
}
|
||||
|
||||
// Re-add the build matches that were just removed, but with the new builder
|
||||
await this.updateBuildMatches(vercelConfig);
|
||||
}
|
||||
|
||||
async getLocalEnv(fileName: string, base?: Env): Promise<Env> {
|
||||
// TODO: use the file watcher to only invalidate the env `dotfile`
|
||||
// once a change to the `fileName` occurs
|
||||
@@ -948,30 +912,8 @@ export default class DevServer {
|
||||
}
|
||||
}
|
||||
|
||||
const builders = new Set<string>(
|
||||
(vercelConfig.builds || [])
|
||||
.filter((b: Builder) => b.use)
|
||||
.map((b: Builder) => b.use)
|
||||
);
|
||||
|
||||
await installBuilders(builders, this.output);
|
||||
await this.updateBuildMatches(vercelConfig, true);
|
||||
|
||||
// Updating builders happens lazily, and any builders that were updated
|
||||
// get their "build matches" invalidated so that the new version is used.
|
||||
this.updateBuildersTimeout = setTimeout(() => {
|
||||
this.updateBuildersPromise = updateBuilders(builders, this.output)
|
||||
.then(updatedBuilders => {
|
||||
this.updateBuildersPromise = null;
|
||||
this.invalidateBuildMatches(vercelConfig, updatedBuilders);
|
||||
})
|
||||
.catch(err => {
|
||||
this.updateBuildersPromise = null;
|
||||
this.output.prettyError(err);
|
||||
this.output.debug(err.stack);
|
||||
});
|
||||
}, ms('30s'));
|
||||
|
||||
// Builders that do not define a `shouldServe()` function need to be
|
||||
// executed at boot-up time in order to get the initial assets and/or routes
|
||||
// that can be served by the builder.
|
||||
@@ -1047,16 +989,11 @@ export default class DevServer {
|
||||
* Shuts down the `vercel dev` server, and cleans up any temporary resources.
|
||||
*/
|
||||
async stop(exitCode?: number): Promise<void> {
|
||||
const { devProcess } = this;
|
||||
const { debug } = this.output;
|
||||
if (this.stopping) return;
|
||||
|
||||
this.stopping = true;
|
||||
|
||||
if (typeof this.updateBuildersTimeout !== 'undefined') {
|
||||
clearTimeout(this.updateBuildersTimeout);
|
||||
}
|
||||
|
||||
const { devProcess } = this;
|
||||
const { debug } = this.output;
|
||||
const ops: Promise<any>[] = [];
|
||||
|
||||
for (const match of this.buildMatches.values()) {
|
||||
@@ -1074,18 +1011,10 @@ export default class DevServer {
|
||||
ops.push(this.watcher.close());
|
||||
}
|
||||
|
||||
if (this.updateBuildersPromise) {
|
||||
debug(`Waiting for builders update to complete`);
|
||||
ops.push(this.updateBuildersPromise);
|
||||
}
|
||||
|
||||
for (const pid of this.devServerPids) {
|
||||
ops.push(this.killBuilderDevServer(pid));
|
||||
}
|
||||
|
||||
// Ensure that the builders module cache is created
|
||||
ops.push(builderDirPromise);
|
||||
|
||||
try {
|
||||
await Promise.all(ops);
|
||||
} catch (err: unknown) {
|
||||
@@ -1484,8 +1413,9 @@ export default class DevServer {
|
||||
// the middleware server for every HTTP request?
|
||||
const { envConfigs, files, devCacheDir, cwd: workPath } = this;
|
||||
try {
|
||||
startMiddlewareResult =
|
||||
await middleware.builderWithPkg.builder.startDevServer?.({
|
||||
const { builder } = middleware.builderWithPkg;
|
||||
if (builder.version === 3) {
|
||||
startMiddlewareResult = await builder.startDevServer?.({
|
||||
files,
|
||||
entrypoint: middleware.entrypoint,
|
||||
workPath,
|
||||
@@ -1499,6 +1429,7 @@ export default class DevServer {
|
||||
buildEnv: { ...envConfigs.buildEnv },
|
||||
},
|
||||
});
|
||||
}
|
||||
|
||||
if (startMiddlewareResult) {
|
||||
const { port, pid } = startMiddlewareResult;
|
||||
@@ -1911,8 +1842,8 @@ export default class DevServer {
|
||||
// up a single-serve dev HTTP server that vercel dev will proxy this HTTP request
|
||||
// to. Once the proxied request is finished, vercel dev shuts down the dev
|
||||
// server child process.
|
||||
const { builder, package: builderPkg } = match.builderWithPkg;
|
||||
if (typeof builder.startDevServer === 'function') {
|
||||
const { builder, pkg: builderPkg } = match.builderWithPkg;
|
||||
if (builder.version === 3 && typeof builder.startDevServer === 'function') {
|
||||
let devServerResult: StartDevServerResult = null;
|
||||
try {
|
||||
const { envConfigs, files, devCacheDir, cwd: workPath } = this;
|
||||
|
||||
Reference in New Issue
Block a user