Skip to content

Commit

Permalink
fix(@ngtools/webpack): add template/styles as dependencies
Browse files Browse the repository at this point in the history
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.
  • Loading branch information
hansl committed Mar 24, 2017
1 parent f2241a8 commit 7cdf56b
Show file tree
Hide file tree
Showing 2 changed files with 57 additions and 12 deletions.
68 changes: 56 additions & 12 deletions packages/@ngtools/webpack/src/loader.ts
Original file line number Diff line number Diff line change
Expand Up @@ -278,9 +278,36 @@ function _getResourceRequest(element: ts.Expression, sourceFile: ts.SourceFile)
function _replaceResources(refactor: TypeScriptFileRefactor): void {
const sourceFile = refactor.sourceFile;

_getResourceNodes(refactor)
// Get the full text of the initializer.
.forEach((node: ts.PropertyAssignment) => {
const key = _getContentOfKeyLiteral(sourceFile, node.name);

if (key == 'templateUrl') {
refactor.replaceNode(node,
`template: require(${_getResourceRequest(node.initializer, sourceFile)})`);
} else if (key == 'styleUrls') {
const arr = <ts.ArrayLiteralExpression[]>(
refactor.findAstNodes(node, ts.SyntaxKind.ArrayLiteralExpression, false));
if (!arr || arr.length == 0 || arr[0].elements.length == 0) {
return;
}

const initializer = arr[0].elements.map((element: ts.Expression) => {
return _getResourceRequest(element, sourceFile);
});
refactor.replaceNode(node, `styles: [require(${initializer.join('), require(')})]`);
}
});
}


function _getResourceNodes(refactor: TypeScriptFileRefactor) {
const { sourceFile } = refactor;

// Find all object literals.
refactor.findAstNodes(sourceFile, ts.SyntaxKind.ObjectLiteralExpression, true)
// Get all their property assignments.
return refactor.findAstNodes(sourceFile, ts.SyntaxKind.ObjectLiteralExpression, true)
// Get all their property assignments.
.map(node => refactor.findAstNodes(node, ts.SyntaxKind.PropertyAssignment))
// Flatten into a single array (from an array of array<property assignments>).
.reduce((prev, curr) => curr ? prev.concat(curr) : prev, [])
Expand All @@ -292,27 +319,38 @@ function _replaceResources(refactor: TypeScriptFileRefactor): void {
return false;
}
return key == 'templateUrl' || key == 'styleUrls';
})
// Get the full text of the initializer.
.forEach((node: ts.PropertyAssignment) => {
const key = _getContentOfKeyLiteral(sourceFile, node.name);
});
}


function _getResourcesUrls(refactor: TypeScriptFileRefactor): string[] {
return _getResourceNodes(refactor)
.reduce((acc: string[], node: ts.PropertyAssignment) => {
const key = _getContentOfKeyLiteral(refactor.sourceFile, node.name);

if (key == 'templateUrl') {
refactor.replaceNode(node,
`template: require(${_getResourceRequest(node.initializer, sourceFile)})`);
const url = (node.initializer as ts.StringLiteral).text;
if (url) {
acc.push(url);
}
} else if (key == 'styleUrls') {
const arr = <ts.ArrayLiteralExpression[]>(
refactor.findAstNodes(node, ts.SyntaxKind.ArrayLiteralExpression, false));
if (!arr || arr.length == 0 || arr[0].elements.length == 0) {
return;
}

const initializer = arr[0].elements.map((element: ts.Expression) => {
return _getResourceRequest(element, sourceFile);
arr[0].elements.forEach((element: ts.Expression) => {
if (element.kind == ts.SyntaxKind.StringLiteral) {
const url = (element as ts.StringLiteral).text;
if (url) {
acc.push(url);
}
}
});
refactor.replaceNode(node, `styles: [require(${initializer.join('), require(')})]`);
}
});
return acc;
}, []);
}


Expand Down Expand Up @@ -366,6 +404,12 @@ export function ngcLoader(this: LoaderContext & { _compilation: any }) {
plugin.diagnose(sourceFileName);
}
})
.then(() => {
// Add resources as dependencies.
_getResourcesUrls(refactor).forEach((url: string) => {
this.addDependency(path.resolve(path.dirname(sourceFileName), url));
});
})
.then(() => {
// Force a few compiler options to make sure we get the result we want.
const compilerOptions: ts.CompilerOptions = Object.assign({}, plugin.compilerOptions, {
Expand Down
1 change: 1 addition & 0 deletions packages/@ngtools/webpack/src/webpack.ts
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,7 @@ export interface NormalModule {
export interface LoaderContext {
_module: NormalModule;

addDependency(path: string): void;
async(): LoaderCallback;
cacheable(): void;

Expand Down

0 comments on commit 7cdf56b

Please sign in to comment.