Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
26 commits
Select commit Hold shift + click to select a range
3de0537
test(vite-plugin-nitro): add snapshot test for Vite config mutations
benpsnyder Apr 13, 2026
8826989
feat(vite-plugin-angular): enhance debugging documentation and improv…
benpsnyder Apr 13, 2026
6f72fa1
feat: add error handling for @reference in comments and improve direc…
benpsnyder Apr 13, 2026
43a5438
chore: update dependencies and configurations for Docusaurus and Angu…
benpsnyder Apr 13, 2026
70263db
chore: update debugging documentation with additional package overrid…
benpsnyder Apr 13, 2026
efcb7f2
chore: update debugging documentation to clarify usage of catalog and…
benpsnyder Apr 13, 2026
e76e35a
docs: enhance documentation on duplicate analog() registrations and S…
benpsnyder Apr 14, 2026
9f39aa7
Merge remote-tracking branch 'origin/alpha' into feat/support-snyder-…
benpsnyder Apr 14, 2026
18312c0
Merge remote-tracking branch 'origin/alpha' into feat/support-snyder-…
benpsnyder Apr 14, 2026
229b9e4
chore: update comments for clarity in Angular and Nitro plugins, and …
benpsnyder Apr 14, 2026
3155d19
feat: enhance configuration handling and improve test stability by cl…
benpsnyder Apr 14, 2026
e0b491b
chore: refine comments and enhance test stability in Angular and Nitr…
benpsnyder Apr 14, 2026
71b31a9
feat: improve handling of CSS comments and references, ensuring quote…
benpsnyder Apr 14, 2026
69af095
feat: add function to detect @reference text in comments and refine C…
benpsnyder Apr 14, 2026
ac4a4ca
feat: refactor CSS directive handling by extracting utility functions…
benpsnyder Apr 14, 2026
ac2dd07
feat: implement TailwindReferenceError handling in JIT plugin and aug…
benpsnyder Apr 14, 2026
00a43bd
fix: update console warning implementation in JIT plugin tests to ret…
benpsnyder Apr 14, 2026
49e660b
feat: add support for selectorless compilation in Angular plugin, enh…
benpsnyder Apr 15, 2026
6679136
Merge remote-tracking branch 'analogjs/alpha' into feat/snyder-suppor…
benpsnyder Apr 15, 2026
cb5feab
feat(vite-plugin-angular): enhance live reload plugin with Windows pa…
benpsnyder Apr 15, 2026
638d30e
feat(vite-plugin-angular): improve selectorless compilation handling …
benpsnyder Apr 15, 2026
c824525
refactor: narrow compilation API PR scope
benpsnyder Apr 15, 2026
8241741
docs: expand maintainer debugging workflow
benpsnyder Apr 15, 2026
6bad91e
docs: update debugging guide with techniques and improved descriptions
benpsnyder Apr 15, 2026
8f93220
feat(vite-plugin-angular): enhance live reload tests with additional …
benpsnyder Apr 15, 2026
7859392
Merge remote-tracking branch 'analogjs/alpha' into docs/debugging-tec…
benpsnyder Apr 15, 2026
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 3 additions & 1 deletion apps/docs-app/docs/guides/debugging.md
Original file line number Diff line number Diff line change
@@ -1,8 +1,10 @@
---
title: Debugging Techniques
description: Enable Analog debug logging, choose the right scopes, and debug local or GitHub-based Analog builds from another pnpm workspace.
sidebar_position: 4
---

# Debugging
# Debugging Techniques

