diff --git a/packages/angular/build/src/builders/dev-server/vite-server.ts b/packages/angular/build/src/builders/dev-server/vite-server.ts index cca66df4a606..07bb397f738a 100644 --- a/packages/angular/build/src/builders/dev-server/vite-server.ts +++ b/packages/angular/build/src/builders/dev-server/vite-server.ts @@ -482,6 +482,15 @@ export async function setupServer( css: { devSourcemap: true, }, + // Ensure custom 'file' loader build option entries are handled by Vite in application code that + // reference third-party libraries. Relative usage is handled directly by the build and not Vite. + // Only 'file' loader entries are currently supported directly by Vite. + assetsInclude: + prebundleLoaderExtensions && + Object.entries(prebundleLoaderExtensions) + .filter(([, value]) => value === 'file') + // Create a file extension glob for each key + .map(([key]) => '*' + key), // Vite will normalize the `base` option by adding a leading slash. base: serverOptions.servePath, resolve: { diff --git a/packages/angular/build/src/tools/esbuild/external-packages-plugin.ts b/packages/angular/build/src/tools/esbuild/external-packages-plugin.ts index fda108b9841c..5344e9abe33f 100644 --- a/packages/angular/build/src/tools/esbuild/external-packages-plugin.ts +++ b/packages/angular/build/src/tools/esbuild/external-packages-plugin.ts @@ -24,8 +24,13 @@ export function createExternalPackagesPlugin(options?: { exclude?: string[] }): return { name: 'angular-external-packages', setup(build) { + // Find all loader keys that are not using the 'file' loader. + // The 'file' loader is automatically handled by Vite and does not need exclusion. const loaderOptionKeys = - build.initialOptions.loader && Object.keys(build.initialOptions.loader); + build.initialOptions.loader && + Object.entries(build.initialOptions.loader) + .filter(([, value]) => value !== 'file') + .map(([key]) => key); // Safe to use native packages external option if no loader options or exclusions present if (!exclusions && !loaderOptionKeys?.length) {