Skip to content

Commit c12901b

Browse files
committed
fix(analog): use the Vite root for routes and build meta in Nx workspaces
The Routes tab, get-routes and the Dashboard SSR and Analog fields resolved the Analog app from the working directory, so in an Nx workspace with several Analog apps they described the first app under apps/ instead of the one Vite serves. They now share the Vite root with the Analog tab through servedAnalogRoot().
1 parent 521460a commit c12901b

7 files changed

Lines changed: 50 additions & 14 deletions

File tree

‎apps/docs/src/content/inspectors/analog.md‎

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -96,7 +96,7 @@ Checks grouped by rule, each with a fix:
9696
### Supported layouts
9797

9898
- **Single app**: `package.json`, `vite.config.ts` and `src/app/pages` in one folder. The build output is read from `dist/analog/public`.
99-
- **Nx workspace**: the app lives in `apps/<name>` and `package.json` sits at the workspace root. The scan uses the Vite root, or the first folder under `apps/` whose `vite.config` calls `analog()` when the tools run from the workspace root. `package.json` is looked up from the app folder upward, and the build output is read from `dist/apps/<name>/analog/public`.
99+
- **Nx workspace**: the app lives in `apps/<name>` and `package.json` sits at the workspace root. The scan uses the Vite root, or the first folder under `apps/` whose `vite.config` calls `analog()` when the tools run from the workspace root. The **Routes** tab, `get-routes` and the **SSR** and **Analog** fields on the **Dashboard** read the same app, so they match this tab. `package.json` is looked up from the app folder upward, and the build output is read from `dist/apps/<name>/analog/public`.
100100

101101
### Render mode rules
102102

‎packages/ng-devtools/src/__tests__/analog-scan.test.ts‎

Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,10 +9,14 @@ import {
99
frontmatter,
1010
lintAnalog,
1111
scanAnalog,
12+
servedAnalogRoot,
13+
setAnalogRoot,
1214
toRawPath,
1315
toSegment,
1416
} from '../rpc/analog-scan.ts';
17+
import { getBuildMeta } from '../rpc/build-meta.ts';
1518
import { extractRoutes } from '../rpc/get-routes.ts';
19+
import { scan } from '../rpc/__tests__/scan.ts';
1620
import { BASE_FILES, BROKEN_FILES, makeProject } from './analog-fixture.ts';
1721

