Skip to content

Commit 9dc6767

Browse files
JoshuaNitschkedanguilherme
authored andcommitted
Update for Angular 8 (#22)
* Set directTemplateLoading to False for Angular 8 * Update direct template loading to false for Angular 8 * Fix the existing broken unit tests Add a unit test for Angular 8 Add a check to maintain Angular 6/7 compatability per PR feedback * add "update needed to typescript.js check" to ng-add-pug-loader.js script make changes requested in PR: * fix typo on unit test description * refactor variable names relating to version of Angular * alter mocked unit test file utilize subset of typescript.js
1 parent 747809b commit 9dc6767

File tree

4 files changed

+140
-28
lines changed

4 files changed

+140
-28
lines changed

src/files/ng-add-pug-loader.js

Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -24,3 +24,30 @@ fs.readFile(commonCliConfig, (err, data) => {
2424
fs.close(file, () => {});
2525
});
2626
});
27+
28+
/**
29+
* Set's directTemplateLoading: false to allow custom pug template loader to work
30+
* @see https://github.com/angular/angular-cli/issues/14534
31+
*/
32+
const typescriptCliConfig = '__TYPESCRIPT_CLI_CONFIG_PATH__';
33+
34+
fs.readFile(typescriptCliConfig, (err, data) => {
35+
if (err) { throw err; }
36+
37+
const typescriptText = data.toString();
38+
39+
// check if needed to be set or already set
40+
if (typescriptText.indexOf('directTemplateLoading') === -1 || typescriptText.indexOf('directTemplateLoading: false,') > -1) { return; }
41+
42+
// update the setting
43+
const output = typescriptText.replace('directTemplateLoading: true,', 'directTemplateLoading: false,');
44+
45+
// rewrite the file
46+
const file2 = fs.openSync(typescriptCliConfig, 'r+');
47+
fs.writeFile(file2, output, error => {
48+
if (error)
49+
console.error("An error occurred while overwriting Angular CLI's Webpack config");
50+
51+
fs.close(file2, () => {});
52+
});
53+
});

src/schematics/ng-add/index.ts

Lines changed: 25 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,8 @@ import { throwError } from 'rxjs';
1111
import { addDependencyToPackageJson, addScriptToPackageJson } from '../../utils/package';
1212
import { devDependencies } from './dependencies';
1313

14-
const TARGET_CONFIG_PATH = 'node_modules/@angular-devkit/build-angular/src/angular-cli-files/models/webpack-configs/common.js';
14+
const TARGET_COMMON_CONFIG_PATH = 'node_modules/@angular-devkit/build-angular/src/angular-cli-files/models/webpack-configs/common.js';
15+
const TARGET_TYPESCRIPT_CONFIG_PATH = 'node_modules/@angular-devkit/build-angular/src/angular-cli-files/models/webpack-configs/typescript.js';
1516
const NG_ADD_PUG_LOADER_SCRIPT_NAME = 'ng-add-pug-loader.js';
1617

1718
/**
@@ -60,21 +61,33 @@ function addLoadersToPackageJson() {
6061
*/
6162
function addPugRules() {
6263
return (tree: Tree) => {
63-
const configFile = tree.read(TARGET_CONFIG_PATH);
64-
if (!configFile)
64+
const commonConfigFile = tree.read(TARGET_COMMON_CONFIG_PATH);
65+
const typescriptConfigFile = tree.read(TARGET_TYPESCRIPT_CONFIG_PATH);
66+
67+
if (!commonConfigFile || !typescriptConfigFile)
6568
return throwError(new Error(`CLI's Webpack config was not found. Try running \`npm install\` before running this tool.`));
66-
67-
const configText = configFile.toString('utf-8');
69+
70+
const commonConfigText = commonConfigFile.toString('utf-8');
6871
const strPugRules = getPugLoaderRules();
6972

7073
// make sure we don't add the rule if it already exists
71-
if (configText.indexOf(strPugRules) > -1) { return; }
74+
if (commonConfigText.indexOf(strPugRules) > -1) { return; }
7275

7376
// We made it this far, let's insert that pug webpack rule
74-
const position = configText.indexOf('rules: [') + 8;
75-
const output = [configText.slice(0, position), `\n${strPugRules}`, configText.slice(position)].join('');
77+
const position = commonConfigText.indexOf('rules: [') + 8;
78+
const commonOutput = [commonConfigText.slice(0, position), `\n${strPugRules}`, commonConfigText.slice(position)].join('');
79+
80+
tree.overwrite(TARGET_COMMON_CONFIG_PATH, commonOutput);
81+
82+
// now we update the typescript config file for Angular8 to turn off direct template loading
83+
const typescriptConfigText = typescriptConfigFile.toString('utf-8');
7684

77-
tree.overwrite(TARGET_CONFIG_PATH, output);
85+
// if directTemplateLoading not present (Angular 6) no change needed, if Angular 8 and already set to false, no change needed
86+
if (typescriptConfigText.indexOf('directTemplateLoading') === -1 || typescriptConfigText.indexOf('directTemplateLoading: false,') > -1) { return; }
87+
88+
// change needed, make and write it
89+
const typescriptOutput = typescriptConfigText.replace('directTemplateLoading: true,', 'directTemplateLoading: false,');
90+
tree.overwrite(TARGET_TYPESCRIPT_CONFIG_PATH, typescriptOutput)
7891
}
7992
}
8093

