diff --git a/package.json b/package.json index ab224e8d0ed1..794afe5bb62c 100644 --- a/package.json +++ b/package.json @@ -112,6 +112,7 @@ "@types/node-fetch": "^2.1.6", "@types/npm-package-arg": "^6.1.0", "@types/pacote": "^11.1.3", + "@types/picomatch": "^2.3.0", "@types/pidusage": "^2.0.1", "@types/progress": "^2.0.3", "@types/resolve": "^1.17.1", @@ -181,6 +182,7 @@ "ora": "5.4.1", "pacote": "15.1.3", "parse5-html-rewriting-stream": "7.0.0", + "picomatch": "2.3.1", "pidtree": "^0.6.0", "pidusage": "^3.0.0", "piscina": "3.2.0", diff --git a/packages/angular_devkit/build_angular/BUILD.bazel b/packages/angular_devkit/build_angular/BUILD.bazel index 4d316ec983ab..5868ff2d3276 100644 --- a/packages/angular_devkit/build_angular/BUILD.bazel +++ b/packages/angular_devkit/build_angular/BUILD.bazel @@ -136,6 +136,7 @@ ts_library( "@npm//@types/less", "@npm//@types/loader-utils", "@npm//@types/node", + "@npm//@types/picomatch", "@npm//@types/semver", "@npm//@types/text-table", "@npm//@vitejs/plugin-basic-ssl", diff --git a/packages/angular_devkit/build_angular/package.json b/packages/angular_devkit/build_angular/package.json index 2ddc5b300f85..1f3378485c25 100644 --- a/packages/angular_devkit/build_angular/package.json +++ b/packages/angular_devkit/build_angular/package.json @@ -49,6 +49,7 @@ "open": "8.4.2", "ora": "5.4.1", "parse5-html-rewriting-stream": "7.0.0", + "picomatch": "2.3.1", "piscina": "3.2.0", "postcss": "8.4.23", "postcss-loader": "7.2.4", diff --git a/packages/angular_devkit/build_angular/src/builders/dev-server/load-proxy-config.ts b/packages/angular_devkit/build_angular/src/builders/dev-server/load-proxy-config.ts index 9d8b29f17cce..f27f388df570 100644 --- a/packages/angular_devkit/build_angular/src/builders/dev-server/load-proxy-config.ts +++ b/packages/angular_devkit/build_angular/src/builders/dev-server/load-proxy-config.ts @@ -6,10 +6,12 @@ * found in the LICENSE file at https://angular.io/license */ +import { hasMagic as isDynamicPattern } from 'glob'; import { existsSync } from 'node:fs'; import { readFile } from 'node:fs/promises'; import { extname, resolve } from 'node:path'; import { pathToFileURL } from 'node:url'; +import { parse as parseGlob } from 'picomatch'; import { assertIsError } from '../../utils/error'; import { loadEsmModule } from '../../utils/load-esm'; @@ -69,6 +71,21 @@ export async function loadProxyConfiguration(root: string, proxyConfig: string | } } +/** + * Converts glob patterns to regular expressions to support Vite's proxy option. + * @param proxy A proxy configuration object. + */ +export function normalizeProxyConfiguration(proxy: Record) { + // TODO: Consider upstreaming glob support + for (const key of Object.keys(proxy)) { + if (isDynamicPattern(key)) { + const { output } = parseGlob(key); + proxy[`^${output}$`] = proxy[key]; + delete proxy[key]; + } + } +} + /** * 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. diff --git a/packages/angular_devkit/build_angular/src/builders/dev-server/vite-server.ts b/packages/angular_devkit/build_angular/src/builders/dev-server/vite-server.ts index 4cbbc7b5916b..537306094df6 100644 --- a/packages/angular_devkit/build_angular/src/builders/dev-server/vite-server.ts +++ b/packages/angular_devkit/build_angular/src/builders/dev-server/vite-server.ts @@ -18,7 +18,7 @@ import path from 'node:path'; import { InlineConfig, ViteDevServer, createServer, normalizePath } from 'vite'; import { buildEsbuildBrowser } from '../browser-esbuild'; import type { Schema as BrowserBuilderOptions } from '../browser-esbuild/schema'; -import { loadProxyConfiguration } from './load-proxy-config'; +import { loadProxyConfiguration, normalizeProxyConfiguration } from './load-proxy-config'; import type { NormalizedDevServerOptions } from './options'; import type { DevServerBuilderOutput } from './webpack-server'; @@ -182,6 +182,9 @@ export async function setupServer( serverOptions.workspaceRoot, serverOptions.proxyConfig, ); + if (proxy) { + normalizeProxyConfiguration(proxy); + } const configuration: InlineConfig = { configFile: false, diff --git a/yarn.lock b/yarn.lock index 1930b006a225..5b1ddb08bd35 100644 --- a/yarn.lock +++ b/yarn.lock @@ -183,6 +183,20 @@ dependencies: tslib "^2.3.0" +"@angular/compiler-cli@16.0.0": + version "16.0.0" + resolved "https://registry.yarnpkg.com/@angular/compiler-cli/-/compiler-cli-16.0.0.tgz#eadcbc65c82c90c663c57bd012f132480bcae218" + integrity sha512-oyJzxiTHxziv7mD0QuA7K6tpDoL6YNGPkquKjeJjNVZvUrodGsvJ8xHO4ydmjK3nMu2ET1YarsdI8bRp4vp/7w== + dependencies: + "@babel/core" "7.19.3" + "@jridgewell/sourcemap-codec" "^1.4.14" + chokidar "^3.0.0" + convert-source-map "^1.5.1" + reflect-metadata "^0.1.2" + semver "^7.0.0" + tslib "^2.3.0" + yargs "^17.2.1" + "@angular/compiler-cli@16.0.0-next.7": version "16.0.0-next.7" resolved "https://registry.yarnpkg.com/@angular/compiler-cli/-/compiler-cli-16.0.0-next.7.tgz#b99504ede7e4e3620dc5087b83a357ec8ad79aac" @@ -197,6 +211,13 @@ tslib "^2.3.0" yargs "^17.2.1" +"@angular/compiler@16.0.0": + version "16.0.0" + resolved "https://registry.yarnpkg.com/@angular/compiler/-/compiler-16.0.0.tgz#9039e29e420ef119f02fb7ec9621bfc897679fac" + integrity sha512-xtg+KRvSeB9DUzMDtvlaRGKv+Y0MERsz+JOoqV9H4606ThNz5h8ih6fEhVKYqG100o7GhdJaVFO+vlr2/edUHA== + dependencies: + tslib "^2.3.0" + "@angular/compiler@16.0.0-next.7": version "16.0.0-next.7" resolved "https://registry.yarnpkg.com/@angular/compiler/-/compiler-16.0.0-next.7.tgz#15058e4390defb5db094d64e1a2f9c9587691533" @@ -3464,6 +3485,11 @@ dependencies: parse5 "*" +"@types/picomatch@^2.3.0": + version "2.3.0" + resolved "https://registry.yarnpkg.com/@types/picomatch/-/picomatch-2.3.0.tgz#75db5e75a713c5a83d5b76780c3da84a82806003" + integrity sha512-O397rnSS9iQI4OirieAtsDqvCj4+3eY1J+EPdNTKuHuRWIfUoGyzX294o8C4KJYaLqgSrd2o60c5EqCU8Zv02g== + "@types/pidusage@^2.0.1": version "2.0.2" resolved "https://registry.yarnpkg.com/@types/pidusage/-/pidusage-2.0.2.tgz#3f8c4b19ba7ea438a733d093661e92b60e5f88ee" @@ -9676,7 +9702,7 @@ picocolors@^1.0.0: resolved "https://registry.yarnpkg.com/picocolors/-/picocolors-1.0.0.tgz#cb5bdc74ff3f51892236eaf79d68bc44564ab81c" integrity sha512-1fygroTLlHu66zi26VoTDv8yRgm0Fccecssto+MhsZ0D/DGW2sm8E8AjW7NU5VVTRt5GxbeZ5qBuJr+HyLYkjQ== -picomatch@^2.0.4, picomatch@^2.2.1, picomatch@^2.3.1: +picomatch@2.3.1, picomatch@^2.0.4, picomatch@^2.2.1, picomatch@^2.3.1: version "2.3.1" resolved "https://registry.yarnpkg.com/picomatch/-/picomatch-2.3.1.tgz#3ba3833733646d9d3e4995946c1365a67fb07a42" integrity sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA==