diff --git a/docs/generated/packages/angular/executors/webpack-browser.json b/docs/generated/packages/angular/executors/webpack-browser.json index 60c53c9843cd8..92cafe962c7ab 100644 --- a/docs/generated/packages/angular/executors/webpack-browser.json +++ b/docs/generated/packages/angular/executors/webpack-browser.json @@ -330,7 +330,7 @@ }, "vendorChunk": { "type": "boolean", - "description": "Generate a seperate bundle containing only vendor libraries. This option should only used for development.", + "description": "Generate a seperate bundle containing only vendor libraries. This option should only be used for development to reduce the incremental compilation time.", "default": false }, "commonChunk": { diff --git a/docs/generated/packages/angular/executors/webpack-server.json b/docs/generated/packages/angular/executors/webpack-server.json index 5813d4bac1ab0..e926fc9e0b5ad 100644 --- a/docs/generated/packages/angular/executors/webpack-server.json +++ b/docs/generated/packages/angular/executors/webpack-server.json @@ -185,6 +185,11 @@ "description": "URL where files will be deployed.", "x-deprecated": "Use \"baseHref\" browser builder option, \"APP_BASE_HREF\" DI token or a combination of both instead. For more information, see https://angular.io/guide/deployment#the-deploy-url." }, + "vendorChunk": { + "type": "boolean", + "description": "Generate a seperate bundle containing only vendor libraries. This option should only be used for development to reduce the incremental compilation time. _Note: supported in Angular versions >= 15.1.0_", + "default": false + }, "verbose": { "type": "boolean", "description": "Adds more details to output logging.", diff --git a/packages/angular/plugins/component-testing.ts b/packages/angular/plugins/component-testing.ts index 56f3c63a78511..6410b4c2fea68 100644 --- a/packages/angular/plugins/component-testing.ts +++ b/packages/angular/plugins/component-testing.ts @@ -23,7 +23,7 @@ import { } from '@nrwl/devkit'; import { existsSync, lstatSync, mkdirSync, writeFileSync } from 'fs'; import { dirname, join, relative, sep } from 'path'; -import type { BrowserBuilderSchema } from '../src/builders/webpack-browser/webpack-browser.impl'; +import type { BrowserBuilderSchema } from '../src/builders/webpack-browser/schema'; /** * Angular nx preset for Cypress Component Testing diff --git a/packages/angular/src/builders/webpack-browser/schema.d.ts b/packages/angular/src/builders/webpack-browser/schema.d.ts new file mode 100644 index 0000000000000..7df96c634f7b7 --- /dev/null +++ b/packages/angular/src/builders/webpack-browser/schema.d.ts @@ -0,0 +1,9 @@ +import { Schema } from '@angular-devkit/build-angular/src/builders/browser/schema'; + +export type BrowserBuilderSchema = Schema & { + customWebpackConfig?: { + path: string; + }; + indexFileTransformer?: string; + buildLibsFromSource?: boolean; +}; diff --git a/packages/angular/src/builders/webpack-browser/schema.json b/packages/angular/src/builders/webpack-browser/schema.json index 2752b04cd454d..c2fb2ed8c3359 100644 --- a/packages/angular/src/builders/webpack-browser/schema.json +++ b/packages/angular/src/builders/webpack-browser/schema.json @@ -278,7 +278,7 @@ }, "vendorChunk": { "type": "boolean", - "description": "Generate a seperate bundle containing only vendor libraries. This option should only used for development.", + "description": "Generate a seperate bundle containing only vendor libraries. This option should only be used for development to reduce the incremental compilation time.", "default": false }, "commonChunk": { diff --git a/packages/angular/src/builders/webpack-browser/validate-options.ts b/packages/angular/src/builders/webpack-browser/validate-options.ts new file mode 100644 index 0000000000000..659d8ca002cb6 --- /dev/null +++ b/packages/angular/src/builders/webpack-browser/validate-options.ts @@ -0,0 +1,50 @@ +import { stripIndents } from '@nrwl/devkit'; +import { extname } from 'path'; +import type { VersionInfo } from '../../executors/utilities/angular-version-utils'; +import { getInstalledAngularVersionInfo } from '../../executors/utilities/angular-version-utils'; +import type { BrowserBuilderSchema } from './schema'; + +export function validateOptions(options: BrowserBuilderSchema): void { + const angularVersionInfo = getInstalledAngularVersionInfo(); + validatePolyfills(options, angularVersionInfo); + validateStyles(options, angularVersionInfo); +} + +function validatePolyfills( + options: BrowserBuilderSchema, + { major, version }: VersionInfo +): void { + if (major < 15 && Array.isArray(options.polyfills)) { + throw new Error(stripIndents`The array syntax for the "polyfills" option is supported from Angular >= 15.0.0. You are currently using "${version}". + You can resolve this error by removing the "polyfills" option, setting it to a string value or migrating to Angular 15.0.0.`); + } +} + +function validateStyles( + options: BrowserBuilderSchema, + { major, version }: VersionInfo +): void { + if (!options.styles || !options.styles.length) { + return; + } + + if (major < 15) { + return; + } + + const stylusFiles = []; + options.styles.forEach((style) => { + const styleFile = typeof style === 'string' ? style : style.input; + if (extname(styleFile) === '.styl') { + stylusFiles.push(styleFile); + } + }); + + if (stylusFiles.length) { + throw new Error(stripIndents`Stylus is not supported since Angular v15. You're currently using "${version}". + You have the "styles" option with the following file(s) using the ".styl" extension: ${stylusFiles + .map((x) => `"${x}"`) + .join(', ')}. + Make sure to convert them to a supported extension (".css", ".scss", ".sass", ".less").`); + } +} diff --git a/packages/angular/src/builders/webpack-browser/webpack-browser.impl.ts b/packages/angular/src/builders/webpack-browser/webpack-browser.impl.ts index 3b05d7b0fa714..4803d0026ca7a 100644 --- a/packages/angular/src/builders/webpack-browser/webpack-browser.impl.ts +++ b/packages/angular/src/builders/webpack-browser/webpack-browser.impl.ts @@ -2,39 +2,22 @@ import { joinPathFragments, ProjectGraph, readCachedProjectGraph, - stripIndents, } from '@nrwl/devkit'; +import type { DependentBuildableProjectNode } from '@nrwl/js/src/utils/buildable-libs-utils'; import { WebpackNxBuildCoordinationPlugin } from '@nrwl/webpack/src/plugins/webpack-nx-build-coordination-plugin'; -import { DependentBuildableProjectNode } from '@nrwl/js/src/utils/buildable-libs-utils'; import { existsSync } from 'fs'; import { readNxJson } from 'nx/src/project-graph/file-utils'; import { isNpmProject } from 'nx/src/project-graph/operators'; import { getDependencyConfigs } from 'nx/src/tasks-runner/utils'; import { from, Observable } from 'rxjs'; import { switchMap } from 'rxjs/operators'; -import { getInstalledAngularVersionInfo } from '../../executors/utilities/angular-version-utils'; import { createTmpTsConfigForBuildableLibs } from '../utilities/buildable-libs'; import { mergeCustomWebpackConfig, resolveIndexHtmlTransformer, } from '../utilities/webpack'; - -export type BrowserBuilderSchema = - import('@angular-devkit/build-angular/src/builders/browser/schema').Schema & { - customWebpackConfig?: { - path: string; - }; - indexFileTransformer?: string; - buildLibsFromSource?: boolean; - }; - -function validateOptions(options: BrowserBuilderSchema): void { - const { major, version } = getInstalledAngularVersionInfo(); - if (major < 15 && Array.isArray(options.polyfills)) { - throw new Error(stripIndents`The array syntax for the "polyfills" option is supported from Angular >= 15.0.0. You are currently using ${version}. - You can resolve this error by removing the "polyfills" option, setting it to a string value or migrating to Angular 15.0.0.`); - } -} +import type { BrowserBuilderSchema } from './schema'; +import { validateOptions } from './validate-options'; function shouldSkipInitialTargetRun( projectGraph: ProjectGraph, diff --git a/packages/angular/src/builders/webpack-server/schema.json b/packages/angular/src/builders/webpack-server/schema.json index 594949c2ac785..892680afa9307 100644 --- a/packages/angular/src/builders/webpack-server/schema.json +++ b/packages/angular/src/builders/webpack-server/schema.json @@ -126,6 +126,11 @@ "description": "URL where files will be deployed.", "x-deprecated": "Use \"baseHref\" browser builder option, \"APP_BASE_HREF\" DI token or a combination of both instead. For more information, see https://angular.io/guide/deployment#the-deploy-url." }, + "vendorChunk": { + "type": "boolean", + "description": "Generate a seperate bundle containing only vendor libraries. This option should only be used for development to reduce the incremental compilation time. _Note: supported in Angular versions >= 15.1.0_", + "default": false + }, "verbose": { "type": "boolean", "description": "Adds more details to output logging.", diff --git a/packages/angular/src/builders/webpack-server/validate-options.ts b/packages/angular/src/builders/webpack-server/validate-options.ts new file mode 100644 index 0000000000000..6ee851e92791d --- /dev/null +++ b/packages/angular/src/builders/webpack-server/validate-options.ts @@ -0,0 +1,40 @@ +import { stripIndents } from '@nrwl/devkit'; +import { lt } from 'semver'; +import type { VersionInfo } from '../../executors/utilities/angular-version-utils'; +import { getInstalledAngularVersionInfo } from '../../executors/utilities/angular-version-utils'; +import type { Schema } from './schema'; + +export function validateOptions(options: Schema): void { + const angularVersionInfo = getInstalledAngularVersionInfo(); + validateAssets(options, angularVersionInfo); + validateBundleDependencies(options, angularVersionInfo); + validateVendorChunk(options, angularVersionInfo); +} + +function validateAssets(options: Schema, { version }: VersionInfo): void { + if ( + lt(version, '15.1.0') && + Array.isArray(options.assets) && + options.assets.length > 0 + ) { + throw new Error(stripIndents`The "assets" option is supported from Angular >= 15.1.0. You are currently using "${version}". + You can resolve this error by removing the "assets" option or by migrating to Angular 15.1.0.`); + } +} + +function validateBundleDependencies( + options: Schema, + { major, version }: VersionInfo +): void { + if (major >= 15 && options.bundleDependencies) { + throw new Error(stripIndents`The "bundleDependencies" option was removed in Angular version 15. You are currently using "${version}". + You can resolve this error by removing the "bundleDependencies" option.`); + } +} + +function validateVendorChunk(options: Schema, { version }: VersionInfo): void { + if (lt(version, '15.1.0') && options.vendorChunk) { + throw new Error(stripIndents`The "vendorChunk" option is supported from Angular >= 15.1.0. You are currently using "${version}". + You can resolve this error by removing the "vendorChunk" option or by migrating to Angular 15.1.0.`); + } +} diff --git a/packages/angular/src/builders/webpack-server/webpack-server.impl.ts b/packages/angular/src/builders/webpack-server/webpack-server.impl.ts index 053a003ee4eb4..3330bc8d235f0 100644 --- a/packages/angular/src/builders/webpack-server/webpack-server.impl.ts +++ b/packages/angular/src/builders/webpack-server/webpack-server.impl.ts @@ -1,12 +1,13 @@ -import { joinPathFragments, stripIndents } from '@nrwl/devkit'; +import { joinPathFragments } from '@nrwl/devkit'; import { existsSync } from 'fs'; -import { from, Observable } from 'rxjs'; -import { mergeCustomWebpackConfig } from '../utilities/webpack'; -import { Schema } from './schema'; -import { createTmpTsConfigForBuildableLibs } from '../utilities/buildable-libs'; +import { Observable, from } from 'rxjs'; import { switchMap } from 'rxjs/operators'; +import { lt } from 'semver'; import { getInstalledAngularVersionInfo } from '../../executors/utilities/angular-version-utils'; -import { gte, lt } from 'semver'; +import { createTmpTsConfigForBuildableLibs } from '../utilities/buildable-libs'; +import { mergeCustomWebpackConfig } from '../utilities/webpack'; +import { Schema } from './schema'; +import { validateOptions } from './validate-options'; function buildServerApp( options: Schema, @@ -92,25 +93,9 @@ export function executeWebpackServerBuilder( options: Schema, context: import('@angular-devkit/architect').BuilderContext ): Observable { - const installedAngularVersionInfo = getInstalledAngularVersionInfo(); - - if ( - lt(installedAngularVersionInfo.version, '15.1.0') && - Array.isArray(options.assets) && - options.assets.length > 0 - ) { - throw new Error(stripIndents`The "assets" option is only supported in Angular >= 15.1.0. You are currently using ${installedAngularVersionInfo.version}. - You can resolve this error by removing the "assets" option or by migrating to Angular 15.1.0.`); - } - - if ( - gte(installedAngularVersionInfo.version, '15.0.0') && - options.bundleDependencies - ) { - throw new Error(stripIndents`The "bundleDependencies" option was removed in Angular version 15. You are currently using ${installedAngularVersionInfo.version}. - You can resolve this error by removing the "bundleDependencies" option.`); - } + validateOptions(options); + const installedAngularVersionInfo = getInstalledAngularVersionInfo(); // default bundleDependencies to true if supported by Angular version if ( lt(installedAngularVersionInfo.version, '15.0.0') && diff --git a/packages/angular/src/executors/utilities/angular-version-utils.ts b/packages/angular/src/executors/utilities/angular-version-utils.ts index ddc824308e45a..3ce71226ae672 100644 --- a/packages/angular/src/executors/utilities/angular-version-utils.ts +++ b/packages/angular/src/executors/utilities/angular-version-utils.ts @@ -1,7 +1,7 @@ import { readModulePackageJson } from 'nx/src/utils/package-json'; import { major } from 'semver'; -type VersionInfo = { major: number; version: string }; +export type VersionInfo = { major: number; version: string }; export function getInstalledAngularVersionInfo(): VersionInfo | null { return getInstalledPackageVersionInfo('@angular/core');