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

Commit 994d6a2

Browse files
author
Dimitar Tachev
authored
Merge pull request #965 from NativeScript/tachev/fix-uglfiy-sourcemaps-snapshot
fix: avoid generating invalid JavaScript when merging IIFE files
2 parents 47ad5cf + 1a9c4b2 commit 994d6a2

File tree

1 file changed

+34
-14
lines changed

1 file changed

+34
-14
lines changed

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

+34-14
Original file line numberDiff line numberDiff line change
@@ -43,19 +43,31 @@ module.exports = SnapshotGenerator;
4343

4444
SnapshotGenerator.SNAPSHOT_PACKAGE_NANE = "nativescript-android-snapshot";
4545

46-
SnapshotGenerator.prototype.preprocessInputFiles = function(inputFiles, outputFile) {
46+
SnapshotGenerator.prototype.preprocessInputFiles = function (inputFiles, outputFile) {
4747
// Make some modifcations on the original bundle and save it on the specified path
4848
const bundlePreambleContent = fs.readFileSync(BUNDLE_PREAMBLE_PATH, "utf8");
4949
const bundleEndingContent = fs.readFileSync(BUNDLE_ENDING_PATH, "utf8");
5050

51-
const inputFilesContent = inputFiles.map(file => fs.readFileSync(file, "utf8")).join("\n");
51+
// IMPORTANT: join by "\n;" as we are joining IIFE functions and if the snapshot tool is used
52+
// along with Uglify configuration for replacing `;` with `/n`, we will generate invalid JavaScript
53+
// Example:
54+
// (function() {
55+
// some code here
56+
// })()
57+
// // sourceMapUrl......
58+
// ** when we join without `;` here, the next IIFE is assumed as a function call to the result of the first IIFE
59+
// (function() {
60+
// some code here
61+
// })()
62+
// // sourceMapUrl......
63+
const inputFilesContent = inputFiles.map(file => fs.readFileSync(file, "utf8")).join("\n;");
5264
const snapshotFileContent = bundlePreambleContent + "\n" + inputFilesContent + "\n" + bundleEndingContent;
5365
fs.writeFileSync(outputFile, snapshotFileContent, { encoding: "utf8" });
5466
}
5567

5668
const snapshotToolsDownloads = {};
5769

58-
SnapshotGenerator.prototype.downloadMksnapshotTool = function(snapshotToolsPath, v8Version, targetArch) {
70+
SnapshotGenerator.prototype.downloadMksnapshotTool = function (snapshotToolsPath, v8Version, targetArch) {
5971
const hostOS = getHostOS();
6072
const mksnapshotToolRelativePath = join("mksnapshot-tools", "v8-v" + v8Version, hostOS + "-" + os.arch(), "mksnapshot-" + targetArch);
6173
const mksnapshotToolPath = join(snapshotToolsPath, mksnapshotToolRelativePath);
@@ -84,7 +96,7 @@ SnapshotGenerator.prototype.downloadMksnapshotTool = function(snapshotToolsPath,
8496
return snapshotToolsDownloads[mksnapshotToolPath];
8597
}
8698

87-
SnapshotGenerator.prototype.convertToAndroidArchName = function(archName) {
99+
SnapshotGenerator.prototype.convertToAndroidArchName = function (archName) {
88100
switch (archName) {
89101
case "arm": return "armeabi-v7a";
90102
case "arm64": return "arm64-v8a";
@@ -94,7 +106,7 @@ SnapshotGenerator.prototype.convertToAndroidArchName = function(archName) {
94106
}
95107
}
96108

97-
SnapshotGenerator.prototype.runMksnapshotTool = function(snapshotToolsPath, inputFile, v8Version, targetArchs, buildCSource, mksnapshotParams) {
109+
SnapshotGenerator.prototype.runMksnapshotTool = function (snapshotToolsPath, inputFile, v8Version, targetArchs, buildCSource, mksnapshotParams) {
98110
// Cleans the snapshot build folder
99111
shelljs.rm("-rf", join(this.buildPath, "snapshots"));
100112

@@ -120,14 +132,22 @@ SnapshotGenerator.prototype.runMksnapshotTool = function(snapshotToolsPath, inpu
120132
const command = `${currentArchMksnapshotToolPath} ${inputFile} --startup_blob ${join(currentArchBlobOutputPath, `${SNAPSHOT_BLOB_NAME}.blob`)} ${params}`;
121133

122134
return new Promise((resolve, reject) => {
123-
const child = child_process.exec(command, {encoding: "utf8"}, (error, stdout, stderr) => {
135+
const child = child_process.exec(command, { encoding: "utf8" }, (error, stdout, stderr) => {
124136
const errorHeader = `Target architecture: ${androidArch}\n`;
137+
let errorFooter = ``;
138+
if (stderr.length || error) {
139+
try {
140+
require(inputFile);
141+
} catch (e) {
142+
errorFooter = `\nJavaScript execution error: ${e.stack}$`;
143+
}
144+
}
125145

126146
if (stderr.length) {
127-
const message = `${errorHeader}${stderr}`;
147+
const message = `${errorHeader}${stderr}${errorFooter}`;
128148
reject(new Error(message));
129149
} else if (error) {
130-
error.message = `${errorHeader}${error.message}`;
150+
error.message = `${errorHeader}${error.message}${errorFooter}`;
131151
reject(error);
132152
} else {
133153
console.log(stdout);
@@ -139,7 +159,7 @@ SnapshotGenerator.prototype.runMksnapshotTool = function(snapshotToolsPath, inpu
139159
if (buildCSource) {
140160
const currentArchSrcOutputPath = join(this.buildPath, "snapshots/src", androidArch);
141161
shelljs.mkdir("-p", currentArchSrcOutputPath);
142-
shellJsExecuteInDir(currentArchBlobOutputPath, function() {
162+
shellJsExecuteInDir(currentArchBlobOutputPath, function () {
143163
shelljs.exec(`xxd -i ${SNAPSHOT_BLOB_NAME}.blob > ${join(currentArchSrcOutputPath, `${SNAPSHOT_BLOB_NAME}.c`)}`);
144164
});
145165
}
@@ -150,7 +170,7 @@ SnapshotGenerator.prototype.runMksnapshotTool = function(snapshotToolsPath, inpu
150170
});
151171
}
152172

153-
SnapshotGenerator.prototype.buildSnapshotLibs = function(androidNdkBuildPath, targetArchs) {
173+
SnapshotGenerator.prototype.buildSnapshotLibs = function (androidNdkBuildPath, targetArchs) {
154174
// Compile *.c files to produce *.so libraries with ndk-build tool
155175
const ndkBuildPath = join(this.buildPath, "ndk-build");
156176
const androidArchs = targetArchs.map(arch => this.convertToAndroidArchName(arch));
@@ -159,22 +179,22 @@ SnapshotGenerator.prototype.buildSnapshotLibs = function(androidNdkBuildPath, ta
159179
shelljs.cp("-r", NDK_BUILD_SEED_PATH, ndkBuildPath);
160180
fs.writeFileSync(join(ndkBuildPath, "jni/Application.mk"), "APP_ABI := " + androidArchs.join(" ")); // create Application.mk file
161181
shelljs.mv(join(this.buildPath, "snapshots/src/*"), join(ndkBuildPath, "jni"));
162-
shellJsExecuteInDir(ndkBuildPath, function(){
182+
shellJsExecuteInDir(ndkBuildPath, function () {
163183
shelljs.exec(androidNdkBuildPath);
164184
});
165185
return join(ndkBuildPath, "libs");
166186
}
167187

168-
SnapshotGenerator.prototype.buildIncludeGradle = function() {
188+
SnapshotGenerator.prototype.buildIncludeGradle = function () {
169189
shelljs.cp(INCLUDE_GRADLE_PATH, join(this.buildPath, "include.gradle"));
170190
}
171191

172-
SnapshotGenerator.prototype.generate = function(options) {
192+
SnapshotGenerator.prototype.generate = function (options) {
173193
// Arguments validation
174194
options = options || {};
175195
if (!options.v8Version) { throw new Error("No v8 version specified."); }
176196
if (!options.snapshotToolsPath) { throw new Error("snapshotToolsPath option is not specified."); }
177-
const preprocessedInputFile = options.preprocessedInputFile || join(this.buildPath, "inputFile.preprocessed");
197+
const preprocessedInputFile = options.preprocessedInputFile || join(this.buildPath, "inputFile.preprocessed");
178198

179199
console.log("***** Starting snapshot generation using V8 version: ", options.v8Version);
180200

0 commit comments

Comments
 (0)