Skip to content

Commit fab246b

Browse files
committed
docs: keep comments short, plain and about the why
Trims the comments added with the profiling tests and the preprocessor fix, and writes the rule down in CLAUDE.md so it holds next time.
1 parent 6ff8ab7 commit fab246b

8 files changed

Lines changed: 33 additions & 65 deletions

File tree

CLAUDE.md

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -166,6 +166,11 @@ Run the whole thing: `npm run test:e2e`. One project: `npx playwright test --pro
166166
- Linting: oxlint, root config in `.oxlintrc.json`, per-package configs in `packages/<pkg>/.oxlintrc.json`
167167
- Doc comments on functions must be terse and follow JSDoc (`/** ... */` with `@param` / `@returns` where they add
168168
information). Write them only when they clarify non-obvious behavior; do not restate the signature.
169+
- Comments explain WHY, not what. The code already says what it does.
170+
- Keep comments as short as possible. One or two lines is usually enough. If you need a paragraph, the code probably
171+
needs the work instead.
172+
- Write them in plain English, the way you would explain it to the developer sitting next to you. No academic or
173+
research-paper tone, no long build-ups, no restating the obvious.
169174
- When there is an opportunity to create a shared utility for the code or the tests, YOU MUST DO SO.
170175
- Code duplication must be kept at A MINIMUM and should only be done when it makes sense in the context of the feature.
171176

packages/svelte/src/preprocessor.ts

Lines changed: 7 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -121,19 +121,13 @@ function escapeString(str: string): string {
121121
}
122122

123123
/**
124-
* The regex Svelte's own preprocessor uses to find script tags, copied verbatim from
125-
* `svelte/src/compiler/preprocess/index.js`. The leading comment alternative is load-bearing: it
126-
* consumes `<!-- ... -->` first, so a commented-out or documented `<script>` matches as a comment
127-
* rather than as a tag. Matching Svelte here is the point, because Svelte decides which tags reach
128-
* the `script` hook and the markup hook has to predict that exactly.
124+
* Copied from Svelte's own preprocessor, because Svelte decides which tags reach the script hook and
125+
* we have to agree with it. The `<!-- -->` branch is what stops a commented-out `<script>` counting.
129126
*/
130127
const REGEX_SCRIPT_OR_COMMENT =
131128
/<!--[^]*?-->|<script((?:\s+[^=>'"/\s]+=(?:"[^"]*"|'[^']*'|[^>\s]+)|\s+[^=>'"/\s]+)*\s*)(?:\/>|>([\S\s]*?)<\/script>)/g;
132129

133-
/**
134-
* Types Svelte still treats as an instance script. A tag carrying anything else (`application/ld+json`,
135-
* `importmap`, `text/template`) holds data rather than component code.
136-
*/
130+
/** Anything else (`application/ld+json`, `importmap`, ...) holds data, not component code. */
137131
const JAVASCRIPT_SCRIPT_TYPES = new Set([
138132
'text/javascript',
139133
'application/javascript',
@@ -147,7 +141,7 @@ const JAVASCRIPT_SCRIPT_TYPES = new Set([
147141
* i.e. a script that is not `<script module>` / `<script context="module">`.
148142
*/
149143
function hasInstanceScript(content: string): boolean {
150-
// matchAll clones the regex, so the shared `g` literal keeps no lastIndex between calls.
144+
// matchAll clones the regex, so the shared /g/ literal can't leak lastIndex between calls.
151145
for (const match of content.matchAll(REGEX_SCRIPT_OR_COMMENT)) {
152146
if (match[0].startsWith('<!--')) {
153147
continue;
@@ -162,10 +156,9 @@ function hasInstanceScript(content: string): boolean {
162156
}
163157

164158
/**
165-
* Svelte hands the `script` hook every script tag in the file, nested ones included, so a
166-
* `<script type="application/ld+json">` inside the markup arrives here looking like component code.
167-
* Prepending an import to one corrupts the data it holds. Skipping on an unrecognized type costs at
168-
* most a missing registration; injecting into one ships broken output.
159+
* Svelte passes us every script tag, nested ones too, so a JSON-LD block turns up here looking like
160+
* component code. Injecting into one would corrupt it, so when in doubt we skip: a missing
161+
* registration is cheaper than broken output.
169162
*/
170163
function isJavaScriptScript(attributes: Record<string, string | boolean>): boolean {
171164
const type = attributes.type;

packages/svelte/tests/fixtures/preprocessed/+layout.svelte

Lines changed: 1 addition & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,4 @@
1-
<!--
2-
Deliberately contains NO call to __flareProfileComponent. Everything under this directory is
3-
instrumented by the real preprocessor, configured in vitest.config.mts.
4-
-->
1+
<!-- No profiling code here on purpose. vitest.config.mts injects it. -->
52
<script lang="ts">
63
let { children }: { children?: () => unknown } = $props();
74
</script>
Lines changed: 1 addition & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,2 @@
1-
<!--
2-
No instance script at all. This is the markup-hook path: the preprocessor has to add the script
3-
block itself, and must not then inject a second time when the script hook runs over that block.
4-
Keep the words "script tag" out of this comment in their angle-bracket form; hasInstanceScript
5-
matches on raw text and would treat the mention as a real instance script.
6-
-->
1+
<!-- No script tag, so the markup hook has to add one. -->
72
<button data-testid="add-to-cart">Add to cart</button>

packages/svelte/tests/fixtures/preprocessed/Harness.svelte

Lines changed: 2 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,5 @@
1-
<!--
2-
Stands in for SvelteKit's generated root: it passes the page to the layout as a snippet, which is
3-
the shape the whole nesting design depends on. Its own name matches no allowlist entry, so it
4-
records no span and the layout parents straight to the active root.
5-
-->
1+
<!-- Stands in for SvelteKit's root: hands the page to the layout as a snippet. Not in the allowlist,
2+
so it records nothing itself. -->
63
<script lang="ts">
74
import Layout from './+layout.svelte';
85
import Page from './product/[id]/+page.svelte';

packages/svelte/tests/preprocessedRuntime.test.ts

Lines changed: 10 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -16,13 +16,9 @@ beforeEach(() => {
1616
});
1717

1818
/**
19-
* Everything else in this suite tests one half of the feature: preprocessor.test.ts asserts on the
20-
* string the preprocessor emits, profileComponent.test.ts calls __flareProfileComponent by hand. That
21-
* leaves the join between them untested, which is where a regression would actually hide: emit a call
22-
* the runtime no longer honours and both halves stay green while every span disappears.
23-
*
24-
* The fixtures under tests/fixtures/preprocessed/ contain no profiling code. The preprocessor is
25-
* installed over them in vitest.config.mts, so these assertions run against injected code only.
19+
* preprocessor.test.ts checks what we emit, profileComponent.test.ts calls the function directly.
20+
* Neither notices if the emitted call stops working, so that gap gets its own test. The fixtures hold
21+
* no profiling code; vitest.config.mts injects it.
2622
*/
2723
describe('preprocessor output at runtime', () => {
2824
it('records the documented pageload tree for components carrying no profiling code', async () => {
@@ -31,15 +27,13 @@ describe('preprocessor output at runtime', () => {
3127

3228
const byName = Object.fromEntries(fake.spans().map((span) => [span.name, span]));
3329

34-
// The names are the route-aware ones from the README table, produced end to end rather than
35-
// asserted against resolveProfileName in isolation. Compared as a set: onMount is bottom-up,
36-
// so the recording order is an implementation detail this assertion should not pin.
30+
// A set, because onMount runs bottom-up and we don't want to pin the recording order.
3731
expect(new Set(Object.keys(byName))).toEqual(new Set(['+layout', 'product/[id]/+page', 'AddToCartButton']));
3832

39-
// Harness matches no allowlist entry, so the layout parents straight to the active root.
33+
// Harness isn't in the allowlist, so the layout parents straight to the root.
4034
expect(byName['+layout']!.parent).toEqual({ traceId: 'T', parentSpanId: 'root' });
41-
// The page reaches the layout only because snippet content inherits the context of the
42-
// component that renders the snippet. This is the assertion that fails if that ever changes.
35+
// Only works because snippet content picks up the context of whoever renders it. If Svelte
36+
// ever changes that, this is the test that breaks.
4337
expect(byName['product/[id]/+page']!.parent).toEqual({
4438
traceId: 'T',
4539
parentSpanId: byName['+layout']!.spanId,
@@ -50,18 +44,16 @@ describe('preprocessor output at runtime', () => {
5044
});
5145
});
5246

53-
// AddToCartButton.svelte has no instance script, so the markup hook has to add a <script> block
54-
// and the script hook then runs over that same block. Without the double-injection guard this
55-
// component records two spans, or fails to compile on a duplicate declaration.
47+
// The markup hook adds a script block, then the script hook sees that same block. Without the
48+
// guard we'd inject twice.
5649
it('injects exactly once into a component with no instance script', async () => {
5750
render(Harness);
5851
await tick();
5952

6053
expect(fake.spans().filter((span) => span.name === 'AddToCartButton')).toHaveLength(1);
6154
});
6255

63-
// Only allowlisted components are instrumented. Harness renders and is a real component in the
64-
// tree, but matches nothing, so it must be invisible rather than recording an unnamed span.
56+
// Harness is a real component in the tree but matches nothing, so it should stay invisible.
6557
it('leaves unmatched components untouched', async () => {
6658
render(Harness);
6759
await tick();

packages/svelte/tests/preprocessor.test.ts

Lines changed: 3 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -358,13 +358,10 @@ describe('withFlareConfig — profileComponents', () => {
358358
});
359359
});
360360

361-
// Both bugs below come from treating a raw text match as a structural fact. Svelte decides what counts
362-
// as a script tag with the regex mirrored in REGEX_SCRIPT_OR_COMMENT, and it hands the `script` hook
363-
// every tag in the file rather than just the instance one.
361+
// Both cases below used to break because we matched raw text instead of matching what Svelte matches.
364362
describe('flarePreprocessor — script tags that only look like component code', () => {
365363
test('a <script> mentioned inside an HTML comment does not count as an instance script', async () => {
366-
// Svelte's regex consumes comments first, so this component reaches the script hook with no
367-
// instance script at all. Reading the mention as real leaves it silently uninstrumented.
364+
// Svelte skips comments, so this component has no instance script at all.
368365
const source = `<!-- replaced the old <script>console.log(1)</script> block -->\n<p>hi</p>`;
369366
const out = await preprocess(source, flarePreprocessor(), { filename: FAKE_FILE });
370367

@@ -382,8 +379,7 @@ describe('flarePreprocessor — script tags that only look like component code',
382379
expect((out.code.match(/__flare_prof__\(/g) || []).length).toBe(1);
383380
});
384381

385-
// A JSON-LD block is data. Prepending an ESM import to it produces invalid structured data in the
386-
// shipped page, which is worse than not instrumenting the component at all.
382+
// Injecting an import here would ship broken JSON-LD to the browser.
387383
test('leaves a nested non-JavaScript script untouched', async () => {
388384
const source = [
389385
'<script lang="ts">',
@@ -398,7 +394,6 @@ describe('flarePreprocessor — script tags that only look like component code',
398394
].join('\n');
399395
const out = await preprocess(source, flarePreprocessor(), { filename: FAKE_FILE });
400396

401-
// Injected once, into the instance script only.
402397
expect((out.code.match(/__flare_node__/g) || []).length).toBe(1);
403398
expect(out.code).toMatch(/<script type="application\/ld\+json">\s*\{"@type": "Product"\}/);
404399
expect(() => compile(out.code, { filename: FAKE_FILE })).not.toThrow();

packages/svelte/vitest.config.mts

Lines changed: 4 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -9,16 +9,10 @@ import { flarePreprocessor } from './src/preprocessor.js';
99

1010
const __dirname = dirname(fileURLToPath(import.meta.url));
1111

12-
// The REAL preprocessor, installed over the test compile so preprocessedRuntime.test.ts can assert on
13-
// what injected code actually does at runtime, not just on the string the preprocessor emits.
14-
//
15-
// Scoped by allowlist rather than by path: `componentTracking: false` plus a `profileComponents` list
16-
// that only tests/fixtures/preprocessed/* can satisfy means every other .svelte file in this package
17-
// is returned untouched, so the rest of the suite compiles exactly as before.
18-
//
19-
// `importSource` points at the module itself instead of '@flareapp/svelte' so the test does not
20-
// depend on dist being built. That the published entries re-export the symbol is covered separately
21-
// by webEntry, injectEntry and sveltekitContract.
12+
// Runs the real preprocessor so preprocessedRuntime.test.ts can check what the injected code does,
13+
// not just what the preprocessor prints. The allowlist is what keeps it scoped: nothing outside
14+
// tests/fixtures/preprocessed/ matches, so the rest of the suite compiles unchanged. importSource
15+
// points straight at the module so the test doesn't need a build.
2216
const preprocessedFixtures = flarePreprocessor({
2317
componentTracking: false,
2418
profileComponents: [/\+(page|layout)(@[^/]*)?$/, 'AddToCartButton'],

0 commit comments

Comments
 (0)