Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
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
Original file line number Diff line number Diff line change
Expand Up @@ -87,6 +87,69 @@ describeBuilder(buildApplication, APPLICATION_BUILDER_INFO, (harness) => {
);
});

it('recovers from error in SCSS partial after fix on rebuild using @use', async () => {
harness.useTarget('build', {
...BASE_OPTIONS,
watch: true,
styles: ['src/styles.scss'],
});

await harness.writeFile('src/styles.scss', "@use './variables' as v;\nh1 { color: v.$primary; }");
await harness.writeFile('src/variables.scss', '$primary: aqua;');

await harness.executeWithCases(
[
async ({ result }) => {
expect(result?.success).toBe(true);
harness.expectFile('dist/browser/styles.css').content.toContain('color: aqua');

// Introduce a syntax error in the imported partial
await harness.writeFile('src/variables.scss', '$primary: aqua\n$broken;');
},
async ({ result }) => {
expect(result?.success).toBe(false);

// Fix the partial — the cached error should be cleared
await harness.writeFile('src/variables.scss', '$primary: blue;');
},
({ result }) => {
expect(result?.success).toBe(true);
harness.expectFile('dist/browser/styles.css').content.not.toContain('color: aqua');
harness.expectFile('dist/browser/styles.css').content.toContain('color: blue');
},
],
{ outputLogsOnFailure: false },
);
});

it('recovers from error in SCSS partial after fix on initial build using @use', async () => {
harness.useTarget('build', {
...BASE_OPTIONS,
watch: true,
styles: ['src/styles.scss'],
});

await harness.writeFile('src/styles.scss', "@use './variables' as v;\nh1 { color: v.$primary; }");
// Start with an error in the partial
await harness.writeFile('src/variables.scss', '$primary: aqua\n$broken;');

await harness.executeWithCases(
[
async ({ result }) => {
expect(result?.success).toBe(false);

// Fix the partial
await harness.writeFile('src/variables.scss', '$primary: aqua;');
},
({ result }) => {
expect(result?.success).toBe(true);
harness.expectFile('dist/browser/styles.css').content.toContain('color: aqua');
},
],
{ outputLogsOnFailure: false },
);
});
Comment on lines +90 to +151
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

medium

There's some duplication of test data strings (like SCSS content and expected CSS output) between the two new tests. To improve maintainability and readability, consider defining these repeated strings as constants at the top of the describe block or before the tests. For example:

const SCSS_AQUA = '$primary: aqua;';
const SCSS_BROKEN = '$primary: aqua\n$broken;';
const CSS_AQUA = 'color: aqua';


it('rebuilds dependent Sass stylesheets after error on initial build from import', async () => {
harness.useTarget('build', {
...BASE_OPTIONS,
Expand Down
10 changes: 8 additions & 2 deletions packages/angular/build/src/tools/esbuild/load-result-cache.ts
Original file line number Diff line number Diff line change
Expand Up @@ -70,7 +70,13 @@ export class MemoryLoadResultCache implements LoadResultCache {
}

invalidate(path: string): boolean {
const affectedPaths = this.#fileDependencies.get(path);
// Normalize the path to match how watch file paths are stored in `put()`.
// Without normalization, paths produced by `fileURLToPath()` or `path.join()`
// during error reporting may use different separators than the normalized paths
// stored as keys in `#fileDependencies`, causing the lookup to fail and leaving
// stale error results in the cache after the source file is corrected.
const normalizedPath = normalize(path);
const affectedPaths = this.#fileDependencies.get(normalizedPath);
let found = false;

if (affectedPaths) {
Expand All @@ -79,7 +85,7 @@ export class MemoryLoadResultCache implements LoadResultCache {
found = true;
}
}
this.#fileDependencies.delete(path);
this.#fileDependencies.delete(normalizedPath);
}

return found;
Expand Down
Loading