diff --git a/docs/angular/api-angular/executors/webpack-server.md b/docs/angular/api-angular/executors/webpack-server.md new file mode 100644 index 0000000000..3b551f6f0f --- /dev/null +++ b/docs/angular/api-angular/executors/webpack-server.md @@ -0,0 +1,211 @@ +# webpack-server + +Serves a browser application with support for a custom webpack configuration. + +Options can be configured in `angular.json` when defining the executor, or when invoking it. + +## Options + +### browserTarget (_**required**_) + +Type: `string` + +A browser builder target to serve in the format of `project:target[:configuration]`. You can also pass in more than one configuration name as a comma-separated list. Example: `project:target:production,staging`. + +### allowedHosts + +Type: `array` + +List of hosts that are allowed to access the dev server. + +### ~~aot~~ + +Type: `boolean` + +**Deprecated:** Use the "aot" option in the browser builder instead. + +Build using Ahead of Time compilation. + +### ~~baseHref~~ + +Type: `string` + +**Deprecated:** Use the "baseHref" option in the browser builder instead. + +Base url for the application being built. + +### ~~commonChunk~~ + +Type: `boolean` + +**Deprecated:** Use the "commonChunk" option in the browser builder instead. + +Generate a seperate bundle containing code used across multiple bundles. + +### ~~deployUrl~~ + +Type: `string` + +**Deprecated:** Use the "deployUrl" option in the browser builder instead. + +URL where files will be deployed. + +### disableHostCheck + +Default: `false` + +Type: `boolean` + +Don't verify connected clients are part of allowed hosts. + +### hmr + +Default: `false` + +Type: `boolean` + +Enable hot module replacement. + +### ~~hmrWarning~~ + +Default: `true` + +Type: `boolean` + +**Deprecated:** No longer has an effect. + +Show a warning when the --hmr option is enabled. + +### host + +Default: `localhost` + +Type: `string` + +Host to listen on. + +### liveReload + +Default: `true` + +Type: `boolean` + +Whether to reload the page on change, using live-reload. + +### open + +Alias(es): o + +Default: `false` + +Type: `boolean` + +Opens the url in default browser. + +### ~~optimization~~ + +Type: `boolean` + +**Deprecated:** Use the "optimization" option in the browser builder instead. + +Enables optimization of the build output. Including minification of scripts and styles, tree-shaking, dead-code elimination, tree-shaking and fonts inlining. For more information, see https://angular.io/guide/workspace-config#optimization-configuration. + +### poll + +Type: `number` + +Enable and define the file watching poll time period in milliseconds. + +### port + +Default: `4200` + +Type: `number` + +Port to listen on. + +### ~~progress~~ + +Type: `boolean` + +**Deprecated:** Use the "progress" option in the browser builder instead. + +Log progress to the console while building. + +### proxyConfig + +Type: `string` + +Proxy configuration file. For more information, see https://angular.io/guide/build#proxying-to-a-backend-server. + +### publicHost + +Type: `string` + +The URL that the browser client (or live-reload client, if enabled) should use to connect to the development server. Use for a complex dev server setup, such as one with reverse proxies. + +### servePath + +Type: `string` + +The pathname where the app will be served. + +### ~~servePathDefaultWarning~~ + +Default: `true` + +Type: `boolean` + +**Deprecated:** No longer has an effect. + +Show a warning when deploy-url/base-href use unsupported serve path values. + +### ~~sourceMap~~ + +Type: `boolean` + +**Deprecated:** Use the "sourceMap" option in the browser builder instead. + +Output source maps for scripts and styles. For more information, see https://angular.io/guide/workspace-config#source-map-configuration. + +### ssl + +Default: `false` + +Type: `boolean` + +Serve using HTTPS. + +### sslCert + +Type: `string` + +SSL certificate to use for serving HTTPS. + +### sslKey + +Type: `string` + +SSL key to use for serving HTTPS. + +### ~~vendorChunk~~ + +Type: `boolean` + +**Deprecated:** Use the "vendorChunk" option in the browser builder instead. + +Generate a seperate bundle containing only vendor libraries. This option should only used for development. + +### verbose + +Type: `boolean` + +Adds more details to output logging. + +### watch + +Default: `true` + +Type: `boolean` + +Rebuild on change. diff --git a/docs/map.json b/docs/map.json index 83976a77c3..b42d4945c2 100644 --- a/docs/map.json +++ b/docs/map.json @@ -481,6 +481,11 @@ "name": "webpack-browser executor", "id": "webpack-browser", "file": "angular/api-angular/executors/webpack-browser" + }, + { + "name": "webpack-server executor", + "id": "webpack-server", + "file": "angular/api-angular/executors/webpack-server" } ] }, @@ -1642,6 +1647,11 @@ "name": "webpack-browser executor", "id": "webpack-browser", "file": "react/api-angular/executors/webpack-browser" + }, + { + "name": "webpack-server executor", + "id": "webpack-server", + "file": "react/api-angular/executors/webpack-server" } ] }, @@ -2767,6 +2777,11 @@ "name": "webpack-browser executor", "id": "webpack-browser", "file": "node/api-angular/executors/webpack-browser" + }, + { + "name": "webpack-server executor", + "id": "webpack-server", + "file": "node/api-angular/executors/webpack-server" } ] }, diff --git a/docs/node/api-angular/executors/webpack-server.md b/docs/node/api-angular/executors/webpack-server.md new file mode 100644 index 0000000000..fa57a72a73 --- /dev/null +++ b/docs/node/api-angular/executors/webpack-server.md @@ -0,0 +1,212 @@ +# webpack-server + +Serves a browser application with support for a custom webpack configuration. + +Options can be configured in `workspace.json` when defining the executor, or when invoking it. +Read more about how to use executors and the CLI here: https://nx.dev/node/getting-started/nx-cli#running-tasks. + +## Options + +### browserTarget (_**required**_) + +Type: `string` + +A browser builder target to serve in the format of `project:target[:configuration]`. You can also pass in more than one configuration name as a comma-separated list. Example: `project:target:production,staging`. + +### allowedHosts + +Type: `array` + +List of hosts that are allowed to access the dev server. + +### ~~aot~~ + +Type: `boolean` + +**Deprecated:** Use the "aot" option in the browser builder instead. + +Build using Ahead of Time compilation. + +### ~~baseHref~~ + +Type: `string` + +**Deprecated:** Use the "baseHref" option in the browser builder instead. + +Base url for the application being built. + +### ~~commonChunk~~ + +Type: `boolean` + +**Deprecated:** Use the "commonChunk" option in the browser builder instead. + +Generate a seperate bundle containing code used across multiple bundles. + +### ~~deployUrl~~ + +Type: `string` + +**Deprecated:** Use the "deployUrl" option in the browser builder instead. + +URL where files will be deployed. + +### disableHostCheck + +Default: `false` + +Type: `boolean` + +Don't verify connected clients are part of allowed hosts. + +### hmr + +Default: `false` + +Type: `boolean` + +Enable hot module replacement. + +### ~~hmrWarning~~ + +Default: `true` + +Type: `boolean` + +**Deprecated:** No longer has an effect. + +Show a warning when the --hmr option is enabled. + +### host + +Default: `localhost` + +Type: `string` + +Host to listen on. + +### liveReload + +Default: `true` + +Type: `boolean` + +Whether to reload the page on change, using live-reload. + +### open + +Alias(es): o + +Default: `false` + +Type: `boolean` + +Opens the url in default browser. + +### ~~optimization~~ + +Type: `boolean` + +**Deprecated:** Use the "optimization" option in the browser builder instead. + +Enables optimization of the build output. Including minification of scripts and styles, tree-shaking, dead-code elimination, tree-shaking and fonts inlining. For more information, see https://angular.io/guide/workspace-config#optimization-configuration. + +### poll + +Type: `number` + +Enable and define the file watching poll time period in milliseconds. + +### port + +Default: `4200` + +Type: `number` + +Port to listen on. + +### ~~progress~~ + +Type: `boolean` + +**Deprecated:** Use the "progress" option in the browser builder instead. + +Log progress to the console while building. + +### proxyConfig + +Type: `string` + +Proxy configuration file. For more information, see https://angular.io/guide/build#proxying-to-a-backend-server. + +### publicHost + +Type: `string` + +The URL that the browser client (or live-reload client, if enabled) should use to connect to the development server. Use for a complex dev server setup, such as one with reverse proxies. + +### servePath + +Type: `string` + +The pathname where the app will be served. + +### ~~servePathDefaultWarning~~ + +Default: `true` + +Type: `boolean` + +**Deprecated:** No longer has an effect. + +Show a warning when deploy-url/base-href use unsupported serve path values. + +### ~~sourceMap~~ + +Type: `boolean` + +**Deprecated:** Use the "sourceMap" option in the browser builder instead. + +Output source maps for scripts and styles. For more information, see https://angular.io/guide/workspace-config#source-map-configuration. + +### ssl + +Default: `false` + +Type: `boolean` + +Serve using HTTPS. + +### sslCert + +Type: `string` + +SSL certificate to use for serving HTTPS. + +### sslKey + +Type: `string` + +SSL key to use for serving HTTPS. + +### ~~vendorChunk~~ + +Type: `boolean` + +**Deprecated:** Use the "vendorChunk" option in the browser builder instead. + +Generate a seperate bundle containing only vendor libraries. This option should only used for development. + +### verbose + +Type: `boolean` + +Adds more details to output logging. + +### watch + +Default: `true` + +Type: `boolean` + +Rebuild on change. diff --git a/docs/react/api-angular/executors/webpack-server.md b/docs/react/api-angular/executors/webpack-server.md new file mode 100644 index 0000000000..c5d99ebb3b --- /dev/null +++ b/docs/react/api-angular/executors/webpack-server.md @@ -0,0 +1,212 @@ +# webpack-server + +Serves a browser application with support for a custom webpack configuration. + +Options can be configured in `workspace.json` when defining the executor, or when invoking it. +Read more about how to use executors and the CLI here: https://nx.dev/react/getting-started/nx-cli#running-tasks. + +## Options + +### browserTarget (_**required**_) + +Type: `string` + +A browser builder target to serve in the format of `project:target[:configuration]`. You can also pass in more than one configuration name as a comma-separated list. Example: `project:target:production,staging`. + +### allowedHosts + +Type: `array` + +List of hosts that are allowed to access the dev server. + +### ~~aot~~ + +Type: `boolean` + +**Deprecated:** Use the "aot" option in the browser builder instead. + +Build using Ahead of Time compilation. + +### ~~baseHref~~ + +Type: `string` + +**Deprecated:** Use the "baseHref" option in the browser builder instead. + +Base url for the application being built. + +### ~~commonChunk~~ + +Type: `boolean` + +**Deprecated:** Use the "commonChunk" option in the browser builder instead. + +Generate a seperate bundle containing code used across multiple bundles. + +### ~~deployUrl~~ + +Type: `string` + +**Deprecated:** Use the "deployUrl" option in the browser builder instead. + +URL where files will be deployed. + +### disableHostCheck + +Default: `false` + +Type: `boolean` + +Don't verify connected clients are part of allowed hosts. + +### hmr + +Default: `false` + +Type: `boolean` + +Enable hot module replacement. + +### ~~hmrWarning~~ + +Default: `true` + +Type: `boolean` + +**Deprecated:** No longer has an effect. + +Show a warning when the --hmr option is enabled. + +### host + +Default: `localhost` + +Type: `string` + +Host to listen on. + +### liveReload + +Default: `true` + +Type: `boolean` + +Whether to reload the page on change, using live-reload. + +### open + +Alias(es): o + +Default: `false` + +Type: `boolean` + +Opens the url in default browser. + +### ~~optimization~~ + +Type: `boolean` + +**Deprecated:** Use the "optimization" option in the browser builder instead. + +Enables optimization of the build output. Including minification of scripts and styles, tree-shaking, dead-code elimination, tree-shaking and fonts inlining. For more information, see https://angular.io/guide/workspace-config#optimization-configuration. + +### poll + +Type: `number` + +Enable and define the file watching poll time period in milliseconds. + +### port + +Default: `4200` + +Type: `number` + +Port to listen on. + +### ~~progress~~ + +Type: `boolean` + +**Deprecated:** Use the "progress" option in the browser builder instead. + +Log progress to the console while building. + +### proxyConfig + +Type: `string` + +Proxy configuration file. For more information, see https://angular.io/guide/build#proxying-to-a-backend-server. + +### publicHost + +Type: `string` + +The URL that the browser client (or live-reload client, if enabled) should use to connect to the development server. Use for a complex dev server setup, such as one with reverse proxies. + +### servePath + +Type: `string` + +The pathname where the app will be served. + +### ~~servePathDefaultWarning~~ + +Default: `true` + +Type: `boolean` + +**Deprecated:** No longer has an effect. + +Show a warning when deploy-url/base-href use unsupported serve path values. + +### ~~sourceMap~~ + +Type: `boolean` + +**Deprecated:** Use the "sourceMap" option in the browser builder instead. + +Output source maps for scripts and styles. For more information, see https://angular.io/guide/workspace-config#source-map-configuration. + +### ssl + +Default: `false` + +Type: `boolean` + +Serve using HTTPS. + +### sslCert + +Type: `string` + +SSL certificate to use for serving HTTPS. + +### sslKey + +Type: `string` + +SSL key to use for serving HTTPS. + +### ~~vendorChunk~~ + +Type: `boolean` + +**Deprecated:** Use the "vendorChunk" option in the browser builder instead. + +Generate a seperate bundle containing only vendor libraries. This option should only used for development. + +### verbose + +Type: `boolean` + +Adds more details to output logging. + +### watch + +Default: `true` + +Type: `boolean` + +Rebuild on change. diff --git a/packages/angular/executors.json b/packages/angular/executors.json index 14cc243909..98a548b1dc 100644 --- a/packages/angular/executors.json +++ b/packages/angular/executors.json @@ -19,6 +19,11 @@ "implementation": "./src/builders/webpack-browser/webpack-browser.impl", "schema": "./src/builders/webpack-browser/schema.json", "description": "Builds a browser application with support for incremental builds and custom webpack configuration." + }, + "webpack-server": { + "implementation": "./src/builders/webpack-server/webpack-server.impl", + "schema": "./src/builders/webpack-server/schema.json", + "description": "Serves a browser application with support for a custom webpack configuration." } }, "builders": { @@ -41,6 +46,11 @@ "implementation": "./src/builders/webpack-browser/webpack-browser.impl", "schema": "./src/builders/webpack-browser/schema.json", "description": "Builds a browser application with support for incremental builds and custom webpack configuration." + }, + "webpack-server": { + "implementation": "./src/builders/webpack-server/webpack-server.impl", + "schema": "./src/builders/webpack-server/schema.json", + "description": "Serves a browser application with support for a custom webpack configuration." } } } diff --git a/packages/angular/src/builders/webpack-server/lib/index.ts b/packages/angular/src/builders/webpack-server/lib/index.ts new file mode 100644 index 0000000000..f9451963f5 --- /dev/null +++ b/packages/angular/src/builders/webpack-server/lib/index.ts @@ -0,0 +1 @@ +export * from './normalize-options'; diff --git a/packages/angular/src/builders/webpack-server/lib/normalize-options.ts b/packages/angular/src/builders/webpack-server/lib/normalize-options.ts new file mode 100644 index 0000000000..b8cc2b3fd2 --- /dev/null +++ b/packages/angular/src/builders/webpack-server/lib/normalize-options.ts @@ -0,0 +1,12 @@ +import type { Schema } from '../schema'; + +export function normalizeOptions(schema: Schema): Schema { + return { + host: 'localhost', + port: 4200, + liveReload: true, + open: false, + ssl: false, + ...schema, + }; +} diff --git a/packages/angular/src/builders/webpack-server/schema.d.ts b/packages/angular/src/builders/webpack-server/schema.d.ts new file mode 100644 index 0000000000..fd8cc98166 --- /dev/null +++ b/packages/angular/src/builders/webpack-server/schema.d.ts @@ -0,0 +1,32 @@ +export interface Schema { + browserTarget: string; + port: number; + host: string; + proxyConfig?: string; + ssl: boolean; + sslKey?: string; + sslCert?: string; + headers?: Record; + open: boolean; + verbose?: boolean; + liveReload: boolean; + publicHost?: string; + allowedHosts?: string[]; + servePath?: string; + disableHostCheck?: boolean; + hmr?: boolean; + watch?: boolean; + hmrWarning?: boolean; + servePathDefaultWarning?: boolean; + optimization?: boolean | { scripts: boolean; styles: boolean }; + aot?: boolean; + sourceMap?: + | boolean + | { scripts: boolean; styles: boolean; hidden: boolean; vendor: boolean }; + vendorChunk?: boolean; + commonChunk?: boolean; + baseHref?: string; + deployUrl?: string; + progress?: boolean; + poll?: number; +} diff --git a/packages/angular/src/builders/webpack-server/schema.json b/packages/angular/src/builders/webpack-server/schema.json new file mode 100644 index 0000000000..131021814d --- /dev/null +++ b/packages/angular/src/builders/webpack-server/schema.json @@ -0,0 +1,206 @@ +{ + "$schema": "http://json-schema.org/draft-07/schema", + "title": "Webpack Server Target", + "description": "Dev Server target options for Build Facade.", + "type": "object", + "properties": { + "browserTarget": { + "type": "string", + "description": "A browser builder target to serve in the format of `project:target[:configuration]`. You can also pass in more than one configuration name as a comma-separated list. Example: `project:target:production,staging`.", + "pattern": "^[^:\\s]+:[^:\\s]+(:[^\\s]+)?$" + }, + "port": { + "type": "number", + "description": "Port to listen on.", + "default": 4200 + }, + "host": { + "type": "string", + "description": "Host to listen on.", + "default": "localhost" + }, + "proxyConfig": { + "type": "string", + "description": "Proxy configuration file. For more information, see https://angular.io/guide/build#proxying-to-a-backend-server." + }, + "ssl": { + "type": "boolean", + "description": "Serve using HTTPS.", + "default": false + }, + "sslKey": { + "type": "string", + "description": "SSL key to use for serving HTTPS." + }, + "sslCert": { + "type": "string", + "description": "SSL certificate to use for serving HTTPS." + }, + "headers": { + "type": "object", + "description": "Custom HTTP headers to be added to all responses.", + "propertyNames": { + "pattern": "^[-_A-Za-z0-9]+$" + }, + "additionalProperties": { + "type": "string" + } + }, + "open": { + "type": "boolean", + "description": "Opens the url in default browser.", + "default": false, + "alias": "o" + }, + "verbose": { + "type": "boolean", + "description": "Adds more details to output logging." + }, + "liveReload": { + "type": "boolean", + "description": "Whether to reload the page on change, using live-reload.", + "default": true + }, + "publicHost": { + "type": "string", + "description": "The URL that the browser client (or live-reload client, if enabled) should use to connect to the development server. Use for a complex dev server setup, such as one with reverse proxies." + }, + "allowedHosts": { + "type": "array", + "description": "List of hosts that are allowed to access the dev server.", + "default": [], + "items": { + "type": "string" + } + }, + "servePath": { + "type": "string", + "description": "The pathname where the app will be served." + }, + "disableHostCheck": { + "type": "boolean", + "description": "Don't verify connected clients are part of allowed hosts.", + "default": false + }, + "hmr": { + "type": "boolean", + "description": "Enable hot module replacement.", + "default": false + }, + "watch": { + "type": "boolean", + "description": "Rebuild on change.", + "default": true + }, + "hmrWarning": { + "type": "boolean", + "description": "Show a warning when the --hmr option is enabled.", + "default": true, + "x-deprecated": "No longer has an effect." + }, + "servePathDefaultWarning": { + "type": "boolean", + "description": "Show a warning when deploy-url/base-href use unsupported serve path values.", + "default": true, + "x-deprecated": "No longer has an effect." + }, + "optimization": { + "description": "Enables optimization of the build output. Including minification of scripts and styles, tree-shaking, dead-code elimination, tree-shaking and fonts inlining. For more information, see https://angular.io/guide/workspace-config#optimization-configuration.", + "x-user-analytics": 16, + "oneOf": [ + { + "type": "object", + "properties": { + "scripts": { + "type": "boolean", + "description": "Enables optimization of the scripts output.", + "default": true + }, + "styles": { + "type": "boolean", + "description": "Enables optimization of the styles output.", + "default": true + } + }, + "additionalProperties": false + }, + { + "type": "boolean" + } + ], + "x-deprecated": "Use the \"optimization\" option in the browser builder instead." + }, + "aot": { + "type": "boolean", + "description": "Build using Ahead of Time compilation.", + "x-user-analytics": 13, + "x-deprecated": "Use the \"aot\" option in the browser builder instead." + }, + "sourceMap": { + "description": "Output source maps for scripts and styles. For more information, see https://angular.io/guide/workspace-config#source-map-configuration.", + "oneOf": [ + { + "type": "object", + "properties": { + "scripts": { + "type": "boolean", + "description": "Output source maps for all scripts.", + "default": true + }, + "styles": { + "type": "boolean", + "description": "Output source maps for all styles.", + "default": true + }, + "hidden": { + "type": "boolean", + "description": "Output source maps used for error reporting tools.", + "default": false + }, + "vendor": { + "type": "boolean", + "description": "Resolve vendor packages source maps.", + "default": false + } + }, + "additionalProperties": false + }, + { + "type": "boolean" + } + ], + "x-deprecated": "Use the \"sourceMap\" option in the browser builder instead." + }, + "vendorChunk": { + "type": "boolean", + "description": "Generate a seperate bundle containing only vendor libraries. This option should only used for development.", + "x-deprecated": "Use the \"vendorChunk\" option in the browser builder instead." + }, + "commonChunk": { + "type": "boolean", + "description": "Generate a seperate bundle containing code used across multiple bundles.", + "x-deprecated": "Use the \"commonChunk\" option in the browser builder instead." + }, + "baseHref": { + "type": "string", + "description": "Base url for the application being built.", + "x-deprecated": "Use the \"baseHref\" option in the browser builder instead." + }, + "deployUrl": { + "type": "string", + "description": "URL where files will be deployed.", + "x-deprecated": "Use the \"deployUrl\" option in the browser builder instead." + }, + "progress": { + "type": "boolean", + "description": "Log progress to the console while building.", + "x-deprecated": "Use the \"progress\" option in the browser builder instead." + }, + "poll": { + "type": "number", + "description": "Enable and define the file watching poll time period in milliseconds." + } + }, + "additionalProperties": false, + "required": ["browserTarget"] +} diff --git a/packages/angular/src/builders/webpack-server/webpack-server.impl.ts b/packages/angular/src/builders/webpack-server/webpack-server.impl.ts new file mode 100644 index 0000000000..23690c2fca --- /dev/null +++ b/packages/angular/src/builders/webpack-server/webpack-server.impl.ts @@ -0,0 +1,58 @@ +import { BuilderContext, createBuilder } from '@angular-devkit/architect'; +import { JsonObject } from '@angular-devkit/core'; +import type { Schema } from './schema'; + +import { parseTargetString, joinPathFragments } from '@nrwl/devkit'; +import { Workspaces } from '@nrwl/tao/src/shared/workspace'; +import { + DevServerBuilderOptions, + serveWebpackBrowser, +} from '@angular-devkit/build-angular/src/dev-server'; +import { existsSync } from 'fs'; +import { merge } from 'webpack-merge'; +import { normalizeOptions } from './lib'; + +export function webpackServer(schema: Schema, context: BuilderContext) { + const options = normalizeOptions(schema); + const workspaceConfig = new Workspaces( + context.workspaceRoot + ).readWorkspaceConfiguration(); + + const parsedBrowserTarget = parseTargetString(options.browserTarget); + const buildTarget = + workspaceConfig.projects[parsedBrowserTarget.project].targets[ + parsedBrowserTarget.target + ]; + + const selectedConfiguration = parsedBrowserTarget.configuration + ? buildTarget.configurations[parsedBrowserTarget.configuration] + : buildTarget.configurations[buildTarget.defaultConfiguration]; + + const customWebpackConfig: { path: string } = + selectedConfiguration.customWebpackConfig ?? + buildTarget.options.customWebpackConfig; + + if (customWebpackConfig && customWebpackConfig.path) { + const pathToWebpackConfig = joinPathFragments( + context.workspaceRoot, + customWebpackConfig.path + ); + + if (existsSync(pathToWebpackConfig)) { + return serveWebpackBrowser(options as DevServerBuilderOptions, context, { + webpackConfiguration: (baseWebpackConfig) => { + const customWebpackConfiguration = require(pathToWebpackConfig); + return merge(baseWebpackConfig, customWebpackConfiguration); + }, + }); + } else { + throw new Error( + `Custom Webpack Config File Not Found!\nTo use a custom webpack config, please ensure the path to the custom webpack file is correct: \n${pathToWebpackConfig}` + ); + } + } + + return serveWebpackBrowser(options as DevServerBuilderOptions, context); +} + +export default createBuilder(webpackServer);