Skip to content

Commit 3c91721

Browse files
committed
feat(@angular/build): integrate Chrome automatic workspace folders
This commit integrates automatic Chrome DevTools workspace folder connection into the vite dev-server process, leveraging the experimental feature available in Chrome Canary, as described in the Chrome DevTools documentation https://chromium.googlesource.com/devtools/devtools-frontend/+/main/docs/ecosystem/automatic_workspace_folders.md
1 parent 896d98a commit 3c91721

File tree

4 files changed

+59
-0
lines changed

4 files changed

+59
-0
lines changed

packages/angular/build/src/builders/dev-server/vite-server.ts

+1
Original file line numberDiff line numberDiff line change
@@ -908,6 +908,7 @@ export async function setupServer(
908908
templateUpdates,
909909
ssrMode,
910910
resetComponentUpdates: () => templateUpdates.clear(),
911+
projectRoot: serverOptions.projectRoot,
911912
}),
912913
createRemoveIdPrefixPlugin(externalMetadata.explicitBrowser),
913914
await createAngularSsrTransformPlugin(serverOptions.workspaceRoot),
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,51 @@
1+
/**
2+
* @license
3+
* Copyright Google LLC All Rights Reserved.
4+
*
5+
* Use of this source code is governed by an MIT-style license that can be
6+
* found in the LICENSE file at https://angular.dev/license
7+
*/
8+
9+
import { randomUUID } from 'node:crypto';
10+
import { mkdirSync, readFileSync, writeFileSync } from 'node:fs';
11+
import { join } from 'node:path';
12+
import type { Connect } from 'vite';
13+
14+
const CHROME_DEVTOOLS_ROUTE = '/.well-known/appspecific/com.chrome.devtools.json';
15+
16+
export function createChromeDevtoolsMiddleware(
17+
cacheDir: string,
18+
projectRoot: string,
19+
): Connect.NextHandleFunction {
20+
let devtoolsConfig: string;
21+
const devtoolsConfigPath = join(cacheDir, 'com.chrome.devtools.json');
22+
23+
return function chromeDevtoolsMiddleware(req, res, next) {
24+
if (req.url !== CHROME_DEVTOOLS_ROUTE) {
25+
next();
26+
27+
return;
28+
}
29+
30+
// We store the UUID and re-use it to ensure Chrome does not repeatedly ask for permissions when restarting the dev server.
31+
try {
32+
devtoolsConfig ??= readFileSync(devtoolsConfigPath, 'utf-8');
33+
} catch {
34+
const devtoolsConfigJson = {
35+
workspace: {
36+
root: projectRoot,
37+
uuid: randomUUID(),
38+
},
39+
};
40+
41+
devtoolsConfig = JSON.stringify(devtoolsConfigJson, undefined, 2);
42+
try {
43+
mkdirSync(cacheDir, { recursive: true });
44+
writeFileSync(devtoolsConfigPath, devtoolsConfig);
45+
} catch {}
46+
}
47+
48+
res.setHeader('Content-Type', 'application/json');
49+
res.end(devtoolsConfig);
50+
};
51+
}

packages/angular/build/src/tools/vite/middlewares/index.ts

+1
Original file line numberDiff line numberDiff line change
@@ -15,3 +15,4 @@ export {
1515
} from './ssr-middleware';
1616
export { createAngularHeadersMiddleware } from './headers-middleware';
1717
export { createAngularComponentMiddleware } from './component-middleware';
18+
export { createChromeDevtoolsMiddleware } from './chrome-devtools-middleware';

packages/angular/build/src/tools/vite/plugins/setup-middlewares-plugin.ts

+6
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,7 @@ import {
1717
createAngularIndexHtmlMiddleware,
1818
createAngularSsrExternalMiddleware,
1919
createAngularSsrInternalMiddleware,
20+
createChromeDevtoolsMiddleware,
2021
} from '../middlewares';
2122
import { AngularMemoryOutputFiles, AngularOutputAssets } from '../utils';
2223

@@ -54,6 +55,7 @@ interface AngularSetupMiddlewaresPluginOptions {
5455
templateUpdates: Map<string, string>;
5556
ssrMode: ServerSsrMode;
5657
resetComponentUpdates: () => void;
58+
projectRoot: string;
5759
}
5860

5961
async function createEncapsulateStyle(): Promise<
@@ -99,6 +101,10 @@ export function createAngularSetupMiddlewaresPlugin(
99101
),
100102
);
101103

104+
server.middlewares.use(
105+
createChromeDevtoolsMiddleware(server.config.cacheDir, options.projectRoot),
106+
);
107+
102108
extensionMiddleware?.forEach((middleware) => server.middlewares.use(middleware));
103109

104110
// Returning a function, installs middleware after the main transform middleware but

0 commit comments

Comments
 (0)