From d8d116b318377d51f258a1a23025be2d41136ee3 Mon Sep 17 00:00:00 2001 From: Alan Agius Date: Thu, 14 Sep 2023 08:52:33 +0000 Subject: [PATCH] fix(@angular-devkit/build-angular): several windows fixes to application builder prerendering This commit fixes several Windows issues in the prerendering pipeline. Primarily due to path normalization and other Windows only constraints. (cherry picked from commit 48963fc17f92a5f6f339cb12bc9a842736e04ae4) --- .../server-rendering/esm-in-memory-file-loader.ts | 13 ++++++++----- .../src/utils/server-rendering/prerender.ts | 5 +++-- 2 files changed, 11 insertions(+), 7 deletions(-) diff --git a/packages/angular_devkit/build_angular/src/utils/server-rendering/esm-in-memory-file-loader.ts b/packages/angular_devkit/build_angular/src/utils/server-rendering/esm-in-memory-file-loader.ts index fc253c6d3477..c6f2e89db82b 100644 --- a/packages/angular_devkit/build_angular/src/utils/server-rendering/esm-in-memory-file-loader.ts +++ b/packages/angular_devkit/build_angular/src/utils/server-rendering/esm-in-memory-file-loader.ts @@ -6,7 +6,8 @@ * found in the LICENSE file at https://angular.io/license */ -import { join } from 'node:path'; +import { join, relative } from 'node:path'; +import { pathToFileURL } from 'node:url'; import { workerData } from 'node:worker_threads'; import { fileURLToPath } from 'url'; import { JavaScriptTransformer } from '../../tools/esbuild/javascript-transformer'; @@ -23,7 +24,7 @@ const { outputFiles, workspaceRoot } = workerData as { const TRANSFORMED_FILES: Record = {}; const CHUNKS_REGEXP = /file:\/\/\/(main\.server|chunk-\w+)\.mjs/; -const WORKSPACE_ROOT_FILE = new URL(join(workspaceRoot, 'index.mjs'), 'file:').href; +const WORKSPACE_ROOT_FILE = pathToFileURL(join(workspaceRoot, 'index.mjs')).href; const JAVASCRIPT_TRANSFORMER = new JavaScriptTransformer( // Always enable JIT linking to support applications built with and without AOT. @@ -44,7 +45,9 @@ export function resolve( return { format: 'module', shortCircuit: true, - url: new URL(normalizedSpecifier, 'file:').href, + // File URLs need to absolute. In Windows these also need to include the drive. + // The `/` will be resolved to the drive letter. + url: pathToFileURL('/' + normalizedSpecifier).href, }; } } @@ -60,8 +63,8 @@ export function resolve( export async function load(url: string, context: { format?: string | null }, nextLoad: Function) { if (isFileProtocol(url)) { const filePath = fileURLToPath(url); - let source = - outputFiles[filePath.slice(1)] /* Remove leading slash */ ?? TRANSFORMED_FILES[filePath]; + // Remove '/' or drive letter for Windows that was added in the above 'resolve'. + let source = outputFiles[relative('/', filePath)] ?? TRANSFORMED_FILES[filePath]; if (source === undefined) { source = TRANSFORMED_FILES[filePath] = Buffer.from( diff --git a/packages/angular_devkit/build_angular/src/utils/server-rendering/prerender.ts b/packages/angular_devkit/build_angular/src/utils/server-rendering/prerender.ts index d03d4821fd72..0d3ffeb18210 100644 --- a/packages/angular_devkit/build_angular/src/utils/server-rendering/prerender.ts +++ b/packages/angular_devkit/build_angular/src/utils/server-rendering/prerender.ts @@ -8,7 +8,8 @@ import { OutputFile } from 'esbuild'; import { readFile } from 'node:fs/promises'; -import { extname, posix } from 'node:path'; +import { extname, join, posix } from 'node:path'; +import { pathToFileURL } from 'node:url'; import Piscina from 'piscina'; import type { RenderResult, ServerContext } from './render-page'; import type { WorkerData } from './render-worker'; @@ -61,7 +62,7 @@ export async function prerenderPages( execArgv: [ '--no-warnings', // Suppress `ExperimentalWarning: Custom ESM Loaders is an experimental feature...`. '--loader', - require.resolve('./esm-in-memory-file-loader.js'), + pathToFileURL(join(__dirname, 'esm-in-memory-file-loader.js')).href, // Loader cannot be an absolute path on Windows. ], });