Skip to content

Commit

Permalink
fix(vite-plugin-angular): cache style URLs by matched styleUrls exp…
Browse files Browse the repository at this point in the history
…ression (#571)
  • Loading branch information
arturovt authored Jul 28, 2023
1 parent e6e015c commit ce348f6
Showing 1 changed file with 37 additions and 23 deletions.
60 changes: 37 additions & 23 deletions packages/vite-plugin-angular/src/lib/component-resolvers.ts
Original file line number Diff line number Diff line change
Expand Up @@ -8,10 +8,12 @@ export function hasStyleUrls(code: string) {
}

interface StyleUrlsCacheEntry {
code: string;
matchedStyleUrls: string;
styleUrls: string[];
}

const EMPTY_ARRAY: any[] = [];

export class StyleUrlsResolver {
// These resolvers may be called multiple times during the same
// compilation for the same files. Caching is required because these
Expand All @@ -20,32 +22,44 @@ export class StyleUrlsResolver {
private readonly styleUrlsCache = new Map<string, StyleUrlsCacheEntry>();

resolve(code: string, id: string): string[] {
const entry = this.styleUrlsCache.get(id);
if (entry?.code === code) {
return entry.styleUrls;
}
const styleUrlsExecArray = styleUrlsRE.exec(code);

const styleUrlsGroup = styleUrlsRE.exec(code);

if (Array.isArray(styleUrlsGroup) && styleUrlsGroup[0]) {
const styleUrls = styleUrlsGroup[0].replace(
/(styleUrls|\:|\s|\[|\]|"|')/g,
''
);
const styleUrlPaths = styleUrls?.split(',') || [];

const newEntry = {
code,
styleUrls: styleUrlPaths.map((styleUrlPath) => {
return `${styleUrlPath}|${resolve(dirname(id), styleUrlPath)}`;
}),
};
if (styleUrlsExecArray === null) {
return EMPTY_ARRAY;
}

this.styleUrlsCache.set(id, newEntry);
return newEntry.styleUrls;
// Given the code is the following:
// @Component({
// styleUrls: [
// './app.component.scss'
// ]
// })
// The `matchedStyleUrls` would result in: `styleUrls: [\n './app.component.scss'\n ]`.
const [matchedStyleUrls] = styleUrlsExecArray;
const entry = this.styleUrlsCache.get(id);
// We're using `matchedStyleUrls` as a key because the code may be changing continuously,
// resulting in the resolver being called multiple times. While the code changes, the
// `styleUrls` may remain constant, which means we should always return the previously
// resolved style URLs.
if (entry?.matchedStyleUrls === matchedStyleUrls) {
return entry.styleUrls;
}

return [];
// The `styleUrls` property is an array, which means we may have a list of
// CSS files provided there. Let `matchedStyleUrls` be equal to the following:
// "styleUrls: [\n './app.component.scss',\n '../global.scss'\n ]"
const styleUrlPaths = matchedStyleUrls
.replace(/(styleUrls|\:|\s|\[|\]|"|')/g, '')
// The above replace will result in the following:
// "./app.component.scss,../global.scss"
.split(',');

const styleUrls = styleUrlPaths.map((styleUrlPath) => {
return `${styleUrlPath}|${resolve(dirname(id), styleUrlPath)}`;
});

this.styleUrlsCache.set(matchedStyleUrls, { styleUrls, matchedStyleUrls });
return styleUrls;
}
}

Expand Down

0 comments on commit ce348f6

Please sign in to comment.