Skip to content
This repository was archived by the owner on Aug 7, 2021. It is now read-only.

Commit 0a6d1b9

Browse files
authored
fix(snapshot): interrupt the webpack build on error (#369)
* fix(snapshot): interrupt the webpack build on error * refactor(snapshot): validate plugin options * chore: add dependency to schema-utils
1 parent 8c7a4f4 commit 0a6d1b9

File tree

5 files changed

+95
-29
lines changed

5 files changed

+95
-29
lines changed

Diff for: package.json

+3-2
Original file line numberDiff line numberDiff line change
@@ -41,9 +41,10 @@
4141
},
4242
"dependencies": {
4343
"minimatch": "^3.0.4",
44+
"nativescript-hook": "0.2.2",
45+
"schema-utils": "^0.4.3",
4446
"semver": "^5.4.1",
45-
"shelljs": "^0.6.0",
46-
"nativescript-hook": "0.2.2"
47+
"shelljs": "^0.6.0"
4748
},
4849
"devDependencies": {
4950
"@ngtools/webpack": "^1.8.0",

Diff for: plugins/NativeScriptSnapshotPlugin.js renamed to plugins/NativeScriptSnapshotPlugin/index.js

+41-18
Original file line numberDiff line numberDiff line change
@@ -1,18 +1,16 @@
11
const { resolve, join } = require("path");
22
const { closeSync, openSync } = require("fs");
3+
const validateOptions = require("schema-utils");
34

4-
const ProjectSnapshotGenerator = require("../snapshot/android/project-snapshot-generator");
5-
const { resolveAndroidAppPath } = require("../projectHelpers");
5+
const ProjectSnapshotGenerator = require("../../snapshot/android/project-snapshot-generator");
6+
const { resolveAndroidAppPath } = require("../../projectHelpers");
7+
const schema = require("./options.json");
68

79
exports.NativeScriptSnapshotPlugin = (function() {
810
function NativeScriptSnapshotPlugin(options) {
9-
ProjectSnapshotGenerator.call(this, options); // Call the parent constructor
10-
11-
if (!this.options.chunk) {
12-
throw new Error("No chunk specified.");
13-
}
11+
NativeScriptSnapshotPlugin.validateSchema(options);
1412

15-
console.dir()
13+
ProjectSnapshotGenerator.call(this, options); // Call the parent constructor
1614

1715
if (this.options.webpackConfig) {
1816
if (this.options.webpackConfig.output && this.options.webpackConfig.output.libraryTarget) {
@@ -29,15 +27,28 @@ exports.NativeScriptSnapshotPlugin = (function() {
2927
}
3028
}
3129

30+
NativeScriptSnapshotPlugin.validateSchema = function(options) {
31+
if (!options.chunk) {
32+
const error = NativeScriptSnapshotPlugin.extendError({ message: `No chunk specified!` });
33+
throw error;
34+
}
35+
36+
try {
37+
validateOptions(schema, options, "NativeScriptSnapshotPlugin");
38+
} catch (error) {
39+
throw new Error(error.message);
40+
}
41+
}
42+
3243
// inherit ProjectSnapshotGenerator
3344
NativeScriptSnapshotPlugin.prototype = Object.create(ProjectSnapshotGenerator.prototype);
3445
NativeScriptSnapshotPlugin.prototype.constructor = NativeScriptSnapshotPlugin;
3546

36-
NativeScriptSnapshotPlugin.prototype.getTnsJavaClassesBuildPath = function() {
47+
NativeScriptSnapshotPlugin.prototype.getTnsJavaClassesBuildPath = function () {
3748
return resolve(this.getBuildPath(), "../tns-java-classes.js");
3849
}
3950

40-
NativeScriptSnapshotPlugin.prototype.generate = function(webpackChunk) {
51+
NativeScriptSnapshotPlugin.prototype.generate = function (webpackChunk) {
4152
const options = this.options;
4253

4354
const inputFile = join(options.webpackConfig.output.path, webpackChunk.files[0]);
@@ -62,7 +73,7 @@ exports.NativeScriptSnapshotPlugin = (function() {
6273
});
6374
}
6475

65-
NativeScriptSnapshotPlugin.prototype.apply = function(compiler) {
76+
NativeScriptSnapshotPlugin.prototype.apply = function (compiler) {
6677
const options = this.options;
6778

6879
// Generate tns-java-classes.js file
@@ -73,26 +84,38 @@ exports.NativeScriptSnapshotPlugin = (function() {
7384
});
7485

7586
// Generate snapshots
76-
compiler.plugin("after-emit", function(compilation, callback) {
87+
compiler.plugin("after-emit", function (compilation, callback) {
7788
debugger;
7889
const chunkToSnapshot = compilation.chunks.find(chunk => chunk.name == options.chunk);
7990
if (!chunkToSnapshot) {
80-
throw new Error(`No chunk named '${options.chunk}' found.`);
91+
const error = NativeScriptSnapshotPlugin.extendError({ message: `No chunk named '${options.chunk}' found.` });
92+
compilation.errors.push(error);
93+
return callback();
8194
}
8295

8396
this.generate(chunkToSnapshot)
8497
.then(() => {
8598
console.log("Successfully generated snapshots!");
86-
callback();
99+
return callback();
87100
})
88101
.catch((error) => {
89-
console.error("Snapshot generation failed with the following error:");
90-
console.error(error);
91-
callback();
102+
const extendedError = NativeScriptSnapshotPlugin.extendError({ originalError: error });
103+
compilation.errors.push(extendedError);
104+
return callback();
92105
});
93-
94106
}.bind(this));
95107
}
96108

109+
NativeScriptSnapshotPlugin.extendError = function ({ originalError, message } = {}) {
110+
const header = `NativeScriptSnapshot. Snapshot generation failed!\n`;
111+
if (originalError) {
112+
originalError.message = `${header}${originalError.message}`;
113+
return originalError;
114+
}
115+
116+
const newMessage = message ? `${header}${message}` : header;
117+
return new Error(newMessage);
118+
};
119+
97120
return NativeScriptSnapshotPlugin;
98121
})();

Diff for: plugins/NativeScriptSnapshotPlugin/options.json

+31
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,31 @@
1+
{
2+
"type": "object",
3+
"properties": {
4+
"chunk": {
5+
"type": "string"
6+
},
7+
"projectRoot": {
8+
"type": "string"
9+
},
10+
"webpackConfig": {},
11+
"targetArchs": {
12+
"type": "array"
13+
},
14+
"tnsJavaClassesOptions": {
15+
"additionalProperties": false,
16+
"type": "object",
17+
"properties": {
18+
"modules": {
19+
"type": "array"
20+
},
21+
"packages": {
22+
"type": "array"
23+
}
24+
}
25+
},
26+
"useLibs": {
27+
"type": "boolean"
28+
}
29+
},
30+
"additionalProperties": false
31+
}

Diff for: snapshot/android/project-snapshot-generator.js

+10-1
Original file line numberDiff line numberDiff line change
@@ -238,7 +238,14 @@ ProjectSnapshotGenerator.prototype.generate = function (generationOptions) {
238238
// Generate snapshots
239239
const generator = new SnapshotGenerator({ buildPath: this.getBuildPath() });
240240

241+
const noV8VersionFoundMessage = `Cannot find suitable v8 version!`;
242+
let shouldRethrow = false;
241243
return this.getV8Version(generationOptions).then(v8Version => {
244+
shouldRethrow = true;
245+
if (!v8Version) {
246+
throw new Error(noV8VersionFoundMessage);
247+
}
248+
242249
return generator.generate({
243250
snapshotToolsPath,
244251
inputFile: generationOptions.inputFile || join(this.options.projectRoot, "__snapshot.js"),
@@ -259,6 +266,8 @@ ProjectSnapshotGenerator.prototype.generate = function (generationOptions) {
259266
}
260267
});
261268
}).catch(error => {
262-
throw new Error(`Cannot find suitable v8 version! Original error: ${error.message || error}`);
269+
throw shouldRethrow ?
270+
error :
271+
new Error(`${noV8VersionFoundMessage} Original error: ${error.message || error}`);
263272
});
264273
}

Diff for: snapshot/android/snapshot-generator.js

+10-8
Original file line numberDiff line numberDiff line change
@@ -100,16 +100,18 @@ SnapshotGenerator.prototype.runMksnapshotTool = function(snapshotToolsPath, inpu
100100

101101
return new Promise((resolve, reject) => {
102102
const child = child_process.exec(command, {encoding: "utf8"}, (error, stdout, stderr) => {
103-
console.log(`${stdout}`);
103+
const errorHeader = `Target architecture: ${androidArch}\n`;
104+
104105
if (stderr.length) {
105-
console.error("***** SNAPSHOT GENERATION FOR " + androidArch + " FAILED! *****");
106-
console.error(stderr);
107-
return reject(stderr);
108-
}
109-
if (error) {
110-
return reject(error);
106+
const message = `${errorHeader}${stderr}`;
107+
reject(new Error(message));
108+
} else if (error) {
109+
error.message = `${errorHeader}${error.message}`;
110+
reject(error);
111+
} else {
112+
console.log(stdout);
113+
resolve();
111114
}
112-
return resolve();
113115
})
114116
}).then(() => {
115117
// Generate .c file

0 commit comments

Comments
 (0)