From 687a6c7eca740a98129196908689a44c181b33a5 Mon Sep 17 00:00:00 2001 From: Alan Agius Date: Wed, 5 Jun 2024 14:50:50 +0000 Subject: [PATCH] feat(@angular/build): add `--inspect` option to the dev-server This commit introduces an `--inspect` option to the dev-server, enabling debugging of server-side code when using SSR or SSG. This option is equivalent to `node --inspect=[[host:]port]`. Usage examples: ``` $ ng serve --inspect $ ng serve --inspect 9999 $ ng serve --inspect localhost:9999 ``` Closes: #27773 --- goldens/public-api/angular/build/index.api.md | 1 + .../angular_devkit/build_angular/index.api.md | 1 + .../build/src/builders/dev-server/options.ts | 24 +++++++++++++++++++ .../build/src/builders/dev-server/schema.json | 11 +++++++++ .../src/builders/dev-server/vite-server.ts | 7 ++++++ .../src/builders/dev-server/options.ts | 24 +++++++++++++++++++ .../src/builders/dev-server/schema.json | 11 +++++++++ 7 files changed, 79 insertions(+) diff --git a/goldens/public-api/angular/build/index.api.md b/goldens/public-api/angular/build/index.api.md index 288fc13c0001..e4b9025be1e6 100644 --- a/goldens/public-api/angular/build/index.api.md +++ b/goldens/public-api/angular/build/index.api.md @@ -114,6 +114,7 @@ export interface DevServerBuilderOptions { }; hmr?: boolean; host?: string; + inspect?: Inspect; liveReload?: boolean; open?: boolean; poll?: number; diff --git a/goldens/public-api/angular_devkit/build_angular/index.api.md b/goldens/public-api/angular_devkit/build_angular/index.api.md index f6e3c54dead2..1f1eb258270a 100644 --- a/goldens/public-api/angular_devkit/build_angular/index.api.md +++ b/goldens/public-api/angular_devkit/build_angular/index.api.md @@ -126,6 +126,7 @@ export interface DevServerBuilderOptions { }; hmr?: boolean; host?: string; + inspect?: Inspect; liveReload?: boolean; open?: boolean; poll?: number; diff --git a/packages/angular/build/src/builders/dev-server/options.ts b/packages/angular/build/src/builders/dev-server/options.ts index 3ddd991a215d..f208991ee9a6 100644 --- a/packages/angular/build/src/builders/dev-server/options.ts +++ b/packages/angular/build/src/builders/dev-server/options.ts @@ -63,6 +63,29 @@ export async function normalizeOptions( } } + let inspect: false | { host?: string; port?: number } = false; + const inspectRaw = options.inspect; + if (inspectRaw === true || inspectRaw === '' || inspectRaw === 'true') { + inspect = { + host: undefined, + port: undefined, + }; + } else if (typeof inspectRaw === 'string' && inspectRaw !== 'false') { + const port = +inspectRaw; + if (isFinite(port)) { + inspect = { + host: undefined, + port, + }; + } else { + const [host, port] = inspectRaw.split(':'); + inspect = { + host, + port: isNaN(+port) ? undefined : +port, + }; + } + } + // Initial options to keep const { host, @@ -104,5 +127,6 @@ export async function normalizeOptions( sslKey, // Prebundling defaults to true but requires caching to function prebundle: cacheOptions.enabled && !optimization.scripts && prebundle, + inspect, }; } diff --git a/packages/angular/build/src/builders/dev-server/schema.json b/packages/angular/build/src/builders/dev-server/schema.json index dee154eb8fc6..3adce45eb71a 100644 --- a/packages/angular/build/src/builders/dev-server/schema.json +++ b/packages/angular/build/src/builders/dev-server/schema.json @@ -79,6 +79,17 @@ "type": "number", "description": "Enable and define the file watching poll time period in milliseconds." }, + "inspect": { + "default": false, + "description": "Activate debugging inspector. This option only has an effect when 'SSR' or 'SSG' are enabled.", + "oneOf": [ + { + "type": "string", + "description": "Activate the inspector on host and port in the format of `[[host:]port]`. See the security warning in https://nodejs.org/docs/latest-v22.x/api/cli.html#warning-binding-inspector-to-a-public-ipport-combination-is-insecure regarding the host parameter usage." + }, + { "type": "boolean" } + ] + }, "prebundle": { "description": "Enable and control the Vite-based development server's prebundling capabilities. To enable prebundling, the Angular CLI cache must also be enabled.", "default": true, diff --git a/packages/angular/build/src/builders/dev-server/vite-server.ts b/packages/angular/build/src/builders/dev-server/vite-server.ts index e4b4e655f66d..73352428e3ba 100644 --- a/packages/angular/build/src/builders/dev-server/vite-server.ts +++ b/packages/angular/build/src/builders/dev-server/vite-server.ts @@ -10,6 +10,7 @@ import type { BuilderContext } from '@angular-devkit/architect'; import type { Plugin } from 'esbuild'; import assert from 'node:assert'; import { readFile } from 'node:fs/promises'; +import inspector from 'node:inspector'; import { builtinModules } from 'node:module'; import { basename, join } from 'node:path'; import type { Connect, DepOptimizationConfig, InlineConfig, ViteDevServer } from 'vite'; @@ -262,6 +263,12 @@ export async function* serveWithVite( 'NOTE: Raw file sizes do not reflect development server per-request transformations.', ); + if (browserOptions.ssr && serverOptions.inspect) { + const { host, port } = serverOptions.inspect as { host?: string; port?: number }; + inspector.open(port, host, true); + context.addTeardown(() => inspector.close()); + } + const { root = '' } = await context.getProjectMetadata(projectName); const projectRoot = join(context.workspaceRoot, root as string); const browsers = getSupportedBrowsers(projectRoot, context.logger); diff --git a/packages/angular_devkit/build_angular/src/builders/dev-server/options.ts b/packages/angular_devkit/build_angular/src/builders/dev-server/options.ts index 5607a1263a18..7a5a8d38947c 100644 --- a/packages/angular_devkit/build_angular/src/builders/dev-server/options.ts +++ b/packages/angular_devkit/build_angular/src/builders/dev-server/options.ts @@ -61,6 +61,29 @@ export async function normalizeOptions( } } + let inspect: false | { host?: string; port?: number } = false; + const inspectRaw = options.inspect; + if (inspectRaw === true || inspectRaw === '' || inspectRaw === 'true') { + inspect = { + host: undefined, + port: undefined, + }; + } else if (typeof inspectRaw === 'string' && inspectRaw !== 'false') { + const port = +inspectRaw; + if (isFinite(port)) { + inspect = { + host: undefined, + port, + }; + } else { + const [host, port] = inspectRaw.split(':'); + inspect = { + host, + port: isNaN(+port) ? undefined : +port, + }; + } + } + // Initial options to keep const { host, @@ -110,5 +133,6 @@ export async function normalizeOptions( forceEsbuild, // Prebundling defaults to true but requires caching to function prebundle: cacheOptions.enabled && !optimization.scripts && (prebundle ?? true), + inspect, }; } diff --git a/packages/angular_devkit/build_angular/src/builders/dev-server/schema.json b/packages/angular_devkit/build_angular/src/builders/dev-server/schema.json index bb7b85737b71..5796dd04e895 100644 --- a/packages/angular_devkit/build_angular/src/builders/dev-server/schema.json +++ b/packages/angular_devkit/build_angular/src/builders/dev-server/schema.json @@ -102,6 +102,17 @@ "type": "number", "description": "Enable and define the file watching poll time period in milliseconds." }, + "inspect": { + "default": false, + "description": "Activate debugging inspector. This option only has an effect when 'SSR' or 'SSG' are enabled.", + "oneOf": [ + { + "type": "string", + "description": "Activate the inspector on host and port in the format of `[[host:]port]`. See the security warning in https://nodejs.org/docs/latest-v22.x/api/cli.html#warning-binding-inspector-to-a-public-ipport-combination-is-insecure regarding the host parameter usage." + }, + { "type": "boolean" } + ] + }, "forceEsbuild": { "type": "boolean", "description": "Force the development server to use the 'browser-esbuild' builder when building. This is a developer preview option for the esbuild-based build system.",