Skip to content

Commit 79b58a8

Browse files
authored
Merge pull request #5086 from NativeScript/fatme/fix-valid-hash
fix: persist the next hmr hash per platform
2 parents a65a6ac + 647b0f6 commit 79b58a8

File tree

2 files changed

+33
-16
lines changed

2 files changed

+33
-16
lines changed

lib/services/webpack/webpack-compiler-service.ts

+6-6
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@ import { WEBPACK_COMPILATION_COMPLETE, WEBPACK_PLUGIN_NAME } from "../../constan
77

88
export class WebpackCompilerService extends EventEmitter implements IWebpackCompilerService {
99
private webpackProcesses: IDictionary<child_process.ChildProcess> = {};
10-
private expectedHash: string = null;
10+
private expectedHashes: IStringDictionary = {};
1111

1212
constructor(
1313
private $errors: IErrors,
@@ -42,14 +42,14 @@ export class WebpackCompilerService extends EventEmitter implements IWebpackComp
4242
if (message.emittedFiles) {
4343
if (isFirstWebpackWatchCompilation) {
4444
isFirstWebpackWatchCompilation = false;
45-
this.expectedHash = message.hash;
45+
this.expectedHashes[platformData.platformNameLowerCase] = message.hash;
4646
return;
4747
}
4848

4949
let result;
5050

5151
if (prepareData.hmr) {
52-
result = this.getUpdatedEmittedFiles(message.emittedFiles, message.chunkFiles, message.hash);
52+
result = this.getUpdatedEmittedFiles(message.emittedFiles, message.chunkFiles, message.hash, platformData.platformNameLowerCase);
5353
} else {
5454
result = { emittedFiles: message.emittedFiles, fallbackFiles: <string[]>[], hash: "" };
5555
}
@@ -248,7 +248,7 @@ export class WebpackCompilerService extends EventEmitter implements IWebpackComp
248248
return args;
249249
}
250250

251-
public getUpdatedEmittedFiles(allEmittedFiles: string[], chunkFiles: string[], nextHash: string) {
251+
public getUpdatedEmittedFiles(allEmittedFiles: string[], chunkFiles: string[], nextHash: string, platform: string) {
252252
const currentHash = this.getCurrentHotUpdateHash(allEmittedFiles);
253253

254254
// This logic is needed as there are already cases when webpack doesn't emit any files physically.
@@ -260,8 +260,8 @@ export class WebpackCompilerService extends EventEmitter implements IWebpackComp
260260
// if files will be emitted or not. This way, the first successful compilation after fixing the compilation error generates
261261
// a hash that is not the same as the one expected in the latest emitted hot-update.json file.
262262
// As a result, the hmr chain is broken and the changes are not applied.
263-
const isHashValid = nextHash ? this.expectedHash === currentHash : true;
264-
this.expectedHash = nextHash;
263+
const isHashValid = nextHash ? this.expectedHashes[platform] === currentHash : true;
264+
this.expectedHashes[platform] = nextHash;
265265

266266
const emittedHotUpdatesAndAssets = isHashValid ? _.difference(allEmittedFiles, chunkFiles) : allEmittedFiles;
267267

test/services/webpack/webpack-compiler-service.ts

+27-10
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,8 @@ import { Yok } from "../../../lib/common/yok";
22
import { WebpackCompilerService } from "../../../lib/services/webpack/webpack-compiler-service";
33
import { assert } from "chai";
44

5+
const iOSPlatformName = "ios";
6+
const androidPlatformName = "android";
57
const chunkFiles = ["bundle.js", "runtime.js", "vendor.js"];
68

79
function getAllEmittedFiles(hash: string) {
@@ -35,39 +37,54 @@ describe("WebpackCompilerService", () => {
3537
describe("getUpdatedEmittedFiles", () => {
3638
// backwards compatibility with old versions of nativescript-dev-webpack
3739
it("should return only hot updates when nextHash is not provided", async () => {
38-
const result = webpackCompilerService.getUpdatedEmittedFiles(getAllEmittedFiles("hash1"), chunkFiles, null);
40+
const result = webpackCompilerService.getUpdatedEmittedFiles(getAllEmittedFiles("hash1"), chunkFiles, null, iOSPlatformName);
3941
const expectedEmittedFiles = ['bundle.hash1.hot-update.js', 'hash1.hot-update.json'];
4042

4143
assert.deepEqual(result.emittedFiles, expectedEmittedFiles);
4244
});
4345
// 2 successful webpack compilations
4446
it("should return only hot updates when nextHash is provided", async () => {
45-
webpackCompilerService.getUpdatedEmittedFiles(getAllEmittedFiles("hash1"), chunkFiles, "hash2");
46-
const result = webpackCompilerService.getUpdatedEmittedFiles(getAllEmittedFiles("hash2"), chunkFiles, "hash3");
47+
webpackCompilerService.getUpdatedEmittedFiles(getAllEmittedFiles("hash1"), chunkFiles, "hash2", iOSPlatformName);
48+
const result = webpackCompilerService.getUpdatedEmittedFiles(getAllEmittedFiles("hash2"), chunkFiles, "hash3", iOSPlatformName);
4749

4850
assert.deepEqual(result.emittedFiles, ['bundle.hash2.hot-update.js', 'hash2.hot-update.json']);
4951
});
5052
// 1 successful webpack compilation, n compilations with no emitted files
5153
it("should return all files when there is a webpack compilation with no emitted files", () => {
52-
webpackCompilerService.getUpdatedEmittedFiles(getAllEmittedFiles("hash1"), chunkFiles, "hash2");
53-
const result = webpackCompilerService.getUpdatedEmittedFiles(getAllEmittedFiles("hash4"), chunkFiles, "hash5");
54+
webpackCompilerService.getUpdatedEmittedFiles(getAllEmittedFiles("hash1"), chunkFiles, "hash2", iOSPlatformName);
55+
const result = webpackCompilerService.getUpdatedEmittedFiles(getAllEmittedFiles("hash4"), chunkFiles, "hash5", iOSPlatformName);
5456

5557
assert.deepEqual(result.emittedFiles, ['bundle.js', 'runtime.js', 'bundle.hash4.hot-update.js', 'hash4.hot-update.json']);
5658
});
5759
// 1 successful webpack compilation, n compilations with no emitted files, 1 successful webpack compilation
5860
it("should return only hot updates after fixing the compilation error", () => {
59-
webpackCompilerService.getUpdatedEmittedFiles(getAllEmittedFiles("hash1"), chunkFiles, "hash2");
60-
webpackCompilerService.getUpdatedEmittedFiles(getAllEmittedFiles("hash5"), chunkFiles, "hash6");
61-
const result = webpackCompilerService.getUpdatedEmittedFiles(getAllEmittedFiles("hash6"), chunkFiles, "hash7");
61+
webpackCompilerService.getUpdatedEmittedFiles(getAllEmittedFiles("hash1"), chunkFiles, "hash2", iOSPlatformName);
62+
webpackCompilerService.getUpdatedEmittedFiles(getAllEmittedFiles("hash5"), chunkFiles, "hash6", iOSPlatformName);
63+
const result = webpackCompilerService.getUpdatedEmittedFiles(getAllEmittedFiles("hash6"), chunkFiles, "hash7", iOSPlatformName);
6264

6365
assert.deepEqual(result.emittedFiles, ['bundle.hash6.hot-update.js', 'hash6.hot-update.json']);
6466
});
6567
// 1 webpack compilation with no emitted files
6668
it("should return all files when first compilation on livesync change is not successful", () => {
67-
(<any>webpackCompilerService).expectedHash = "hash1";
68-
const result = webpackCompilerService.getUpdatedEmittedFiles(getAllEmittedFiles("hash1"), chunkFiles, "hash2");
69+
(<any>webpackCompilerService).expectedHashes = {
70+
"ios": "hash1"
71+
};
72+
const result = webpackCompilerService.getUpdatedEmittedFiles(getAllEmittedFiles("hash1"), chunkFiles, "hash2", iOSPlatformName);
6973

7074
assert.deepEqual(result.emittedFiles, ["bundle.hash1.hot-update.js", "hash1.hot-update.json"]);
7175
});
76+
it("should return correct hashes when there are more than one platform", () => {
77+
webpackCompilerService.getUpdatedEmittedFiles(getAllEmittedFiles("hash1"), chunkFiles, "hash2", iOSPlatformName);
78+
webpackCompilerService.getUpdatedEmittedFiles(getAllEmittedFiles("hash3"), chunkFiles, "hash4", androidPlatformName);
79+
80+
webpackCompilerService.getUpdatedEmittedFiles(getAllEmittedFiles("hash2"), chunkFiles, "hash5", iOSPlatformName);
81+
webpackCompilerService.getUpdatedEmittedFiles(getAllEmittedFiles("hash4"), chunkFiles, "hash6", androidPlatformName);
82+
83+
const iOSResult = webpackCompilerService.getUpdatedEmittedFiles(getAllEmittedFiles("hash5"), chunkFiles, "hash7", iOSPlatformName);
84+
assert.deepEqual(iOSResult.emittedFiles, ["bundle.hash5.hot-update.js", "hash5.hot-update.json"]);
85+
86+
const androidResult = webpackCompilerService.getUpdatedEmittedFiles(getAllEmittedFiles("hash6"), chunkFiles, "hash8", androidPlatformName);
87+
assert.deepEqual(androidResult.emittedFiles, ["bundle.hash6.hot-update.js", "hash6.hot-update.json"]);
88+
});
7289
});
7390
});

0 commit comments

Comments
 (0)