Skip to content

Commit 1b4e44a

Browse files
committed
fix(@ngtools/webpack): add template/styles as dependencies
So they are rebuilt when the resource changes. This PR refactor _replaceResources into _getResourceNodes which returns the AST nodes for templateUrl or styleUrls, then use that to get the URLs (values). For values that are not computable, we simply ignores.
1 parent 9b52253 commit 1b4e44a

File tree

2 files changed

+56
-11
lines changed

2 files changed

+56
-11
lines changed

packages/@ngtools/webpack/src/loader.ts

Lines changed: 55 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -274,9 +274,36 @@ function _getResourceRequest(element: ts.Expression, sourceFile: ts.SourceFile)
274274
function _replaceResources(refactor: TypeScriptFileRefactor): void {
275275
const sourceFile = refactor.sourceFile;
276276

277+
_getResourceNodes(refactor)
278+
// Get the full text of the initializer.
279+
.forEach((node: ts.PropertyAssignment) => {
280+
const key = _getContentOfKeyLiteral(sourceFile, node.name);
281+
282+
if (key == 'templateUrl') {
283+
refactor.replaceNode(node,
284+
`template: require(${_getResourceRequest(node.initializer, sourceFile)})`);
285+
} else if (key == 'styleUrls') {
286+
const arr = <ts.ArrayLiteralExpression[]>(
287+
refactor.findAstNodes(node, ts.SyntaxKind.ArrayLiteralExpression, false));
288+
if (!arr || arr.length == 0 || arr[0].elements.length == 0) {
289+
return;
290+
}
291+
292+
const initializer = arr[0].elements.map((element: ts.Expression) => {
293+
return _getResourceRequest(element, sourceFile);
294+
});
295+
refactor.replaceNode(node, `styles: [require(${initializer.join('), require(')})]`);
296+
}
297+
});
298+
}
299+
300+
301+
function _getResourceNodes(refactor: TypeScriptFileRefactor) {
302+
const { sourceFile } = refactor;
303+
277304
// Find all object literals.
278-
refactor.findAstNodes(sourceFile, ts.SyntaxKind.ObjectLiteralExpression, true)
279-
// Get all their property assignments.
305+
return refactor.findAstNodes(sourceFile, ts.SyntaxKind.ObjectLiteralExpression, true)
306+
// Get all their property assignments.
280307
.map(node => refactor.findAstNodes(node, ts.SyntaxKind.PropertyAssignment))
281308
// Flatten into a single array (from an array of array<property assignments>).
282309
.reduce((prev, curr) => curr ? prev.concat(curr) : prev, [])
@@ -289,26 +316,37 @@ function _replaceResources(refactor: TypeScriptFileRefactor): void {
289316
}
290317
return key == 'templateUrl' || key == 'styleUrls';
291318
})
292-
// Get the full text of the initializer.
293-
.forEach((node: ts.PropertyAssignment) => {
294-
const key = _getContentOfKeyLiteral(sourceFile, node.name);
319+
}
320+
321+
322+
function _getResourcesUrls(refactor: TypeScriptFileRefactor): string[] {
323+
return _getResourceNodes(refactor)
324+
.reduce((acc: string[], node: ts.PropertyAssignment) => {
325+
const key = _getContentOfKeyLiteral(refactor.sourceFile, node.name);
295326

296327
if (key == 'templateUrl') {
297-
refactor.replaceNode(node,
298-
`template: require(${_getResourceRequest(node.initializer, sourceFile)})`);
328+
const url = (node.initializer as ts.StringLiteral).text;
329+
if (url) {
330+
acc.push(url);
331+
}
299332
} else if (key == 'styleUrls') {
300333
const arr = <ts.ArrayLiteralExpression[]>(
301334
refactor.findAstNodes(node, ts.SyntaxKind.ArrayLiteralExpression, false));
302335
if (!arr || arr.length == 0 || arr[0].elements.length == 0) {
303336
return;
304337
}
305338

306-
const initializer = arr[0].elements.map((element: ts.Expression) => {
307-
return _getResourceRequest(element, sourceFile);
339+
arr[0].elements.forEach((element: ts.Expression) => {
340+
if (element.kind == ts.SyntaxKind.StringLiteral) {
341+
const url = (element as ts.StringLiteral).text;
342+
if (url) {
343+
acc.push(url);
344+
}
345+
}
308346
});
309-
refactor.replaceNode(node, `styles: [require(${initializer.join('), require(')})]`);
310347
}
311-
});
348+
return acc;
349+
}, []);
312350
}
313351

314352

@@ -362,6 +400,12 @@ export function ngcLoader(this: LoaderContext & { _compilation: any }) {
362400
plugin.diagnose(sourceFileName);
363401
}
364402
})
403+
.then(() => {
404+
// Add resources as dependencies.
405+
_getResourcesUrls(refactor).forEach((url: string) => {
406+
this.addDependency(path.resolve(path.dirname(sourceFileName), url));
407+
});
408+
})
365409
.then(() => {
366410
// Force a few compiler options to make sure we get the result we want.
367411
const compilerOptions: ts.CompilerOptions = Object.assign({}, plugin.compilerOptions, {

packages/@ngtools/webpack/src/webpack.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -42,6 +42,7 @@ export interface NormalModule {
4242
export interface LoaderContext {
4343
_module: NormalModule;
4444

45+
addDependency(path: string): void;
4546
async(): LoaderCallback;
4647
cacheable(): void;
4748

0 commit comments

Comments
 (0)