1822
describe('Analog route rules', () => {
@@ -219,6 +223,33 @@ describe('Analog route rules', () => {
219223
);
220224
});
221225

226+
it('uses the Vite root for every surface when an Nx workspace has several Analog apps', async () => {
227+
const { 'package.json': pkg, ...app } = BASE_FILES;
228+
const inApp = (name: string) =>
229+
Object.fromEntries(Object.entries(app).map(([file, text]) => [`apps/${name}/${file}`, text]));
230+
const ws = makeProject(
231+
{
232+
'package.json': pkg,
233+
'nx.json': '{}',
234+
'apps/blog/src/app/pages/blog-only.page.ts': app['src/app/pages/index.page.ts']!,
235+
'apps/blog/vite.config.ts': `import analog from '@analogjs/platform';\nexport default { plugins: [analog({ ssr: false })] };\n`,
236+
},
237+
inApp('shop'),
238+
);
239+
const shop = join(ws, 'apps/shop');
240+
setAnalogRoot(shop);
241+
try {
242+
expect(servedAnalogRoot(ws)).toBe(shop);
243+
const files = extractRoutes(ws).map((r) => r.file);
244+
expect(files).toContain('apps/shop/src/app/pages/(marketing)/pricing.page.ts');
245+
expect(files.some((file) => file.startsWith('apps/blog/'))).toBe(false);
246+
expect(await scan(getBuildMeta, ws)).toMatchObject({ ssr: true, analog: '2.7.5' });
247+
} finally {
248+
setAnalogRoot(undefined);
249+
}
250+
expect(servedAnalogRoot(ws)).toBe(join(ws, 'apps/blog'));
251+
});
252+
222253
it('does not treat a plain Angular app as Analog because the workspace root installs Analog', () => {
223254
const { 'package.json': pkg, ...app } = BASE_FILES;
224255
const ws = makeProject(

‎packages/ng-devtools/src/rpc/analog-register.ts‎

Lines changed: 2 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@ import {
77
recentCalls,
88
type AnalogCall,
99
} from '../analog-server-log.ts';
10-
import { explainUrl, scanAnalog, type AnalogProject } from './analog-scan.ts';
10+
import { explainUrl, scanAnalog, servedAnalogRoot, type AnalogProject } from './analog-scan.ts';
1111
import {
1212
analogApiRoutesText,
1313
analogContentText,
@@ -36,7 +36,6 @@ const PAGE_TTL_MS = 15_000;
3636

3737
let disposeAnalog: (() => void) | undefined;
3838
let analogOwner: unknown;
39-
let viteRoot: string | undefined;
4039

4140
interface Scoped {
4241
rpc: {
@@ -105,10 +104,6 @@ export async function callApi(request: ApiRequest, origin = devOrigin()): Promis
105104
}
106105
}
107106

108-
export function setAnalogRoot(root: string | undefined) {
109-
viteRoot = root;
110-
}
111-
112107
export function stopAnalog(owner?: unknown) {
113108
if (owner !== undefined && owner !== analogOwner) return;
114109
disposeAnalog?.();
@@ -165,7 +160,7 @@ export async function registerAnalog(
165160
let cache: { at: number; project: AnalogProject } | null = null;
166161
const project = () => {
167162
if (!cache || Date.now() - cache.at > SCAN_CACHE_MS) {
168-
cache = { at: Date.now(), project: scanAnalog(viteRoot ?? ctx.cwd) };
163+
cache = { at: Date.now(), project: scanAnalog(servedAnalogRoot(ctx.cwd)) };
169164
}
170165
return cache.project;
171166
};

‎packages/ng-devtools/src/rpc/analog-scan.ts‎

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -491,6 +491,16 @@ function hasAnalogConfig(dir: string): boolean {
491491
return !!file && /\banalog\s*\(/.test(stripComments(read(join(dir, file))));
492492
}
493493

494+
let viteRoot: string | undefined;
495+
496+
export function setAnalogRoot(root: string | undefined) {
497+
viteRoot = root;
498+
}
499+
500+
export function servedAnalogRoot(cwd: string): string {
501+
return analogRoot(viteRoot ?? cwd);
502+
}
503+
494504
export function analogRoot(cwd: string): string {
495505
if (existsSync(join(cwd, 'src/app/pages')) || hasAnalogConfig(cwd)) return cwd;
496506
let names: string[];

‎packages/ng-devtools/src/rpc/build-meta.ts‎

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@ import { describable } from './agent-schema.ts';
44
import { existsSync, readFileSync } from 'node:fs';
55
import { createRequire } from 'node:module';
66
import { dirname, join } from 'node:path';
7-
import { analogConfig, analogRoot, analogVersion } from './analog-scan.ts';
7+
import { analogConfig, analogVersion, servedAnalogRoot } from './analog-scan.ts';
88

99
const BuildMetaSchema = v.object({
1010
angularVersion: v.string(),
@@ -37,7 +37,7 @@ export const getBuildMeta = defineRpcFunction({
3737
installedVersion(ctx.cwd, 'typescript') ?? versionFromRange(deps['typescript']);
3838

3939
const project = mainProject(ctx.cwd);
40-
const app = analogRoot(ctx.cwd);
40+
const app = servedAnalogRoot(ctx.cwd);
4141
const analog = analogVersion(app);
4242
return {
4343
angularVersion,

‎packages/ng-devtools/src/rpc/get-routes.ts‎

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
import { defineRpcFunction } from 'devframe';
22
import * as v from 'valibot';
33
import { describable } from './agent-schema.ts';
4-
import { analogRoot, analogVersion, buildRoutes, flattenRoutes } from './analog-scan.ts';
4+
import { analogVersion, buildRoutes, flattenRoutes, servedAnalogRoot } from './analog-scan.ts';
55
import { existsSync, readFileSync, readdirSync, statSync } from 'node:fs';
66
import { dirname, isAbsolute, join, relative } from 'node:path';
77
import {
@@ -47,7 +47,7 @@ export const getRoutes = defineRpcFunction({
4747
});
4848

4949
export function extractRoutes(cwd: string): ExtractedRoute[] {
50-
const app = analogRoot(cwd);
50+
const app = servedAnalogRoot(cwd);
5151
const routes: ExtractedRoute[] = analogVersion(app) ? analogRoutes(app, cwd) : [];
5252
const files: string[] = [];
5353
for (const root of sourceRoots(cwd)) {

‎packages/ng-devtools/src/vite.ts‎

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -6,8 +6,8 @@ import type { WsOriginRegistry } from 'devframe/rpc/transports/ws-server';
66
import { isLoopbackHostname } from 'devframe/utils/origin';
77
import { NG_DEVTOOLS_HUB_BASE, initNgDevtoolsHub } from './hub.ts';
88
import { analogMiddleware, setDevOrigin } from './analog-server-log.ts';
9-
import { analogConfig } from './rpc/analog-scan.ts';
10-
import { setAnalogRoot, stopAnalog } from './rpc/analog-register.ts';
9+
import { analogConfig, setAnalogRoot } from './rpc/analog-scan.ts';
10+
import { stopAnalog } from './rpc/analog-register.ts';
1111
import { httpRegistry } from './http-rules.ts';
1212
import { pickNgDevtoolsConfig, resolveNgDevtoolsConfig, type NgDevtoolsConfig } from './config.ts';
1313

0 commit comments

Comments
 (0)