Skip to content

Commit 24de553

Browse files
alan-agius4vikerman
authored andcommitted
fix(@ngtools/webpack): files are not being updated when using allowJs or resolveJsonModule (#13089)
* fix(@ngtools/webpack): files are not being updated when using `allowJs` or `resolveJsonModule` Fixes #13076 and Fixes #12964 * test: add tests for allowJs and resolveJsonModule in watch mode * test: improve tests for `allowJs` When not using `allowJs` js files are not processed by the tsc compiler, but still processed by webpack. So a correct test should be to check that the JS is transpiled down to ES5 syntax.
1 parent e339d8b commit 24de553

File tree

4 files changed

+141
-6
lines changed

4 files changed

+141
-6
lines changed

packages/angular_devkit/build_angular/test/browser/allow-js_spec_large.ts

Lines changed: 70 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -7,8 +7,9 @@
77
*/
88

99
import { runTargetSpec } from '@angular-devkit/architect/testing';
10-
import { tap } from 'rxjs/operators';
11-
import { browserTargetSpec, host } from '../utils';
10+
import { join, virtualFs } from '@angular-devkit/core';
11+
import { debounceTime, take, tap } from 'rxjs/operators';
12+
import { browserTargetSpec, host, outputPath } from '../utils';
1213

1314

1415
describe('Browser Builder allow js', () => {
@@ -21,11 +22,21 @@ describe('Browser Builder allow js', () => {
2122
'src/main.ts': `import { a } from './my-js-file'; console.log(a);`,
2223
});
2324

24-
// TODO: this test originally edited tsconfig to have `"allowJs": true` but works without it.
25-
// Investigate.
25+
host.replaceInFile(
26+
'tsconfig.json',
27+
'"target": "es5"',
28+
'"target": "es5", "allowJs": true',
29+
);
2630

2731
runTargetSpec(host, browserTargetSpec).pipe(
2832
tap((buildEvent) => expect(buildEvent.success).toBe(true)),
33+
tap(() => {
34+
const content = virtualFs.fileBufferToString(
35+
host.scopedSync().read(join(outputPath, 'main.js')),
36+
);
37+
38+
expect(content).toContain('var a = 2');
39+
}),
2940
).toPromise().then(done, done.fail);
3041
});
3142

@@ -35,10 +46,65 @@ describe('Browser Builder allow js', () => {
3546
'src/main.ts': `import { a } from './my-js-file'; console.log(a);`,
3647
});
3748

49+
host.replaceInFile(
50+
'tsconfig.json',
51+
'"target": "es5"',
52+
'"target": "es5", "allowJs": true',
53+
);
54+
3855
const overrides = { aot: true };
3956

4057
runTargetSpec(host, browserTargetSpec, overrides).pipe(
4158
tap((buildEvent) => expect(buildEvent.success).toBe(true)),
59+
tap(() => {
60+
const content = virtualFs.fileBufferToString(
61+
host.scopedSync().read(join(outputPath, 'main.js')),
62+
);
63+
64+
expect(content).toContain('var a = 2');
65+
}),
66+
).toPromise().then(done, done.fail);
67+
});
68+
69+
it('works with watch', (done) => {
70+
host.writeMultipleFiles({
71+
'src/my-js-file.js': `console.log(1); export const a = 2;`,
72+
'src/main.ts': `import { a } from './my-js-file'; console.log(a);`,
73+
});
74+
75+
host.replaceInFile(
76+
'tsconfig.json',
77+
'"target": "es5"',
78+
'"target": "es5", "allowJs": true',
79+
);
80+
81+
const overrides = { watch: true };
82+
83+
let buildCount = 1;
84+
runTargetSpec(host, browserTargetSpec, overrides).pipe(
85+
debounceTime(1000),
86+
tap(() => {
87+
const content = virtualFs.fileBufferToString(
88+
host.scopedSync().read(join(outputPath, 'main.js')),
89+
);
90+
91+
switch (buildCount) {
92+
case 1:
93+
expect(content).toContain('var a = 2');
94+
host.writeMultipleFiles({
95+
'src/my-js-file.js': `console.log(1); export const a = 1;`,
96+
});
97+
break;
98+
case 2:
99+
expect(content).toContain('var a = 1');
100+
break;
101+
}
102+
103+
buildCount++;
104+
}),
105+
tap((buildEvent) => expect(buildEvent.success).toBe(true)),
106+
take(2),
42107
).toPromise().then(done, done.fail);
43108
});
109+
44110
});
Lines changed: 60 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,60 @@
1+
/**
2+
* @license
3+
* Copyright Google Inc. All Rights Reserved.
4+
*
5+
* Use of this source code is governed by an MIT-style license that can be
6+
* found in the LICENSE file at https://angular.io/license
7+
*/
8+
9+
import { runTargetSpec } from '@angular-devkit/architect/testing';
10+
import { join, virtualFs } from '@angular-devkit/core';
11+
import { debounceTime, take, tap } from 'rxjs/operators';
12+
import { browserTargetSpec, host, outputPath } from '../utils';
13+
14+
15+
describe('Browser Builder resolve json module', () => {
16+
beforeEach(done => host.initialize().toPromise().then(done, done.fail));
17+
afterEach(done => host.restore().toPromise().then(done, done.fail));
18+
19+
it('works with watch', (done) => {
20+
host.writeMultipleFiles({
21+
'src/my-json-file.json': `{"foo": "1"}`,
22+
'src/main.ts': `import * as a from './my-json-file.json'; console.log(a);`,
23+
});
24+
25+
host.replaceInFile(
26+
'tsconfig.json',
27+
'"target": "es5"',
28+
'"target": "es5", "resolveJsonModule": true',
29+
);
30+
31+
const overrides = { watch: true };
32+
33+
let buildCount = 1;
34+
runTargetSpec(host, browserTargetSpec, overrides).pipe(
35+
debounceTime(1000),
36+
tap(() => {
37+
const content = virtualFs.fileBufferToString(
38+
host.scopedSync().read(join(outputPath, 'main.js')),
39+
);
40+
41+
switch (buildCount) {
42+
case 1:
43+
expect(content).toContain('foo":"1"');
44+
host.writeMultipleFiles({
45+
'src/my-json-file.json': `{"foo": "2"}`,
46+
});
47+
break;
48+
case 2:
49+
expect(content).toContain('foo":"2"');
50+
break;
51+
}
52+
53+
buildCount++;
54+
}),
55+
tap((buildEvent) => expect(buildEvent.success).toBe(true)),
56+
take(2),
57+
).toPromise().then(done, done.fail);
58+
});
59+
60+
});

