diff --git a/packages/angular/build/src/builders/application/tests/behavior/typescript-isolated-modules_spec.ts b/packages/angular/build/src/builders/application/tests/behavior/typescript-isolated-modules_spec.ts index 738e454adb01..06e66cbd6da9 100644 --- a/packages/angular/build/src/builders/application/tests/behavior/typescript-isolated-modules_spec.ts +++ b/packages/angular/build/src/builders/application/tests/behavior/typescript-isolated-modules_spec.ts @@ -47,5 +47,33 @@ describeBuilder(buildApplication, APPLICATION_BUILDER_INFO, (harness) => { expect(result?.success).toBe(true); }); + + it('supports TSX files with isolated modules enabled and enabled optimizations', async () => { + // Enable tsconfig isolatedModules option in tsconfig + await harness.modifyFile('tsconfig.json', (content) => { + const tsconfig = JSON.parse(content); + tsconfig.compilerOptions.isolatedModules = true; + tsconfig.compilerOptions.jsx = 'react-jsx'; + + return JSON.stringify(tsconfig); + }); + + await harness.writeFile('src/types.d.ts', `declare module 'react/jsx-runtime' { jsx: any }`); + await harness.writeFile('src/abc.tsx', `export function hello() { return

Hello

; }`); + await harness.modifyFile( + 'src/main.ts', + (content) => content + `import { hello } from './abc'; console.log(hello());`, + ); + + harness.useTarget('build', { + ...BASE_OPTIONS, + optimization: true, + externalDependencies: ['react'], + }); + + const { result } = await harness.executeOnce(); + + expect(result?.success).toBe(true); + }); }); }); diff --git a/packages/angular/build/src/tools/esbuild/angular/compiler-plugin.ts b/packages/angular/build/src/tools/esbuild/angular/compiler-plugin.ts index 16c4b01fd459..f4ff8a5de1d9 100644 --- a/packages/angular/build/src/tools/esbuild/angular/compiler-plugin.ts +++ b/packages/angular/build/src/tools/esbuild/angular/compiler-plugin.ts @@ -8,6 +8,7 @@ import type { BuildFailure, + Loader, Metafile, OnStartResult, OutputFile, @@ -461,9 +462,21 @@ export function createCompilerPlugin( typeScriptFileCache.set(request, contents); } + let loader: Loader; + if (useTypeScriptTranspilation || isJS) { + // TypeScript has transpiled to JS or is already JS + loader = 'js'; + } else if (request.at(-1) === 'x') { + // TSX and TS have different syntax rules. Only set if input is a TSX file. + loader = 'tsx'; + } else { + // Otherwise, directly bundle TS + loader = 'ts'; + } + return { contents, - loader: useTypeScriptTranspilation || isJS ? 'js' : 'ts', + loader, }; });