From 4b67d2afd3a2d4be188a7313b3fe4ea5c07907b6 Mon Sep 17 00:00:00 2001 From: Charles Lyding <19598772+clydin@users.noreply.github.com> Date: Thu, 7 Sep 2023 10:13:26 -0400 Subject: [PATCH] perf(@angular-devkit/build-angular): use single JS transformer instance during dev-server prebundling By setting up a single instance of the `JavaTransformer`, the Vite-based development server will now have a fixed and controllable number of worker threads available to process prebundling requests. This avoids a potentially large number of initial worker threads when a new application with a large number of dependencies is first used with the development server. This is particularly beneficial for web container setups which may not be able to efficiently handle the number of workers. --- .../src/builders/dev-server/vite-server.ts | 38 ++++++++++--------- 1 file changed, 20 insertions(+), 18 deletions(-) diff --git a/packages/angular_devkit/build_angular/src/builders/dev-server/vite-server.ts b/packages/angular_devkit/build_angular/src/builders/dev-server/vite-server.ts index 4ff6d7e2565d..d5917db82ccd 100644 --- a/packages/angular_devkit/build_angular/src/builders/dev-server/vite-server.ts +++ b/packages/angular_devkit/build_angular/src/builders/dev-server/vite-server.ts @@ -65,6 +65,15 @@ export async function* serveWithVite( serverOptions.servePath = browserOptions.baseHref; } + // Setup the prebundling transformer that will be shared across Vite prebundling requests + const prebundleTransformer = new JavaScriptTransformer( + // Always enable JIT linking to support applications built with and without AOT. + // In a development environment the additional scope information does not + // have a negative effect unlike production where final output size is relevant. + { sourcemap: true, jit: true }, + 1, + ); + // dynamically import Vite for ESM compatibility const { createServer, normalizePath } = await import('vite'); @@ -99,6 +108,7 @@ export async function* serveWithVite( browserOptions.preserveSymlinks, browserOptions.externalDependencies, !!browserOptions.ssr, + prebundleTransformer, ); server = await createServer(serverConfiguration); @@ -114,14 +124,14 @@ export async function* serveWithVite( yield { success: true, port: listeningAddress?.port } as unknown as DevServerBuilderOutput; } - if (server) { - let deferred: () => void; - context.addTeardown(async () => { - await server?.close(); - deferred?.(); - }); - await new Promise((resolve) => (deferred = resolve)); - } + // Add cleanup logic via a builder teardown + let deferred: () => void; + context.addTeardown(async () => { + await server?.close(); + await prebundleTransformer.close(); + deferred?.(); + }); + await new Promise((resolve) => (deferred = resolve)); } function handleUpdate( @@ -241,6 +251,7 @@ export async function setupServer( preserveSymlinks: boolean | undefined, prebundleExclude: string[] | undefined, ssr: boolean, + prebundleTransformer: JavaScriptTransformer, ): Promise { const proxy = await loadProxyConfiguration( serverOptions.workspaceRoot, @@ -494,21 +505,12 @@ export async function setupServer( { name: 'angular-vite-optimize-deps', setup(build) { - const transformer = new JavaScriptTransformer( - // Always enable JIT linking to support applications built with and without AOT. - // In a development environment the additional scope information does not - // have a negative effect unlike production where final output size is relevant. - { sourcemap: !!build.initialOptions.sourcemap, jit: true }, - 1, - ); - build.onLoad({ filter: /\.[cm]?js$/ }, async (args) => { return { - contents: await transformer.transformFile(args.path), + contents: await prebundleTransformer.transformFile(args.path), loader: 'js', }; }); - build.onEnd(() => transformer.close()); }, }, ],