-
Notifications
You must be signed in to change notification settings - Fork 12k
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
feat(@angular-devkit/build-angular): initial development server for e…
…sbuild-based builder When using the experimental esbuild-based browser application builder, the preexisting `dev-server` builder can now be used to execute the `ng serve` command with an esbuild bundled application. The `dev-server` builder provides an alternate development server that will execute the `browser-esbuild` builder to build the application and then serve the output files within a development server with live reload capabilities. This is an initial integration of the development server. It is not yet fully optimized and all features may not yet be supported. SSL, in particular, does not yet work. If already using the esbuild-based builder, no additional changes to the Angular configuration are required. The `dev-server` builder will automatically detect the application builder and use the relevent development server implementation. As the esbuild-based browser application builders is currently experimental, using the development server in this mode is also considered experimental.
- Loading branch information
1 parent
aae34fc
commit 8c55030
Showing
8 changed files
with
412 additions
and
17 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
98 changes: 98 additions & 0 deletions
98
packages/angular_devkit/build_angular/src/builders/dev-server/load-proxy-config.ts
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,98 @@ | ||
/** | ||
* @license | ||
* Copyright Google LLC All Rights Reserved. | ||
* | ||
* Use of this source code is governed by an MIT-style license that can be | ||
* found in the LICENSE file at https://angular.io/license | ||
*/ | ||
|
||
import { existsSync } from 'node:fs'; | ||
import { readFile } from 'node:fs/promises'; | ||
import { extname, resolve } from 'node:path'; | ||
import { pathToFileURL } from 'node:url'; | ||
import { assertIsError } from '../../utils/error'; | ||
import { loadEsmModule } from '../../utils/load-esm'; | ||
|
||
export async function loadProxyConfiguration(root: string, proxyConfig: string | undefined) { | ||
if (!proxyConfig) { | ||
return undefined; | ||
} | ||
|
||
const proxyPath = resolve(root, proxyConfig); | ||
|
||
if (!existsSync(proxyPath)) { | ||
throw new Error(`Proxy configuration file ${proxyPath} does not exist.`); | ||
} | ||
|
||
switch (extname(proxyPath)) { | ||
case '.json': { | ||
const content = await readFile(proxyPath, 'utf-8'); | ||
|
||
const { parse, printParseErrorCode } = await import('jsonc-parser'); | ||
const parseErrors: import('jsonc-parser').ParseError[] = []; | ||
const proxyConfiguration = parse(content, parseErrors, { allowTrailingComma: true }); | ||
|
||
if (parseErrors.length > 0) { | ||
let errorMessage = `Proxy configuration file ${proxyPath} contains parse errors:`; | ||
for (const parseError of parseErrors) { | ||
const { line, column } = getJsonErrorLineColumn(parseError.offset, content); | ||
errorMessage += `\n[${line}, ${column}] ${printParseErrorCode(parseError.error)}`; | ||
} | ||
throw new Error(errorMessage); | ||
} | ||
|
||
return proxyConfiguration; | ||
} | ||
case '.mjs': | ||
// Load the ESM configuration file using the TypeScript dynamic import workaround. | ||
// Once TypeScript provides support for keeping the dynamic import this workaround can be | ||
// changed to a direct dynamic import. | ||
return (await loadEsmModule<{ default: unknown }>(pathToFileURL(proxyPath))).default; | ||
case '.cjs': | ||
return require(proxyPath); | ||
default: | ||
// The file could be either CommonJS or ESM. | ||
// CommonJS is tried first then ESM if loading fails. | ||
try { | ||
return require(proxyPath); | ||
} catch (e) { | ||
assertIsError(e); | ||
if (e.code === 'ERR_REQUIRE_ESM') { | ||
// Load the ESM configuration file using the TypeScript dynamic import workaround. | ||
// Once TypeScript provides support for keeping the dynamic import this workaround can be | ||
// changed to a direct dynamic import. | ||
return (await loadEsmModule<{ default: unknown }>(pathToFileURL(proxyPath))).default; | ||
} | ||
|
||
throw e; | ||
} | ||
} | ||
} | ||
|
||
/** | ||
* Calculates the line and column for an error offset in the content of a JSON file. | ||
* @param location The offset error location from the beginning of the content. | ||
* @param content The full content of the file containing the error. | ||
* @returns An object containing the line and column | ||
*/ | ||
function getJsonErrorLineColumn(offset: number, content: string) { | ||
if (offset === 0) { | ||
return { line: 1, column: 1 }; | ||
} | ||
|
||
let line = 0; | ||
let position = 0; | ||
// eslint-disable-next-line no-constant-condition | ||
while (true) { | ||
++line; | ||
|
||
const nextNewline = content.indexOf('\n', position); | ||
This comment has been minimized.
Sorry, something went wrong. |
||
if (nextNewline === -1 || nextNewline > offset) { | ||
break; | ||
} | ||
|
||
position = nextNewline + 1; | ||
} | ||
|
||
return { line, column: offset - position + 1 }; | ||
} |
Oops, something went wrong.
I think it's possible to have
\r\n
as new line delimiters