packages/ngtools/webpack/src/angular_compiler_plugin.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -145,7 +145,7 @@ export class AngularCompilerPlugin {
145145
private _platform: PLATFORM;
146146
private _JitMode = false;
147147
private _emitSkipped = true;
148-
private _changedFileExtensions = new Set(['ts', 'tsx', 'html', 'css']);
148+
private _changedFileExtensions = new Set(['ts', 'tsx', 'html', 'css', 'js', 'json']);
149149

150150
// Webpack plugin.
151151
private _firstRun = true;
@@ -1060,7 +1060,7 @@ export class AngularCompilerPlugin {
10601060
// generate a list of changed files for emit
10611061
// not needed on first run since a full program emit is required
10621062
for (const changedFile of this._compilerHost.getChangedFilePaths()) {
1063-
if (!changedFile.endsWith('.ts') && !changedFile.endsWith('.tsx')) {
1063+
if (!/.(tsx|ts|json|js)$/.test(changedFile)) {
10641064
continue;
10651065
}
10661066
// existing type definitions are not emitted

packages/ngtools/webpack/src/compiler_host.ts

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -109,6 +109,15 @@ export class WebpackCompilerHost implements ts.CompilerHost {
109109
}
110110
});
111111
}
112+
113+
// In case resolveJsonModule and allowJs we also need to remove virtual emitted files
114+
// both if they exists or not.
115+
if ((fullPath.endsWith('.js') || fullPath.endsWith('.json'))
116+
&& !/(\.(ngfactory|ngstyle)\.js|ngsummary\.json)$/.test(fullPath)) {
117+
if (this._memoryHost.exists(fullPath)) {
118+
this._memoryHost.delete(fullPath);
119+
}
120+
}
112121
}
113122

114123
fileExists(fileName: string, delegate = true): boolean {

0 commit comments

Comments
 (0)