Skip to content

Commit

Permalink
fix(vite-plugin-angular): extract templateUrls using AST (#887)
Browse files Browse the repository at this point in the history
  • Loading branch information
rlmestre committed Feb 10, 2024
1 parent b525d0d commit f91ab02
Show file tree
Hide file tree
Showing 2 changed files with 69 additions and 20 deletions.
56 changes: 52 additions & 4 deletions packages/vite-plugin-angular/src/lib/component-resolvers.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -136,7 +136,24 @@ describe('component-resolvers', () => {
const resolvedTemplateUrls = templateUrlsResolver.resolve(code, id);

expect(hasTemplateUrl(code)).toBeTruthy();
expect(thePathsAreEqual(resolvedTemplateUrls, [actualUrl]));
expect(thePathsAreEqual(resolvedTemplateUrls, [actualUrl])).toBe(true);
});

it('should handle templateUrls with single quotes and route params', () => {
const code = `
@Component({
templateUrl: './[param].component.html'
})
export class MyComponent {}
`;

const actualUrl =
'./[param].component.html|/path/to/src/[param].component.html';
const templateUrlsResolver = new TemplateUrlsResolver();
const resolvedTemplateUrls = templateUrlsResolver.resolve(code, id);

expect(hasTemplateUrl(code)).toBeTruthy();
expect(thePathsAreEqual(resolvedTemplateUrls, [actualUrl])).toBe(true);
});

it('should handle templateUrls with double quotes', () => {
Expand All @@ -153,7 +170,24 @@ describe('component-resolvers', () => {
const resolvedTemplateUrls = templateUrlsResolver.resolve(code, id);

expect(hasTemplateUrl(code)).toBeTruthy();
expect(thePathsAreEqual(resolvedTemplateUrls, [actualUrl]));
expect(thePathsAreEqual(resolvedTemplateUrls, [actualUrl])).toBe(true);
});

it('should handle templateUrls with double quotes and route params', () => {
const code = `
@Component({
templateUrl: "./[param].component.html"
})
export class MyComponent {}
`;

const actualUrl =
'./[param].component.html|/path/to/src/[param].component.html';
const templateUrlsResolver = new TemplateUrlsResolver();
const resolvedTemplateUrls = templateUrlsResolver.resolve(code, id);

expect(hasTemplateUrl(code)).toBeTruthy();
expect(thePathsAreEqual(resolvedTemplateUrls, [actualUrl])).toBe(true);
});

it('should handle multiple templateUrls in a single file', () => {
Expand All @@ -166,7 +200,7 @@ describe('component-resolvers', () => {
@Component({
templateUrl: "./app1.component.html"
})
export class MyComponentTwo {}
export class MyComponentTwo {}
`;

const actualUrl1 =
Expand All @@ -179,7 +213,21 @@ describe('component-resolvers', () => {
expect(hasTemplateUrl(code)).toBeTruthy();
expect(
thePathsAreEqual(resolvedTemplateUrls, [actualUrl1, actualUrl2])
);
).toBe(true);
});

it('should ignore commented out templateUrls', () => {
const code = `
@Component({
//templateUrl: './app.component.html'
})
export class MyComponent {}
`;

const templateUrlsResolver = new TemplateUrlsResolver();
const resolvedTemplateUrls = templateUrlsResolver.resolve(code, id);

expect(resolvedTemplateUrls).toHaveLength(0);
});
});
});
Expand Down
33 changes: 17 additions & 16 deletions packages/vite-plugin-angular/src/lib/component-resolvers.ts
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
import { dirname, resolve } from 'path';
import { Project, SyntaxKind } from 'ts-morph';
import { normalizePath } from 'vite';

const styleUrlsRE = /styleUrls\s*:\s*\[([^\[]*?)\]|styleUrl:\s*["'](.*?)["']/;
const templateUrlRE = /templateUrl:\s*["'](.*?)["']/g;

export function hasStyleUrls(code: string) {
return styleUrlsRE.test(code);
Expand Down Expand Up @@ -71,6 +71,18 @@ export function hasTemplateUrl(code: string) {
return code.includes('templateUrl:');
}

export function getTemplateUrls(code: string) {
const project = new Project({ useInMemoryFileSystem: true });
const sourceFile = project.createSourceFile('cmp.ts', code);
return sourceFile
.getDescendantsOfKind(SyntaxKind.PropertyAssignment)
.filter((property) => property.getName() === 'templateUrl')
.map((property) =>
property.getInitializer()?.getText().replace(/['"]/g, '')
)
.filter((url): url is string => url !== undefined);
}

interface TemplateUrlsCacheEntry {
code: string;
templateUrlPaths: string[];
Expand All @@ -88,21 +100,10 @@ export class TemplateUrlsResolver {
return entry.templateUrlPaths;
}

const templateUrlGroup = Array.from(code.matchAll(templateUrlRE));
const templateUrlPaths: string[] = [];

if (Array.isArray(templateUrlGroup)) {
templateUrlGroup.forEach((trg) => {
const resolvedTemplatePath = trg[1].replace(
/templateUrl|\s|'|"|\:|,/g,
''
);
const templateUrlPath = normalizePath(
resolve(dirname(id), resolvedTemplatePath).replace(/\\/g, '/')
);
templateUrlPaths.push(`${resolvedTemplatePath}|${templateUrlPath}`);
});
}
const templateUrlPaths = getTemplateUrls(code).map(
(url) =>
`${url}|${normalizePath(resolve(dirname(id), url).replace(/\\/g, '/'))}`
);

this.templateUrlsCache.set(id, { code, templateUrlPaths });
return templateUrlPaths;
Expand Down

0 comments on commit f91ab02

Please sign in to comment.