Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 1 addition & 3 deletions packages/angular/build/src/builders/dev-server/vite/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,6 @@ import { ServerSsrMode } from '../../../tools/vite/plugins';
import { EsbuildLoaderOption } from '../../../tools/vite/utils';
import { normalizeSourceMaps } from '../../../utils';
import { useComponentStyleHmr, useComponentTemplateHmr } from '../../../utils/environment-options';
import { loadEsmModule } from '../../../utils/load-esm';
import { Result, ResultKind } from '../../application/results';
import { OutputHashing } from '../../application/schema';
import {
Expand Down Expand Up @@ -175,8 +174,7 @@ export async function* serveWithVite(
// The index HTML path will be updated from the build results if provided by the builder
let htmlIndexPath = 'index.html';

// dynamically import Vite for ESM compatibility
const { createServer, normalizePath } = await loadEsmModule<typeof import('vite')>('vite');
const { createServer, normalizePath } = await import('vite');

let server: ViteDevServer | undefined;
let serverUrl: URL | undefined;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,6 @@ import {
} from '../../../tools/vite/plugins';
import { EsbuildLoaderOption, getDepOptimizationConfig } from '../../../tools/vite/utils';
import { loadProxyConfiguration } from '../../../utils';
import { loadEsmModule } from '../../../utils/load-esm';
import { type ApplicationBuilderInternalOptions, JavaScriptTransformer } from '../internal';
import type { NormalizedDevServerOptions } from '../options';
import { DevServerExternalResultMetadata, OutputAssetRecord, OutputFileRecord } from './utils';
Expand Down Expand Up @@ -152,8 +151,7 @@ export async function setupServer(
indexHtmlTransformer?: (content: string) => Promise<string>,
thirdPartySourcemaps = false,
): Promise<InlineConfig> {
// dynamically import Vite for ESM compatibility
const { normalizePath } = await loadEsmModule<typeof import('vite')>('vite');
const { normalizePath } = await import('vite');

// Path will not exist on disk and only used to provide separate path for Vite requests
const virtualProjectRoot = normalizePath(
Expand Down
4 changes: 1 addition & 3 deletions packages/angular/build/src/builders/extract-i18n/builder.ts
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,6 @@ import type { Diagnostics } from '@angular/localize/tools';
import type { BuilderContext, BuilderOutput } from '@angular-devkit/architect';
import fs from 'node:fs';
import path from 'node:path';
import { loadEsmModule } from '../../utils/load-esm';
import { assertCompatibleAngularVersion } from '../../utils/version';
import type { ApplicationBuilderExtensions } from '../application/options';
import { normalizeOptions } from './options';
Expand Down Expand Up @@ -51,8 +50,7 @@ export async function execute(
// The package is a peer dependency and might not be present
let localizeToolsModule;
try {
localizeToolsModule =
await loadEsmModule<typeof import('@angular/localize/tools')>('@angular/localize/tools');
localizeToolsModule = await import('@angular/localize/tools');
} catch {
return {
success: false,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,15 +7,16 @@
*/

import { createRequire } from 'node:module';
import type { BrowserBuiltinProvider, BrowserConfigOptions } from 'vitest/node';

export interface BrowserConfiguration {
browser?: import('vitest/node').BrowserConfigOptions;
browser?: BrowserConfigOptions;
errors?: string[];
}

function findBrowserProvider(
projectResolver: NodeJS.RequireResolve,
): import('vitest/node').BrowserBuiltinProvider | undefined {
): BrowserBuiltinProvider | undefined {
// One of these must be installed in the project to use browser testing
const vitestBuiltinProviders = ['playwright', 'webdriverio'] as const;

Expand Down Expand Up @@ -87,7 +88,7 @@ export function setupBrowserConfiguration(
const isCI = !!process.env['CI'];
const headless = isCI || browsers.some((name) => name.toLowerCase().includes('headless'));

const browser = {
const browser: BrowserConfigOptions = {
enabled: true,
provider,
headless,
Expand All @@ -96,7 +97,7 @@ export function setupBrowserConfiguration(
instances: browsers.map((browserName) => ({
browser: normalizeBrowserName(browserName),
})),
} satisfies import('vitest/node').BrowserConfigOptions;
};

return { browser };
}
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,6 @@ import assert from 'node:assert';
import path from 'node:path';
import type { InlineConfig, Vitest } from 'vitest/node';
import { assertIsError } from '../../../../utils/error';
import { loadEsmModule } from '../../../../utils/load-esm';
import { toPosixPath } from '../../../../utils/path';
import {
type FullResult,
Expand Down Expand Up @@ -141,7 +140,7 @@ export class VitestExecutor implements TestExecutor {
} = this.options;
let vitestNodeModule;
try {
vitestNodeModule = await loadEsmModule<typeof import('vitest/node')>('vitest/node');
vitestNodeModule = await import('vitest/node');
} catch (error: unknown) {
assertIsError(error);
if (error.code !== 'ERR_MODULE_NOT_FOUND') {
Expand Down Expand Up @@ -230,7 +229,7 @@ async function generateCoverageOption(
let defaultExcludes: string[] = [];
if (coverage.exclude) {
try {
const vitestConfig = await loadEsmModule<typeof import('vitest/config')>('vitest/config');
const vitestConfig = await import('vitest/config');
defaultExcludes = vitestConfig.coverageConfigDefaults.exclude;
} catch {}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,6 @@
import type ng from '@angular/compiler-cli';
import type { PartialMessage } from 'esbuild';
import type ts from 'typescript';
import { loadEsmModule } from '../../../utils/load-esm';
import { convertTypeScriptDiagnostic } from '../../esbuild/angular/diagnostics';
import { profileAsync, profileSync } from '../../esbuild/profiling';
import type { AngularHostOptions } from '../angular-host';
Expand All @@ -33,10 +32,7 @@ export abstract class AngularCompilation {
static #typescriptModule?: typeof ts;

static async loadCompilerCli(): Promise<typeof ng> {
// This uses a wrapped dynamic import to load `@angular/compiler-cli` which is ESM.
// Once TypeScript provides support for retaining dynamic imports this workaround can be dropped.
AngularCompilation.#angularCompilerCliModule ??=
await loadEsmModule<typeof ng>('@angular/compiler-cli');
AngularCompilation.#angularCompilerCliModule ??= await import('@angular/compiler-cli');

return AngularCompilation.#angularCompilerCliModule;
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,6 @@
import type ng from '@angular/compiler-cli';
import assert from 'node:assert';
import ts from 'typescript';
import { loadEsmModule } from '../../../utils/load-esm';
import { profileSync } from '../../esbuild/profiling';
import { AngularHostOptions, createAngularCompilerHost } from '../angular-host';
import { createJitResourceTransformer } from '../transformers/jit-resource-transformer';
Expand Down Expand Up @@ -44,9 +43,9 @@ export class JitCompilation extends AngularCompilation {
referencedFiles: readonly string[];
}> {
// Dynamically load the Angular compiler CLI package
const { constructorParametersDownlevelTransform } = await loadEsmModule<
typeof import('@angular/compiler-cli/private/tooling')
>('@angular/compiler-cli/private/tooling');
const { constructorParametersDownlevelTransform } = await import(
'@angular/compiler-cli/private/tooling'
);

// Load the compiler configuration and transform as needed
const {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,6 @@ import { PluginObj, parseSync, transformFromAstAsync, types } from '@babel/core'
import assert from 'node:assert';
import { workerData } from 'node:worker_threads';
import { assertIsError } from '../../utils/error';
import { loadEsmModule } from '../../utils/load-esm';

/**
* The options passed to the inliner for each file request
Expand Down Expand Up @@ -131,7 +130,7 @@ async function loadLocalizeTools(): Promise<LocalizeUtilityModule> {
// Load ESM `@angular/localize/tools` using the TypeScript dynamic import workaround.
// Once TypeScript provides support for keeping the dynamic import this workaround can be
// changed to a direct dynamic import.
localizeToolsModule ??= await loadEsmModule<LocalizeUtilityModule>('@angular/localize/tools');
localizeToolsModule ??= await import('@angular/localize/tools');

return localizeToolsModule;
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,6 @@ import { type PluginItem, transformAsync } from '@babel/core';
import fs from 'node:fs';
import path from 'node:path';
import Piscina from 'piscina';
import { loadEsmModule } from '../../utils/load-esm';

interface JavaScriptTransformRequest {
filename: string;
Expand Down Expand Up @@ -133,11 +132,8 @@ async function requiresLinking(path: string, source: string): Promise<boolean> {
}

async function createLinkerPlugin(options: Omit<JavaScriptTransformRequest, 'filename' | 'data'>) {
linkerPluginCreator ??= (
await loadEsmModule<typeof import('@angular/compiler-cli/linker/babel')>(
'@angular/compiler-cli/linker/babel',
)
).createEs2015LinkerPlugin;
linkerPluginCreator ??= (await import('@angular/compiler-cli/linker/babel'))
.createEs2015LinkerPlugin;

const linkerPlugin = linkerPluginCreator({
linkerJitMode: options.jit,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -10,10 +10,8 @@ import type {
AngularAppEngine as SSRAngularAppEngine,
ɵgetOrCreateAngularServerApp as getOrCreateAngularServerApp,
} from '@angular/ssr';
import type * as AngularSsrNode from '@angular/ssr/node' with { 'resolution-mode': 'import' };
import type { ServerResponse } from 'node:http';
import type { Connect, ViteDevServer } from 'vite';
import { loadEsmModule } from '../../../utils/load-esm';
import {
isSsrNodeRequestHandler,
isSsrRequestHandler,
Expand All @@ -37,9 +35,11 @@ export function createAngularSsrInternalMiddleware(
(async () => {
// Load the compiler because `@angular/ssr/node` depends on `@angular/` packages,
// which must be processed by the runtime linker, even if they are not used.
await loadEsmModule('@angular/compiler');
const { writeResponseToNodeResponse, createWebRequestFromNodeRequest } =
await loadEsmModule<typeof AngularSsrNode>('@angular/ssr/node');
await import('@angular/compiler');
const { writeResponseToNodeResponse, createWebRequestFromNodeRequest } = (await import(
// eslint-disable-next-line @typescript-eslint/no-explicit-any
'@angular/ssr/node' as any
)) as typeof import('@angular/ssr/node', { with: { 'resolution-mode': 'import' } });

const { ɵgetOrCreateAngularServerApp } = (await server.ssrLoadModule('/main.server.mjs')) as {
ɵgetOrCreateAngularServerApp: typeof getOrCreateAngularServerApp;
Expand Down Expand Up @@ -91,10 +91,12 @@ export async function createAngularSsrExternalMiddleware(

// Load the compiler because `@angular/ssr/node` depends on `@angular/` packages,
// which must be processed by the runtime linker, even if they are not used.
await loadEsmModule('@angular/compiler');
await import('@angular/compiler');

const { createWebRequestFromNodeRequest, writeResponseToNodeResponse } =
await loadEsmModule<typeof AngularSsrNode>('@angular/ssr/node');
const { createWebRequestFromNodeRequest, writeResponseToNodeResponse } = (await import(
// eslint-disable-next-line @typescript-eslint/no-explicit-any
'@angular/ssr/node' as any
)) as typeof import('@angular/ssr/node', { with: { 'resolution-mode': 'import' } });

return function angularSsrExternalMiddleware(
req: Connect.IncomingMessage,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,6 @@ import { readFile } from 'node:fs/promises';
import { dirname, join, relative } from 'node:path';
import { fileURLToPath } from 'node:url';
import type { Plugin } from 'vite';
import { loadEsmModule } from '../../../utils/load-esm';
import { AngularMemoryOutputFiles } from '../utils';

interface AngularMemoryPluginOptions {
Expand All @@ -30,7 +29,7 @@ export async function createAngularMemoryPlugin(
options: AngularMemoryPluginOptions,
): Promise<Plugin> {
const { virtualProjectRoot, outputFiles, external } = options;
const { normalizePath } = await loadEsmModule<typeof import('vite')>('vite');
const { normalizePath } = await import('vite');

return {
name: 'vite:angular-memory',
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,6 @@
*/

import type { Connect, Plugin } from 'vite';
import { loadEsmModule } from '../../../utils/load-esm';
import {
ComponentStyleRecord,
angularHtmlFallbackMiddleware,
Expand Down Expand Up @@ -61,8 +60,7 @@ interface AngularSetupMiddlewaresPluginOptions {
async function createEncapsulateStyle(): Promise<
(style: Uint8Array, componentId: string) => string
> {
const { encapsulateStyle } =
await loadEsmModule<typeof import('@angular/compiler')>('@angular/compiler');
const { encapsulateStyle } = await import('@angular/compiler');
const decoder = new TextDecoder('utf-8');

return (style, componentId) => {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -8,10 +8,9 @@

import remapping, { SourceMapInput } from '@ampproject/remapping';
import type { Plugin } from 'vite';
import { loadEsmModule } from '../../../utils/load-esm';

export async function createAngularSsrTransformPlugin(workspaceRoot: string): Promise<Plugin> {
const { normalizePath } = await loadEsmModule<typeof import('vite')>('vite');
const { normalizePath } = await import('vite');

return {
name: 'vite:angular-ssr-transform',
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,6 @@

import { createHash } from 'node:crypto';
import { extname } from 'node:path';
import { loadEsmModule } from '../load-esm';
import { htmlRewritingStream } from './html-rewriting-stream';
import { VALID_SELF_CLOSING_TAGS } from './valid-self-closing-tags';

Expand Down Expand Up @@ -352,12 +351,7 @@ async function getLanguageDirection(

async function getLanguageDirectionFromLocales(locale: string): Promise<string | undefined> {
try {
const localeData = (
await loadEsmModule<typeof import('@angular/common/locales/en')>(
`@angular/common/locales/${locale}`,
)
).default;

const localeData = (await import(`@angular/common/locales/${locale}`)).default;
const dir = localeData[localeData.length - 2];

return isString(dir) ? dir : undefined;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,6 @@
import { Readable } from 'node:stream';
import { pipeline } from 'node:stream/promises';
import type { RewritingStream } from 'parse5-html-rewriting-stream';
import { loadEsmModule } from '../load-esm';

// Export helper types for the rewriter
export type StartTag = Parameters<RewritingStream['emitStartTag']>[0];
Expand All @@ -20,9 +19,7 @@ export async function htmlRewritingStream(content: string): Promise<{
rewriter: RewritingStream;
transformedContent: () => Promise<string>;
}> {
const { RewritingStream } = await loadEsmModule<typeof import('parse5-html-rewriting-stream')>(
'parse5-html-rewriting-stream',
);
const { RewritingStream } = await import('parse5-html-rewriting-stream');
const rewriter = new RewritingStream();

return {
Expand Down
29 changes: 8 additions & 21 deletions packages/angular/build/src/utils/load-proxy-config.ts
Original file line number Diff line number Diff line change
Expand Up @@ -49,33 +49,20 @@ export async function loadProxyConfiguration(

break;
}
case '.mjs':
// Load the ESM configuration file using the TypeScript dynamic import workaround.
// Once TypeScript provides support for keeping the dynamic import this workaround can be
// changed to a direct dynamic import.
proxyConfiguration = await loadEsmModule<{ default: unknown }>(pathToFileURL(proxyPath));
break;
case '.cjs':
proxyConfiguration = require(proxyPath);
break;
default:
// The file could be either CommonJS or ESM.
// CommonJS is tried first then ESM if loading fails.
default: {
try {
proxyConfiguration = require(proxyPath);
break;
proxyConfiguration = await import(proxyPath);
} catch (e) {
assertIsError(e);
if (e.code === 'ERR_REQUIRE_ESM' || e.code === 'ERR_REQUIRE_ASYNC_MODULE') {
// Load the ESM configuration file using the TypeScript dynamic import workaround.
// Once TypeScript provides support for keeping the dynamic import this workaround can be
// changed to a direct dynamic import.
proxyConfiguration = await loadEsmModule<{ default: unknown }>(pathToFileURL(proxyPath));
break;
if (e.code !== 'ERR_REQUIRE_ASYNC_MODULE') {
throw e;
}

throw e;
proxyConfiguration = await loadEsmModule<{ default: unknown }>(pathToFileURL(proxyPath));
}

break;
}
}

if ('default' in proxyConfiguration) {
Expand Down
3 changes: 1 addition & 2 deletions packages/angular/build/src/utils/load-translations.ts
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,6 @@
import type { Diagnostics } from '@angular/localize/tools';
import { createHash } from 'node:crypto';
import * as fs from 'node:fs';
import { loadEsmModule } from './load-esm';

export type TranslationLoader = (path: string) => {
translations: Record<string, import('@angular/localize').ɵParsedTranslation>;
Expand Down Expand Up @@ -62,7 +61,7 @@ async function importParsers() {
Xliff1TranslationParser,
Xliff2TranslationParser,
XtbTranslationParser,
} = await loadEsmModule<typeof import('@angular/localize/tools')>('@angular/localize/tools');
} = await import('@angular/localize/tools');

const diagnostics = new Diagnostics();
const parsers = {
Expand Down
Loading