77 */
88
99import type {
10- BuildFailure ,
1110 Loader ,
1211 Metafile ,
1312 OnStartResult ,
1413 OutputFile ,
1514 PartialMessage ,
16- PartialNote ,
1715 Plugin ,
1816 PluginBuild ,
1917} from 'esbuild' ;
@@ -28,11 +26,14 @@ import { JavaScriptTransformer } from '../javascript-transformer';
2826import { LoadResultCache , createCachedLoad } from '../load-result-cache' ;
2927import { logCumulativeDurations , profileAsync , resetCumulativeDurations } from '../profiling' ;
3028import { SharedTSCompilationState , getSharedCompilationState } from './compilation-state' ;
29+ import { createCompilerOptionsTransformer } from './compiler-options-transformer' ;
3130import { ComponentStylesheetBundler } from './component-stylesheets' ;
31+ import { createMissingFileDiagnostic } from './diagnostics' ;
3232import { FileReferenceTracker } from './file-reference-tracker' ;
3333import { setupJitPluginCallbacks } from './jit-plugin-callbacks' ;
3434import { rewriteForBazel } from './rewrite-bazel-paths' ;
3535import { SourceFileCache } from './source-file-cache' ;
36+ import { bundleWebWorker } from './web-worker-bundler' ;
3637
3738export interface CompilerPluginOptions {
3839 sourcemap : boolean | 'external' ;
@@ -642,178 +643,6 @@ async function bundleExternalStylesheet(
642643 }
643644}
644645
645- function createCompilerOptionsTransformer (
646- setupWarnings : PartialMessage [ ] | undefined ,
647- pluginOptions : CompilerPluginOptions ,
648- preserveSymlinks : boolean | undefined ,
649- customConditions : string [ ] | undefined ,
650- ) : Parameters < AngularCompilation [ 'initialize' ] > [ 2 ] {
651- return ( compilerOptions ) => {
652- // target of 9 is ES2022 (using the number avoids an expensive import of typescript just for an enum)
653- if ( compilerOptions . target === undefined || compilerOptions . target < 9 /** ES2022 */ ) {
654- // If 'useDefineForClassFields' is already defined in the users project leave the value as is.
655- // Otherwise fallback to false due to https://github.com/microsoft/TypeScript/issues/45995
656- // which breaks the deprecated `@Effects` NGRX decorator and potentially other existing code as well.
657- compilerOptions . target = 9 /** ES2022 */ ;
658- compilerOptions . useDefineForClassFields ??= false ;
659-
660- // Only add the warning on the initial build
661- setupWarnings ?. push ( {
662- text :
663- `TypeScript compiler options 'target' and 'useDefineForClassFields' are set to 'ES2022' and ` +
664- `'false' respectively by the Angular CLI.` ,
665- location : { file : pluginOptions . tsconfig } ,
666- notes : [
667- {
668- text :
669- 'To control ECMA version and features use the Browserslist configuration. ' +
670- 'For more information, see https://angular.dev/tools/cli/build#configuring-browser-compatibility' ,
671- } ,
672- ] ,
673- } ) ;
674- }
675-
676- if ( compilerOptions . compilationMode === 'partial' ) {
677- setupWarnings ?. push ( {
678- text : 'Angular partial compilation mode is not supported when building applications.' ,
679- location : null ,
680- notes : [ { text : 'Full compilation mode will be used instead.' } ] ,
681- } ) ;
682- compilerOptions . compilationMode = 'full' ;
683- }
684-
685- // Enable incremental compilation by default if caching is enabled and incremental is not explicitly disabled
686- if (
687- compilerOptions . incremental !== false &&
688- pluginOptions . sourceFileCache ?. persistentCachePath
689- ) {
690- compilerOptions . incremental = true ;
691- // Set the build info file location to the configured cache directory
692- compilerOptions . tsBuildInfoFile = path . join (
693- pluginOptions . sourceFileCache ?. persistentCachePath ,
694- '.tsbuildinfo' ,
695- ) ;
696- } else {
697- compilerOptions . incremental = false ;
698- }
699-
700- if ( compilerOptions . module === undefined || compilerOptions . module < 5 /** ES2015 */ ) {
701- compilerOptions . module = 7 ; /** ES2022 */
702- setupWarnings ?. push ( {
703- text : `TypeScript compiler options 'module' values 'CommonJS', 'UMD', 'System' and 'AMD' are not supported.` ,
704- location : null ,
705- notes : [ { text : `The 'module' option will be set to 'ES2022' instead.` } ] ,
706- } ) ;
707- }
708-
709- if ( compilerOptions . isolatedModules && compilerOptions . emitDecoratorMetadata ) {
710- setupWarnings ?. push ( {
711- text : `TypeScript compiler option 'isolatedModules' may prevent the 'emitDecoratorMetadata' option from emitting all metadata.` ,
712- location : null ,
713- notes : [
714- {
715- text :
716- `The 'emitDecoratorMetadata' option is not required by Angular` +
717- 'and can be removed if not explictly required by the project.' ,
718- } ,
719- ] ,
720- } ) ;
721- }
722-
723- // Synchronize custom resolve conditions.
724- // Set if using the supported bundler resolution mode (bundler is the default in new projects)
725- if (
726- compilerOptions . moduleResolution === 100 /* ModuleResolutionKind.Bundler */ ||
727- compilerOptions . module === 200 /** ModuleKind.Preserve */
728- ) {
729- compilerOptions . customConditions = customConditions ;
730- }
731-
732- return {
733- ...compilerOptions ,
734- noEmitOnError : false ,
735- composite : false ,
736- inlineSources : ! ! pluginOptions . sourcemap ,
737- inlineSourceMap : ! ! pluginOptions . sourcemap ,
738- sourceMap : undefined ,
739- mapRoot : undefined ,
740- sourceRoot : undefined ,
741- preserveSymlinks,
742- externalRuntimeStyles : pluginOptions . externalRuntimeStyles ,
743- _enableHmr : ! ! pluginOptions . templateUpdates ,
744- supportTestBed : ! ! pluginOptions . includeTestMetadata ,
745- supportJitMode : ! ! pluginOptions . includeTestMetadata ,
746- } ;
747- } ;
748- }
749-
750- function bundleWebWorker (
751- build : PluginBuild ,
752- pluginOptions : CompilerPluginOptions ,
753- workerFile : string ,
754- ) {
755- try {
756- return build . esbuild . buildSync ( {
757- ...build . initialOptions ,
758- platform : 'browser' ,
759- write : false ,
760- bundle : true ,
761- metafile : true ,
762- format : 'esm' ,
763- entryNames : 'worker-[hash]' ,
764- entryPoints : [ workerFile ] ,
765- sourcemap : pluginOptions . sourcemap ,
766- // Zone.js is not used in Web workers so no need to disable
767- supported : undefined ,
768- // Plugins are not supported in sync esbuild calls
769- plugins : undefined ,
770- } ) ;
771- } catch ( error ) {
772- if ( error && typeof error === 'object' && 'errors' in error && 'warnings' in error ) {
773- return error as BuildFailure ;
774- }
775- throw error ;
776- }
777- }
778-
779- function createMissingFileDiagnostic (
780- request : string ,
781- original : string ,
782- root : string ,
783- angular : boolean ,
784- ) : PartialMessage {
785- const relativeRequest = path . relative ( root , request ) ;
786- const notes : PartialNote [ ] = [ ] ;
787-
788- if ( angular ) {
789- notes . push ( {
790- text :
791- `Files containing Angular metadata ('@Component'/'@Directive'/etc.) must be part of the TypeScript compilation.` +
792- ` You can ensure the file is part of the TypeScript program via the 'files' or 'include' property.` ,
793- } ) ;
794- } else {
795- notes . push ( {
796- text :
797- `The file will be bundled and included in the output but will not be type-checked at build time.` +
798- ` To remove this message you can add the file to the TypeScript program via the 'files' or 'include' property.` ,
799- } ) ;
800- }
801-
802- const relativeOriginal = path . relative ( root , original ) ;
803- if ( relativeRequest !== relativeOriginal ) {
804- notes . push ( {
805- text : `File is requested from a file replacement of '${ relativeOriginal } '.` ,
806- } ) ;
807- }
808-
809- const diagnostic = {
810- text : `File '${ relativeRequest } ' not found in TypeScript compilation.` ,
811- notes,
812- } ;
813-
814- return diagnostic ;
815- }
816-
817646const POTENTIAL_METADATA_REGEX = / @ a n g u l a r \/ c o r e | @ C o m p o n e n t | @ D i r e c t i v e | @ I n j e c t a b l e | @ P i p e | @ N g M o d u l e / ;
818647
819648function requiresAngularCompiler ( contents : string ) : boolean {
0 commit comments