Skip to content

Commit

Permalink
fix(@angular/build): prevent transformation of Node.js internal depen…
Browse files Browse the repository at this point in the history
…dencies by Vite

This commit excludes Node.js module imports from being processed by Vite when prebundling is enabled.

Closes #28390
  • Loading branch information
alan-agius4 committed Sep 11, 2024
1 parent 743188b commit 4153a6e
Showing 1 changed file with 21 additions and 12 deletions.
33 changes: 21 additions & 12 deletions packages/angular/build/src/builders/dev-server/vite-server.ts
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,11 @@ interface OutputFileRecord {
type: BuildOutputFileType;
}

interface DevServerExternalResultMetadata extends Omit<ExternalResultMetadata, 'explicit'> {
explicitBrowser: string[];
explicitServer: string[];
}

export type BuilderAction = (
options: ApplicationBuilderInternalOptions,
context: BuilderContext,
Expand Down Expand Up @@ -140,10 +145,11 @@ export async function* serveWithVite(
let hadError = false;
const generatedFiles = new Map<string, OutputFileRecord>();
const assetFiles = new Map<string, string>();
const externalMetadata: ExternalResultMetadata = {
const externalMetadata: DevServerExternalResultMetadata = {
implicitBrowser: [],
implicitServer: [],
explicit: [],
explicitBrowser: [],
explicitServer: [],
};

// Add cleanup logic via a builder teardown.
Expand Down Expand Up @@ -236,17 +242,20 @@ export async function* serveWithVite(
}

// Empty Arrays to avoid growing unlimited with every re-build.
externalMetadata.explicit.length = 0;
externalMetadata.explicitBrowser.length = 0;
externalMetadata.explicitServer.length = 0;
externalMetadata.implicitServer.length = 0;
externalMetadata.implicitBrowser.length = 0;

externalMetadata.explicit.push(...explicit);
externalMetadata.explicitBrowser.push(...explicit);
externalMetadata.explicitServer.push(...explicit, ...nodeJsBuiltinModules);
externalMetadata.implicitServer.push(...implicitServerFiltered);
externalMetadata.implicitBrowser.push(...implicitBrowserFiltered);

// The below needs to be sorted as Vite uses these options are part of the hashing invalidation algorithm.
// See: https://github.com/vitejs/vite/blob/0873bae0cfe0f0718ad2f5743dd34a17e4ab563d/packages/vite/src/node/optimizer/index.ts#L1203-L1239
externalMetadata.explicit.sort();
externalMetadata.explicitBrowser.sort();
externalMetadata.explicitServer.sort();
externalMetadata.implicitServer.sort();
externalMetadata.implicitBrowser.sort();
}
Expand Down Expand Up @@ -494,7 +503,7 @@ export async function setupServer(
outputFiles: Map<string, OutputFileRecord>,
assets: Map<string, string>,
preserveSymlinks: boolean | undefined,
externalMetadata: ExternalResultMetadata,
externalMetadata: DevServerExternalResultMetadata,
ssr: boolean,
prebundleTransformer: JavaScriptTransformer,
target: string[],
Expand Down Expand Up @@ -573,18 +582,18 @@ export async function setupServer(
},
// This is needed when `externalDependencies` is used to prevent Vite load errors.
// NOTE: If Vite adds direct support for externals, this can be removed.
preTransformRequests: externalMetadata.explicit.length === 0,
preTransformRequests: externalMetadata.explicitBrowser.length === 0,
},
ssr: {
// Note: `true` and `/.*/` have different sematics. When true, the `external` option is ignored.
noExternal: /.*/,
// Exclude any Node.js built in module and provided dependencies (currently build defined externals)
external: externalMetadata.explicit,
external: externalMetadata.explicitServer,
optimizeDeps: getDepOptimizationConfig({
// Only enable with caching since it causes prebundle dependencies to be cached
disabled: serverOptions.prebundle === false,
// Exclude any explicitly defined dependencies (currently build defined externals and node.js built-ins)
exclude: externalMetadata.explicit,
exclude: externalMetadata.explicitServer,
// Include all implict dependencies from the external packages internal option
include: externalMetadata.implicitServer,
ssr: true,
Expand All @@ -603,19 +612,19 @@ export async function setupServer(
outputFiles,
assets,
ssr,
external: externalMetadata.explicit,
external: externalMetadata.explicitBrowser,
indexHtmlTransformer,
extensionMiddleware,
normalizePath,
}),
createRemoveIdPrefixPlugin(externalMetadata.explicit),
createRemoveIdPrefixPlugin(externalMetadata.explicitBrowser),
],
// Browser only optimizeDeps. (This does not run for SSR dependencies).
optimizeDeps: getDepOptimizationConfig({
// Only enable with caching since it causes prebundle dependencies to be cached
disabled: serverOptions.prebundle === false,
// Exclude any explicitly defined dependencies (currently build defined externals)
exclude: externalMetadata.explicit,
exclude: externalMetadata.explicitBrowser,
// Include all implict dependencies from the external packages internal option
include: externalMetadata.implicitBrowser,
ssr: false,
Expand Down

0 comments on commit 4153a6e

Please sign in to comment.