Analog includes structured debug logging powered by [obug](https://www.npmjs.com/package/obug). You can enable debug output through the `debug` option in your Vite config or via the `DEBUG` environment variable.

Expand Down
100 changes: 85 additions & 15 deletions docs/debugging.md
Original file line number Diff line number Diff line change
Expand Up @@ -29,8 +29,8 @@ When debugging package changes in this monorepo, prefer the project-level Nx tar
# Focus on Angular plugin HMR/style behavior
DEBUG=analog:angular:hmr,analog:angular:styles pnpm nx test vite-plugin-angular

# Focus on platform routing output
DEBUG=analog:platform:routes pnpm nx build platform
# Focus on Compilation API inclusion, emit registration, and transform misses
DEBUG=analog:angular:compilation-api,analog:angular:compiler,analog:angular:emit pnpm nx test vite-plugin-angular

# Focus on the style-pipeline integration seam in a served app
DEBUG=analog:platform:style-pipeline,analog:angular:style-pipeline pnpm nx serve your-app
Expand All @@ -47,6 +47,16 @@ first so each `dist` folder contains its generated `package.json`. The source
package manifests still contain `catalog:` and `workspace:*` references that are
only rewritten during Analog's release-style build pipeline.

Prefer `link:` for active local debugging.

- `link:` keeps the consumer wired to the live built `dist` directories through
symlinks.
- `file:` can stage a snapshot into the consumer's `.pnpm` store. If you later
rebuild Analog without changing the version or specifier, pnpm may decide the
consumer install is already current and keep serving stale package contents.
- If you must use `file:`, always verify the active installed package contents,
not just the Analog source tree or `dist`.

### Local checkout example

`pnpm-workspace.yaml`
Expand All @@ -57,26 +67,26 @@ packages:
- 'libs/**'

overrides:
'@analogjs/platform': file:/path/to/analog/packages/platform/dist
'@analogjs/router': file:/path/to/analog/packages/router/dist
'@analogjs/vite-plugin-angular': file:/path/to/analog/packages/vite-plugin-angular/dist
'@analogjs/vite-plugin-nitro': file:/path/to/analog/packages/vite-plugin-nitro/dist
'@analogjs/vitest-angular': file:/path/to/analog/packages/vitest-angular/dist
'@analogjs/platform': link:/path/to/analog/packages/platform/dist
'@analogjs/router': link:/path/to/analog/packages/router/dist
'@analogjs/vite-plugin-angular': link:/path/to/analog/packages/vite-plugin-angular/dist
'@analogjs/vite-plugin-nitro': link:/path/to/analog/packages/vite-plugin-nitro/dist
'@analogjs/vitest-angular': link:/path/to/analog/packages/vitest-angular/dist
```

Root `package.json`

```json
{
"dependencies": {
"@analogjs/platform": "file:/path/to/analog/packages/platform/dist"
"@analogjs/platform": "link:/path/to/analog/packages/platform/dist"
},
"overrides": {
"@analogjs/platform": "file:/path/to/analog/packages/platform/dist",
"@analogjs/router": "file:/path/to/analog/packages/router/dist",
"@analogjs/vite-plugin-angular": "file:/path/to/analog/packages/vite-plugin-angular/dist",
"@analogjs/vite-plugin-nitro": "file:/path/to/analog/packages/vite-plugin-nitro/dist",
"@analogjs/vitest-angular": "file:/path/to/analog/packages/vitest-angular/dist"
"@analogjs/platform": "link:/path/to/analog/packages/platform/dist",
"@analogjs/router": "link:/path/to/analog/packages/router/dist",
"@analogjs/vite-plugin-angular": "link:/path/to/analog/packages/vite-plugin-angular/dist",
"@analogjs/vite-plugin-nitro": "link:/path/to/analog/packages/vite-plugin-nitro/dist",
"@analogjs/vitest-angular": "link:/path/to/analog/packages/vitest-angular/dist"
}
}
```
Expand All @@ -88,13 +98,52 @@ can still resolve transitive packages like `@analogjs/vite-plugin-angular` and
:::

:::note
pnpm currently does not allow `file:` entries in `catalog`, so local checkout
wiring needs direct `file:` overrides instead of `catalog:` indirection.
If the consumer workspace uses pnpm `catalog` entries, switch both the catalog
entries and the consumer overrides together. Mixed states are a common source of
confusing resolution behavior.
:::

If your app also uses other published Analog packages such as
`@analogjs/content` or `@analogjs/storybook-angular`, pin those the same way.

### Consumer validation checklist

After rebuilding Analog and refreshing the consumer install:

```bash
# Confirm the active install points at your local dist output
readlink node_modules/@analogjs/vite-plugin-angular

# Confirm the dev server is actually listening
curl -k -I https://localhost:4200/

# Confirm the shell HTML and stylesheet entry are present
lightpanda fetch \
--insecure-disable-tls-host-verification \
--wait-until done \
--wait-ms 12000 \
--dump html \
https://localhost:4200/ | sed -n '1,80p'
```

What to trust:

- `curl` is the fastest readiness check.
- `Lightpanda` is useful for reachability, shell HTML, and asset-presence smoke
tests.
- Treat the consumer dev server logs as the source of truth for Angular
compilation failures such as:
- `contains Angular decorators but is not in the TypeScript program`
- missing Angular emit output
- JIT fallback for `@Injectable()` / `@Component()`

What not to over-trust:

- `Lightpanda` can surface browser-client or HMR-transport behavior that does
not necessarily mean Analog failed to compile the app correctly.
- A successful Analog rebuild does not prove the consumer is executing the new
package code unless the consumer install is verified.

### GitHub branch example

If you want the same pattern from a GitHub branch instead of a local path, pnpm
Expand Down Expand Up @@ -136,6 +185,27 @@ those manifests still contain unresolved `catalog:` and `workspace:*`
specifiers.
:::

## Useful Angular Debug Scopes

Start with the smallest scope set that answers the question:

```bash
DEBUG=analog:angular:compilation-api,analog:angular:compiler pnpm nx serve your-app
DEBUG=analog:angular:emit pnpm nx serve your-app
DEBUG=analog:angular:emit:v pnpm nx serve your-app
```

Recommended interpretation:

- `analog:angular:compilation-api`
- wrapper tsconfig generation, initialization, high-level compilation flow
- `analog:angular:compiler`
- compiler-option mutations and transform-path decisions
- `analog:angular:emit`
- root-name expansion, emit registration, transform misses/hits
- `analog:angular:emit:v`
- per-file root lists, output registration, and normalized emitter lookups

## Notes

- Use the repo root unless you have a specific reason to run inside a package subdirectory.
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -479,6 +479,12 @@ describe('angular hmr style preprocessing', () => {
mkdirSync(join(tempWorkspaceRoot, 'libs/shared/extra/src'), {
recursive: true,
});
mkdirSync(join(tempWorkspaceRoot, 'libs/shared/directory/src'), {
recursive: true,
});
mkdirSync(join(tempWorkspaceRoot, 'libs/shared/wildcard/src/nested'), {
recursive: true,
});

writeFileSync(
join(tempWorkspaceRoot, 'src/app/app.component.ts'),
Expand All @@ -495,6 +501,17 @@ describe('angular hmr style preprocessing', () => {
join(tempWorkspaceRoot, 'libs/shared/extra/src/index.ts'),
'export const extra = true;\n',
);
writeFileSync(
join(tempWorkspaceRoot, 'libs/shared/directory/src/directory.ts'),
'export const directory = true;\n',
);
writeFileSync(
join(
tempWorkspaceRoot,
'libs/shared/wildcard/src/nested/wildcard.ts',
),
'export const wildcard = true;\n',
);
writeFileSync(
join(tempWorkspaceRoot, 'libs/shared/feature/tsconfig.lib.json'),
JSON.stringify(
Expand All @@ -517,7 +534,9 @@ describe('angular hmr style preprocessing', () => {
module: 'esnext',
moduleResolution: 'bundler',
paths: {
'@shared/directory': ['libs/shared/directory/src'],
'@shared/extra': ['libs/shared/extra/src/index.ts'],
'@shared/wildcard/*': ['libs/shared/wildcard/src/**/*'],
},
target: 'es2022',
},
Expand Down Expand Up @@ -562,8 +581,23 @@ describe('angular hmr style preprocessing', () => {
normalize(
join(tempWorkspaceRoot, 'libs/shared/extra/src/index.ts'),
),
normalize(
join(tempWorkspaceRoot, 'libs/shared/directory/src/directory.ts'),
),
normalize(
join(
tempWorkspaceRoot,
'libs/shared/wildcard/src/nested/wildcard.ts',
),
),
]),
);
expect(generatedConfig.files).not.toContain(
normalize(join(tempWorkspaceRoot, 'libs/shared/directory/src')),
);
expect(generatedConfig.files).not.toContain(
normalize(join(tempWorkspaceRoot, 'libs/shared/wildcard/src/nested')),
);
expect(generatedConfig.references).toEqual([
{ path: './libs/shared/feature/tsconfig.lib.json' },
]);
Expand Down
24 changes: 17 additions & 7 deletions packages/vite-plugin-angular/src/lib/angular-vite-plugin.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2402,6 +2402,15 @@ export function angular(options?: PluginOptions): Plugin[] {
: resolve(tsconfigDir, configuredBaseUrl)
: tsconfigDir;
const discoveredRoots = new Set<string>();
const addDiscoveredFiles = (pattern: string) => {
for (const match of globSync(pattern, {
dot: true,
absolute: true,
onlyFiles: true,
})) {
discoveredRoots.add(normalizePath(match));
}
};

for (const targets of Object.values(tsPaths)) {
for (const target of targets) {
Expand All @@ -2410,17 +2419,18 @@ export function angular(options?: PluginOptions): Plugin[] {
);

if (target.includes('*')) {
for (const match of globSync(resolvedTarget, {
dot: true,
absolute: true,
})) {
discoveredRoots.add(normalizePath(match));
}
addDiscoveredFiles(resolvedTarget);
continue;
}

if (existsSync(resolvedTarget)) {
discoveredRoots.add(resolvedTarget);
if (statSync(resolvedTarget).isDirectory()) {
addDiscoveredFiles(
normalizePath(join(resolvedTarget, '**/*.{ts,tsx,js,jsx}')),
);
} else {
discoveredRoots.add(normalizePath(resolvedTarget));
}
}
}
}
Expand Down
Loading