@@ -98,7 +111,8 @@ function addScriptToProject() {
98111
const scriptContent = files.read(NG_ADD_PUG_LOADER_SCRIPT_NAME)!.toString('utf-8');
99112

100113
const modifiedContent = replaceVars(scriptContent, {
101-
COMMON_CLI_CONFIG_PATH: TARGET_CONFIG_PATH,
114+
COMMON_CLI_CONFIG_PATH: TARGET_COMMON_CONFIG_PATH,
115+
TYPESCRIPT_CLI_CONFIG_PATH: TARGET_TYPESCRIPT_CONFIG_PATH,
102116
PUG_RULES: getPugLoaderRules()
103117
});
104118

@@ -149,4 +163,4 @@ function getPugLoaderRules(): string {
149163
test: ${partialRegex},
150164
loader: "pug-loader"
151165
},`.replace(/\s+/gm, ' ');
152-
}
166+
}

src/schematics/ng-add/index_spec.ts

Lines changed: 38 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -2,19 +2,22 @@ import { SchematicTestRunner, UnitTestTree } from '@angular-devkit/schematics/te
22
import { getFileContent } from '@schematics/angular/utility/test';
33
import * as path from 'path';
44

5-
import { createTestApp, createCommonWebpackConfig } from '../../utils/testing';
5+
import { createTestApp, createCommonWebpackConfigForAngular6, createCommonWebpackConfigForAngular7orGreater } from '../../utils/testing';
66
import { NgAddOptions } from '.';
77

8-
describe('ng-add', () => {
9-
const TARGET_CONFIG_PATH = 'node_modules/@angular-devkit/build-angular/src/angular-cli-files/models/webpack-configs/common.js';
8+
const TARGET_COMMON_CONFIG_PATH = 'node_modules/@angular-devkit/build-angular/src/angular-cli-files/models/webpack-configs/common.js';
9+
const TARGET_TYPESCRIPT_CONFIG_PATH = 'node_modules/@angular-devkit/build-angular/src/angular-cli-files/models/webpack-configs/typescript.js';
10+
11+
describe('ng-add-angular-6', () => {
12+
1013
let runner: SchematicTestRunner;
1114
let appTree: UnitTestTree;
1215

1316
const defaultOptions: NgAddOptions = {};
1417

1518
beforeEach(() => {
1619
appTree = createTestApp();
17-
createCommonWebpackConfig(appTree);
20+
createCommonWebpackConfigForAngular6(appTree);
1821
runner = new SchematicTestRunner('schematics', path.join(__dirname, '../collection.json'));
1922
});
2023

@@ -29,16 +32,16 @@ describe('ng-add', () => {
2932
});
3033

3134
it('should add 2 new pug rules', () => {
32-
const oldConfig = eval(getFileContent(appTree, TARGET_CONFIG_PATH));
35+
const oldConfig = eval(getFileContent(appTree, TARGET_COMMON_CONFIG_PATH));
3336
const tree = runner.runSchematic('ng-add', defaultOptions, appTree);
34-
const config = eval(getFileContent(tree, TARGET_CONFIG_PATH));
37+
const config = eval(getFileContent(tree, TARGET_COMMON_CONFIG_PATH));
3538

3639
expect(config.rules.length - oldConfig.rules.length).toBe(2);
3740
});
3841

3942
it('should add the apply and pug loaders in webpack config', () => {
4043
const tree = runner.runSchematic('ng-add', defaultOptions, appTree);
41-
const config = eval(getFileContent(tree, TARGET_CONFIG_PATH));
44+
const config = eval(getFileContent(tree, TARGET_COMMON_CONFIG_PATH));
4245
const pugRule = config.rules[0];
4346

4447
expect(pugRule.test.toString()).toBe(/\.(pug|jade)$/.toString());
@@ -51,13 +54,20 @@ describe('ng-add', () => {
5154

5255
it('should add the pug loader only for include/partial files in webpack config', () => {
5356
const tree = runner.runSchematic('ng-add', defaultOptions, appTree);
54-
const config = eval(getFileContent(tree, TARGET_CONFIG_PATH));
57+
const config = eval(getFileContent(tree, TARGET_COMMON_CONFIG_PATH));
5558
const partialPugRule = config.rules[1];
5659

5760
expect(partialPugRule.test.toString()).toBe(/\.(include|partial)\.(pug|jade)$/.toString());
5861
expect(partialPugRule.loader).toBe('pug-loader');
5962
});
6063

64+
it('should not modify the typescript.js file in webpack config', () => {
65+
const tree = runner.runSchematic('ng-add', defaultOptions, appTree);
66+
const newTypescriptConfig = getFileContent(tree, TARGET_TYPESCRIPT_CONFIG_PATH);
67+
68+
expect(newTypescriptConfig).not.toContain('directTemplateLoading');
69+
});
70+
6171
it('should add script file to root', () => {
6272
const tree = runner.runSchematic('ng-add', defaultOptions, appTree);
6373
expect(tree.read('/ng-add-pug-loader.js')).toBeDefined();
@@ -73,3 +83,23 @@ describe('ng-add', () => {
7383
expect((npmInstallTask.options as any).command).toBe('install');
7484
});
7585
});
86+
87+
88+
describe('ng-add-angular-7-or-greater-specific', () => {
89+
let runner: SchematicTestRunner;
90+
let appTree: UnitTestTree;
91+
92+
const defaultOptions: NgAddOptions = {};
93+
94+
beforeEach(() => {
95+
appTree = createTestApp();
96+
createCommonWebpackConfigForAngular7orGreater(appTree);
97+
runner = new SchematicTestRunner('schematics', path.join(__dirname, '../collection.json'));
98+
});
99+
100+
it('the typescript.js file in webpack config should have directTemplateLoading: false', () => {
101+
const tree = runner.runSchematic('ng-add', defaultOptions, appTree);
102+
const newTypescriptConfig = getFileContent(tree, TARGET_TYPESCRIPT_CONFIG_PATH);
103+
expect(newTypescriptConfig).toContain('directTemplateLoading: false');
104+
});
105+
});

src/utils/testing.ts

Lines changed: 50 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,48 @@ import { SchematicTestRunner, UnitTestTree } from '@angular-devkit/schematics/te
33
import { Tree } from '@angular-devkit/schematics';
44

55
const collectionPath = join('./node_modules/@schematics/angular/collection.json');
6+
const commonJsFile =
7+
`({
8+
rules: [
9+
{ test: /.anything$/, loader: 'any-loader' }
10+
]
11+
})`
12+
13+
const angular6TypescriptJsFile =
14+
`const pluginOptions: AngularCompilerPluginOptions = {
15+
mainPath: useMain ? path.join(root, buildOptions.main) : undefined,
16+
...i18nFileAndFormat,
17+
locale: buildOptions.i18nLocale,
18+
platform: buildOptions.platform === 'server' ? PLATFORM.Server : PLATFORM.Browser,
19+
missingTranslation: buildOptions.i18nMissingTranslation,
20+
sourceMap: buildOptions.sourceMap.scripts,
21+
additionalLazyModules,
22+
hostReplacementPaths,
23+
nameLazyFiles: buildOptions.namedChunks,
24+
forkTypeChecker: buildOptions.forkTypeChecker,
25+
contextElementDependencyConstructor: require('webpack/lib/dependencies/ContextElementDependency'),
26+
logger: wco.logger,
27+
...options,
28+
};`
29+
30+
const angular7orGreaterTypescriptJsFile =
31+
`const pluginOptions: AngularCompilerPluginOptions = {
32+
mainPath: useMain ? path.join(root, buildOptions.main) : undefined,
33+
...i18nFileAndFormat,
34+
locale: buildOptions.i18nLocale,
35+
platform: buildOptions.platform === 'server' ? PLATFORM.Server : PLATFORM.Browser,
36+
missingTranslation: buildOptions.i18nMissingTranslation,
37+
sourceMap: buildOptions.sourceMap.scripts,
38+
additionalLazyModules,
39+
hostReplacementPaths,
40+
nameLazyFiles: buildOptions.namedChunks,
41+
forkTypeChecker: buildOptions.forkTypeChecker,
42+
contextElementDependencyConstructor: require('webpack/lib/dependencies/ContextElementDependency'),
43+
logger: wco.logger,
44+
directTemplateLoading: true,
45+
...options,
46+
};`
47+
648

749
/**
850
* Create a base app used for testing.
@@ -30,13 +72,12 @@ export function createTestApp(): UnitTestTree {
3072
}, tree);
3173
}
3274

33-
export function createCommonWebpackConfig(host: Tree) {
34-
host.create(
35-
'node_modules/@angular-devkit/build-angular/src/angular-cli-files/models/webpack-configs/common.js',
36-
`
37-
({
38-
rules: [
39-
{ test: /.anything$/, loader: 'any-loader' }
40-
]
41-
})`);
75+
export function createCommonWebpackConfigForAngular6(host: Tree) {
76+
host.create("node_modules/@angular-devkit/build-angular/src/angular-cli-files/models/webpack-configs/common.js", commonJsFile);
77+
host.create("node_modules/@angular-devkit/build-angular/src/angular-cli-files/models/webpack-configs/typescript.js", angular6TypescriptJsFile);
78+
}
79+
80+
export function createCommonWebpackConfigForAngular7orGreater(host: Tree) {
81+
host.create("node_modules/@angular-devkit/build-angular/src/angular-cli-files/models/webpack-configs/common.js", commonJsFile);
82+
host.create("node_modules/@angular-devkit/build-angular/src/angular-cli-files/models/webpack-configs/typescript.js", angular7orGreaterTypescriptJsFile);
4283
}

0 commit comments

Comments
 (0)