320 lines
19 KiB
JavaScript
320 lines
19 KiB
JavaScript
"use strict";
|
|
|
|
var _slicedToArray = function () { function sliceIterator(arr, i) { var _arr = []; var _n = true; var _d = false; var _e = undefined; try { for (var _i = arr[Symbol.iterator](), _s; !(_n = (_s = _i.next()).done); _n = true) { _arr.push(_s.value); if (i && _arr.length === i) break; } } catch (err) { _d = true; _e = err; } finally { try { if (!_n && _i["return"]) _i["return"](); } finally { if (_d) throw _e; } } return _arr; } return function (arr, i) { if (Array.isArray(arr)) { return arr; } else if (Symbol.iterator in Object(arr)) { return sliceIterator(arr, i); } else { throw new TypeError("Invalid attempt to destructure non-iterable instance"); } }; }(); /**
|
|
* Copyright (c) 2017-present, Facebook, Inc.
|
|
* All rights reserved.
|
|
*
|
|
* This source code is licensed under the BSD-style license found in the
|
|
* LICENSE file in the root directory of this source tree. An additional grant
|
|
* of patent rights can be found in the PATENTS file in the same directory.
|
|
*/
|
|
|
|
/* eslint-disable no-shadow */
|
|
|
|
var _errors = require("./errors.js");
|
|
|
|
var _options = require("./options.js");
|
|
|
|
var _prepackNode = require("./prepack-node.js");
|
|
|
|
var _fs = require("fs");
|
|
|
|
var _fs2 = _interopRequireDefault(_fs);
|
|
|
|
var _v = require("v8");
|
|
|
|
var _v2 = _interopRequireDefault(_v);
|
|
|
|
var _package = require("../package.json");
|
|
|
|
var _invariant = require("./invariant");
|
|
|
|
var _invariant2 = _interopRequireDefault(_invariant);
|
|
|
|
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
|
|
|
|
// Prepack helper
|
|
function run(Object, Array, console, JSON, process, prepackStdin, prepackFileSync, FatalError, CompatibilityValues, fs) {
|
|
var HELP_STR = "\n input The name of the file to run Prepack over (for web please provide the single js bundle file)\n --out The name of the output file\n --compatibility The target environment for Prepack [" + CompatibilityValues.map(function (v) {
|
|
return "\"" + v + "\"";
|
|
}).join(", ") + "]\n --mathRandomSeed If you want Prepack to evaluate Math.random() calls, please provide a seed.\n --srcmapIn The input sourcemap filename. If present, Prepack will output a sourcemap that maps from\n the original file (pre-input sourcemap) to Prepack's output\n --srcmapOut The output sourcemap filename.\n --maxStackDepth Specify the maximum call stack depth.\n --timeout The amount of time in seconds until Prepack should time out.\n --additionalFunctions Additional functions that should be prepacked (comma separated).\n --abstractEffectsInAdditionalFunctions Experimental flag to allow abstract effectful function calls.\n --lazyObjectsRuntime Enable lazy objects feature and specify the JS runtime that support this feature.\n --debugNames Changes the output of Prepack so that for named functions and variables that get emitted into\n Prepack's output, the original name is appended as a suffix to Prepack's generated identifier.\n --speculate Enable speculative initialization of modules (for the module system Prepack has builtin\n knowledge about). Prepack will try to execute all factory functions it is able to.\n --trace Traces the order of module initialization.\n --serialize Serializes the partially evaluated global environment as a program that recreates it.\n (default = true)\n --residual Produces the residual program that results after constant folding.\n --profile Enables console logging of profile information of different phases of prepack.\n --statsFile The name of the output file where statistics will be written to.\n --heapGraphFilePath The name of the output file where heap graph will be written to.\n --inlineExpressions When generating code, tells prepack to avoid naming expressions when they are only used once,\n and instead inline them where they are used.\n --simpleClosures When generating code, tells prepack to not defer initializing closures\n --omitInvariants When generating code, tells prepack to omit writing invariants. (Invariants generated by default.)\n --version Output the version number.\n ";
|
|
var args = Array.from(process.argv);
|
|
args.splice(0, 2);
|
|
var inputFilenames = [];
|
|
var outputFilename = void 0;
|
|
var compatibility = void 0;
|
|
var mathRandomSeed = void 0;
|
|
var inputSourceMap = void 0;
|
|
var outputSourceMap = void 0;
|
|
var statsFileName = void 0;
|
|
var maxStackDepth = void 0;
|
|
var timeout = void 0;
|
|
var additionalFunctions = void 0;
|
|
var lazyObjectsRuntime = void 0;
|
|
var heapGraphFilePath = void 0;
|
|
var debugInFilePath = void 0;
|
|
var debugOutFilePath = void 0;
|
|
var flags = {
|
|
initializeMoreModules: false,
|
|
trace: false,
|
|
debugNames: false,
|
|
omitInvariants: false,
|
|
inlineExpressions: false,
|
|
simpleClosures: false,
|
|
abstractEffectsInAdditionalFunctions: false,
|
|
logStatistics: false,
|
|
logModules: false,
|
|
delayInitializations: false,
|
|
delayUnsupportedRequires: false,
|
|
accelerateUnsupportedRequires: true,
|
|
internalDebug: false,
|
|
debugScopes: false,
|
|
serialize: false,
|
|
residual: false,
|
|
profile: false,
|
|
reactEnabled: false,
|
|
reactOutput: "create-element"
|
|
};
|
|
|
|
while (args.length) {
|
|
var arg = args.shift();
|
|
if (!arg.startsWith("--")) {
|
|
inputFilenames.push(arg);
|
|
} else {
|
|
arg = arg.slice(2);
|
|
switch (arg) {
|
|
case "out":
|
|
arg = args.shift();
|
|
outputFilename = arg;
|
|
break;
|
|
case "compatibility":
|
|
arg = args.shift();
|
|
if (!CompatibilityValues.includes(arg)) {
|
|
console.error("Unsupported compatibility: " + arg);
|
|
process.exit(1);
|
|
}
|
|
compatibility = arg;
|
|
break;
|
|
case "mathRandomSeed":
|
|
mathRandomSeed = args.shift();
|
|
break;
|
|
case "srcmapIn":
|
|
inputSourceMap = args.shift();
|
|
break;
|
|
case "srcmapOut":
|
|
outputSourceMap = args.shift();
|
|
break;
|
|
case "statsFile":
|
|
statsFileName = args.shift();
|
|
break;
|
|
case "maxStackDepth":
|
|
var value = args.shift();
|
|
if (isNaN(value)) {
|
|
console.error("Stack depth value must be a number");
|
|
process.exit(1);
|
|
}
|
|
maxStackDepth = parseInt(value, 10);
|
|
break;
|
|
case "timeout":
|
|
var seconds = args.shift();
|
|
if (isNaN(seconds)) {
|
|
console.error("Timeout must be a number");
|
|
process.exit(1);
|
|
}
|
|
timeout = parseInt(seconds, 10) * 1000;
|
|
break;
|
|
case "additionalFunctions":
|
|
var line = args.shift();
|
|
additionalFunctions = line.split(",");
|
|
break;
|
|
case "debugInFilePath":
|
|
debugInFilePath = args.shift();
|
|
break;
|
|
case "debugOutFilePath":
|
|
debugOutFilePath = args.shift();
|
|
break;
|
|
case "lazyObjectsRuntime":
|
|
lazyObjectsRuntime = args.shift();
|
|
break;
|
|
case "heapGraphFilePath":
|
|
heapGraphFilePath = args.shift();
|
|
break;
|
|
case "help":
|
|
console.log("Usage: prepack.js [ -- | input.js ] [ --out output.js ] [ --compatibility jsc ] [ --mathRandomSeed seedvalue ] [ --srcmapIn inputMap ] [ --srcmapOut outputMap ] [ --maxStackDepth depthValue ] [ --timeout seconds ] [ --additionalFunctions fnc1,fnc2,... ] [ --lazyObjectsRuntime lazyObjectsRuntimeName] [ --heapGraphFilePath heapGraphFilePath]" + Object.keys(flags).map(function (s) {
|
|
return "[ --" + s + "]";
|
|
}).join(" ") + "\n" + HELP_STR);
|
|
return;
|
|
case "version":
|
|
console.log(_package.version);
|
|
return;
|
|
default:
|
|
if (arg in flags) {
|
|
flags[arg] = true;
|
|
} else {
|
|
console.error("Unknown option: " + arg);
|
|
process.exit(1);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
if (!flags.serialize && !flags.residual) flags.serialize = true;
|
|
|
|
var resolvedOptions = Object.assign({}, {
|
|
compatibility: compatibility,
|
|
mathRandomSeed: mathRandomSeed,
|
|
inputSourceMapFilename: inputSourceMap,
|
|
errorHandler: errorHandler,
|
|
sourceMaps: !!outputSourceMap,
|
|
maxStackDepth: maxStackDepth,
|
|
timeout: timeout,
|
|
additionalFunctions: additionalFunctions,
|
|
lazyObjectsRuntime: lazyObjectsRuntime,
|
|
heapGraphFormat: "DotLanguage",
|
|
debugInFilePath: debugInFilePath,
|
|
debugOutFilePath: debugOutFilePath
|
|
}, flags);
|
|
if (lazyObjectsRuntime && (resolvedOptions.additionalFunctions || resolvedOptions.delayInitializations || resolvedOptions.inlineExpressions)) {
|
|
console.error("lazy objects feature is incompatible with additionalFunctions, delayInitializations and inlineExpressions options");
|
|
process.exit(1);
|
|
}
|
|
|
|
var errors = new Map();
|
|
function errorHandler(diagnostic) {
|
|
if (diagnostic.location) errors.set(diagnostic.location, diagnostic);
|
|
return "Recover";
|
|
}
|
|
|
|
function printDiagnostics() {
|
|
var foundFatal = false;
|
|
if (errors.size > 0) {
|
|
console.error("Errors found while prepacking");
|
|
var _iteratorNormalCompletion = true;
|
|
var _didIteratorError = false;
|
|
var _iteratorError = undefined;
|
|
|
|
try {
|
|
for (var _iterator = errors[Symbol.iterator](), _step; !(_iteratorNormalCompletion = (_step = _iterator.next()).done); _iteratorNormalCompletion = true) {
|
|
var _ref = _step.value;
|
|
|
|
var _ref2 = _slicedToArray(_ref, 2);
|
|
|
|
var loc = _ref2[0];
|
|
var error = _ref2[1];
|
|
|
|
var sourceMessage = "";
|
|
switch (loc.source) {
|
|
case "":
|
|
sourceMessage = "In an unknown source file";
|
|
break;
|
|
case "no-filename-specified":
|
|
sourceMessage = "In stdin";
|
|
break;
|
|
default:
|
|
// flow made me do this || ""
|
|
sourceMessage = "In input file " + (loc.source || "");
|
|
break;
|
|
}
|
|
|
|
foundFatal = foundFatal || error.severity === "FatalError";
|
|
console.error(sourceMessage + "(" + loc.start.line + ":" + (loc.start.column + 1) + ") " + error.severity + " " + error.errorCode + ": " + error.message + (" (https://github.com/facebook/prepack/wiki/" + error.errorCode + ")"));
|
|
if (foundFatal) {
|
|
console.error(error.callStack || "");
|
|
}
|
|
}
|
|
} catch (err) {
|
|
_didIteratorError = true;
|
|
_iteratorError = err;
|
|
} finally {
|
|
try {
|
|
if (!_iteratorNormalCompletion && _iterator.return) {
|
|
_iterator.return();
|
|
}
|
|
} finally {
|
|
if (_didIteratorError) {
|
|
throw _iteratorError;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
return foundFatal;
|
|
}
|
|
|
|
try {
|
|
if (inputFilenames.length === 0) {
|
|
prepackStdin(resolvedOptions, processSerializedCode);
|
|
return;
|
|
}
|
|
var serialized = prepackFileSync(inputFilenames, resolvedOptions);
|
|
processSerializedCode(null, serialized);
|
|
} catch (err) {
|
|
//FatalErrors must have generated at least one CompilerDiagnostic.
|
|
if (err instanceof FatalError) {
|
|
(0, _invariant2.default)(errors.size > 0, "FatalError must generate at least one CompilerDiagnostic");
|
|
} else {
|
|
// if it is not a FatalError, it means prepack failed, and we should display the CompilerDiagnostics and stack trace.
|
|
printDiagnostics();
|
|
console.error(err.stack);
|
|
process.exit(1);
|
|
}
|
|
} finally {
|
|
var foundFatal = printDiagnostics();
|
|
if (foundFatal) process.exit(1);
|
|
}
|
|
|
|
function processSerializedCode(err, serialized) {
|
|
//FatalErrors must have generated at least one CompilerDiagnostic.
|
|
if (err && err instanceof FatalError) {
|
|
(0, _invariant2.default)(errors.size > 0, "FatalError must generate at least one CompilerDiagnostic");
|
|
}
|
|
if (err && !(err instanceof FatalError)) {
|
|
// if it is not a FatalError, it means prepack failed, and we should display the CompilerDiagnostics and stack trace.
|
|
printDiagnostics();
|
|
console.error(err);
|
|
process.exit(1);
|
|
}
|
|
// we print the non-fatal diagnostics. We test again if there is any FatalError-level CompilerDiagnostics that wouldn't have thrown a FatalError.
|
|
var foundFatal = printDiagnostics();
|
|
if (foundFatal) process.exit(1);
|
|
if (serialized) {
|
|
if (serialized.code === "") {
|
|
console.error("Prepack returned empty code.");
|
|
return;
|
|
}
|
|
if (outputFilename) {
|
|
console.log("Prepacked source code written to " + outputFilename + ".");
|
|
fs.writeFileSync(outputFilename, serialized.code);
|
|
} else {
|
|
console.log(serialized.code);
|
|
}
|
|
if (statsFileName) {
|
|
if (serialized.statistics === undefined || serialized.timingStats === undefined) {
|
|
return;
|
|
}
|
|
var stats = {
|
|
SerializerStatistics: serialized.statistics,
|
|
TimingStatistics: serialized.timingStats,
|
|
MemoryStatistics: _v2.default.getHeapStatistics()
|
|
};
|
|
fs.writeFileSync(statsFileName, JSON.stringify(stats));
|
|
}
|
|
if (outputSourceMap) {
|
|
fs.writeFileSync(outputSourceMap, serialized.map ? JSON.stringify(serialized.map) : "");
|
|
}
|
|
if (heapGraphFilePath) {
|
|
(0, _invariant2.default)(serialized.heapGraph);
|
|
fs.writeFileSync(heapGraphFilePath, serialized.heapGraph);
|
|
}
|
|
}
|
|
}
|
|
|
|
return true;
|
|
}
|
|
|
|
if (typeof __residual === "function") {
|
|
// If we're running inside of Prepack. This is the residual function we'll
|
|
// want to leave untouched in the final program.
|
|
__residual("boolean", run, Object, Array, console, JSON, process, _prepackNode.prepackStdin, _prepackNode.prepackFileSync, _errors.FatalError, _options.CompatibilityValues, _fs2.default);
|
|
} else {
|
|
run(Object, Array, console, JSON, process, _prepackNode.prepackStdin, _prepackNode.prepackFileSync, _errors.FatalError, _options.CompatibilityValues, _fs2.default);
|
|
}
|
|
//# sourceMappingURL=prepack-cli.js.map
|