guess-webpack
Version:
Webpack plugins for the Machine Learning-driven bundler
1,048 lines (988 loc) • 41.6 kB
JavaScript
(function webpackUniversalModuleDefinition(root, factory) {
if(typeof exports === 'object' && typeof module === 'object')
module.exports = factory(require("path"), require("lodash.template"), require("memory-fs"), require("webpack"), require("webpack-sources"), require("chalk"), require("table"), require("google-oauth2-node"), require("guess-ga"), require("flat-cache"), require("googleapis"));
else if(typeof define === 'function' && define.amd)
define(["path", "lodash.template", "memory-fs", "webpack", "webpack-sources", "chalk", "table", "google-oauth2-node", "guess-ga", "flat-cache", "googleapis"], factory);
else {
var a = typeof exports === 'object' ? factory(require("path"), require("lodash.template"), require("memory-fs"), require("webpack"), require("webpack-sources"), require("chalk"), require("table"), require("google-oauth2-node"), require("guess-ga"), require("flat-cache"), require("googleapis")) : factory(root["path"], root["lodash.template"], root["memory-fs"], root["webpack"], root["webpack-sources"], root["chalk"], root["table"], root["google-oauth2-node"], root["guess-ga"], root["flat-cache"], root["googleapis"]);
for(var i in a) (typeof exports === 'object' ? exports : root)[i] = a[i];
}
})(global, function(__WEBPACK_EXTERNAL_MODULE__0__, __WEBPACK_EXTERNAL_MODULE__4__, __WEBPACK_EXTERNAL_MODULE__5__, __WEBPACK_EXTERNAL_MODULE__6__, __WEBPACK_EXTERNAL_MODULE__11__, __WEBPACK_EXTERNAL_MODULE__13__, __WEBPACK_EXTERNAL_MODULE__14__, __WEBPACK_EXTERNAL_MODULE__16__, __WEBPACK_EXTERNAL_MODULE__17__, __WEBPACK_EXTERNAL_MODULE__18__, __WEBPACK_EXTERNAL_MODULE__19__) {
return /******/ (function(modules) { // webpackBootstrap
/******/ // The module cache
/******/ var installedModules = {};
/******/
/******/ // The require function
/******/ function __webpack_require__(moduleId) {
/******/
/******/ // Check if module is in cache
/******/ if(installedModules[moduleId]) {
/******/ return installedModules[moduleId].exports;
/******/ }
/******/ // Create a new module (and put it into the cache)
/******/ var module = installedModules[moduleId] = {
/******/ i: moduleId,
/******/ l: false,
/******/ exports: {}
/******/ };
/******/
/******/ // Execute the module function
/******/ modules[moduleId].call(module.exports, module, module.exports, __webpack_require__);
/******/
/******/ // Flag the module as loaded
/******/ module.l = true;
/******/
/******/ // Return the exports of the module
/******/ return module.exports;
/******/ }
/******/
/******/
/******/ // expose the modules object (__webpack_modules__)
/******/ __webpack_require__.m = modules;
/******/
/******/ // expose the module cache
/******/ __webpack_require__.c = installedModules;
/******/
/******/ // define getter function for harmony exports
/******/ __webpack_require__.d = function(exports, name, getter) {
/******/ if(!__webpack_require__.o(exports, name)) {
/******/ Object.defineProperty(exports, name, { enumerable: true, get: getter });
/******/ }
/******/ };
/******/
/******/ // define __esModule on exports
/******/ __webpack_require__.r = function(exports) {
/******/ if(typeof Symbol !== 'undefined' && Symbol.toStringTag) {
/******/ Object.defineProperty(exports, Symbol.toStringTag, { value: 'Module' });
/******/ }
/******/ Object.defineProperty(exports, '__esModule', { value: true });
/******/ };
/******/
/******/ // create a fake namespace object
/******/ // mode & 1: value is a module id, require it
/******/ // mode & 2: merge all properties of value into the ns
/******/ // mode & 4: return value when already ns object
/******/ // mode & 8|1: behave like require
/******/ __webpack_require__.t = function(value, mode) {
/******/ if(mode & 1) value = __webpack_require__(value);
/******/ if(mode & 8) return value;
/******/ if((mode & 4) && typeof value === 'object' && value && value.__esModule) return value;
/******/ var ns = Object.create(null);
/******/ __webpack_require__.r(ns);
/******/ Object.defineProperty(ns, 'default', { enumerable: true, value: value });
/******/ if(mode & 2 && typeof value != 'string') for(var key in value) __webpack_require__.d(ns, key, function(key) { return value[key]; }.bind(null, key));
/******/ return ns;
/******/ };
/******/
/******/ // getDefaultExport function for compatibility with non-harmony modules
/******/ __webpack_require__.n = function(module) {
/******/ var getter = module && module.__esModule ?
/******/ function getDefault() { return module['default']; } :
/******/ function getModuleExports() { return module; };
/******/ __webpack_require__.d(getter, 'a', getter);
/******/ return getter;
/******/ };
/******/
/******/ // Object.prototype.hasOwnProperty.call
/******/ __webpack_require__.o = function(object, property) { return Object.prototype.hasOwnProperty.call(object, property); };
/******/
/******/ // __webpack_public_path__
/******/ __webpack_require__.p = "";
/******/
/******/
/******/ // Load entry module and return exports
/******/ return __webpack_require__(__webpack_require__.s = 7);
/******/ })
/************************************************************************/
/******/ ([
/* 0 */
/***/ (function(module, exports) {
module.exports = __WEBPACK_EXTERNAL_MODULE__0__;
/***/ }),
/* 1 */
/***/ (function(module, exports) {
module.exports = require("fs");
/***/ }),
/* 2 */
/***/ (function(module, exports, __webpack_require__) {
;
Object.defineProperty(exports, "__esModule", { value: true });
var path_1 = __webpack_require__(0);
exports.defaultPrefetchConfig = {
'4g': 0.15,
'3g': 0.3,
'2g': 0.45,
'slow-2g': 0.6
};
var validateInput = function (routes, graph, logger, debug) {
var routesInReport = new Set();
Object.keys(graph).forEach(function (r) {
routesInReport.add(r);
Object.keys(graph[r]).forEach(function (c) { return routesInReport.add(c); });
});
routes
.map(function (r) { return r.path; })
.filter(function (x) { return !routesInReport.has(x); })
.forEach(function (r) {
if (debug) {
logger.debug("The route " + r + " is not present in the report or in the route declarations");
}
});
};
exports.buildMap = function (routes, graph, logger, debug) {
validateInput(routes, graph, logger, debug);
var result = {};
var routeFile = {};
routes.forEach(function (r) {
routeFile[r.path] = r.modulePath;
});
Object.keys(graph).forEach(function (route) {
result[route] = [];
var sum = Object.keys(graph[route]).reduce(function (a, n) { return a + graph[route][n]; }, 0);
Object.keys(graph[route]).forEach(function (n) {
result[route].push({
route: n,
probability: graph[route][n] / sum,
file: routeFile[n]
});
});
result[route] = result[route].sort(function (a, b) { return b.probability - a.probability; });
});
return result;
};
exports.stripExtension = function (path) { return path.replace(/\.(j|t)sx?$/, ''); };
var getChunkJsFile = function (chunk) {
return chunk.files.filter(function (f) { return f.endsWith('.js'); }).shift();
};
var getChunkDependencyGraph = function (stats) {
var chunkGraph = {};
var chunkIdToChunk = {};
stats.chunks.forEach(function (chunk) { return chunkIdToChunk[chunk.id] = chunk; });
var moduleIdToModule = {};
stats.modules.forEach(function (module) { return moduleIdToModule[module.id] = module; });
stats.modules.forEach(function (module) {
var moduleChunks = module.chunks.map(function (id) { return chunkIdToChunk[id]; });
module.reasons.forEach(function (reason) {
var dependent = moduleIdToModule[reason.moduleId];
if (!dependent) {
return;
}
var dependentChunks = dependent.chunks.map(function (id) { return chunkIdToChunk[id]; });
dependentChunks.forEach(function (dependentChunk) {
var file = getChunkJsFile(dependentChunk);
if (!file) {
return;
}
chunkGraph[file] = chunkGraph[file] || new Set();
moduleChunks.forEach(function (dependencyChunk) {
if (dependencyChunk.initial) {
return;
}
var dependencyFile = getChunkJsFile(dependencyChunk);
if (!dependencyFile) {
return;
}
chunkGraph[file].add(dependencyFile);
});
});
});
});
return chunkGraph;
};
exports.getCompilationMapping = function (compilation, entryPoints, logger) {
var mainName = null;
var mainPriority = Infinity;
function getModulePath(moduleName) {
var cwd = process.cwd();
var relativePath = moduleName
.split(' ')
.filter(function (p) { return /(\.)?(\/|\\)/.test(p); })
.pop();
if (relativePath === undefined) {
return null;
}
var jsPath = exports.stripExtension(relativePath.replace(/\.ngfactory\.js$/, '.js'));
return path_1.join(cwd, jsPath);
}
var jsonStats = compilation.getStats().toJson();
var chunkDepGraph = getChunkDependencyGraph(jsonStats);
logger.debug('Chunk dependency graph', chunkDepGraph);
var fileChunk = {};
jsonStats
.chunks.forEach(function (c) {
var jsFile = getChunkJsFile(c);
if (!jsFile) {
return;
}
if (c.initial) {
var pickers = [
function (f) { return f.startsWith('main') && f.endsWith('.js'); },
function (f) { return f.indexOf('/main') >= 0 && f.endsWith('.js'); },
function (f) { return f.startsWith('runtime') && f.endsWith('.js'); },
function (f) { return f.indexOf('/runtime') >= 0 && f.endsWith('.js'); },
function (f) { return f.startsWith('vendor') && f.endsWith('.js'); },
function (f) { return f.indexOf('/vendor') >= 0 && f.endsWith('.js'); },
function (f) { return f.startsWith('common') && f.endsWith('.js'); },
function (f) { return f.endsWith('.js'); },
];
var currentMain = null;
var currentPriority = 0;
while (!currentMain && pickers.length) {
currentMain = c.files.filter(pickers.shift()).pop();
currentPriority++;
}
if (mainPriority > currentPriority) {
mainName = currentMain;
mainPriority = currentPriority;
}
}
if (c.modules && c.modules.length) {
var existingEntries = c.modules.filter(function (m) {
var path = getModulePath(m.name);
if (!path) {
return false;
}
return entryPoints.has(path);
});
if (existingEntries.length > 1) {
logger.debug('There are more than two entry points associated with chunk', jsFile);
}
else if (existingEntries.length === 0) {
logger.debug('Cannot find entry point for chunk: ' + jsFile);
}
else {
var path = getModulePath(existingEntries[0].name);
if (path) {
fileChunk[path] = fileChunk[path] || { file: jsFile, deps: chunkDepGraph[jsFile] };
}
}
}
else {
logger.debug('Cannot find modules for chunk', jsFile);
}
});
return { mainName: mainName, fileChunk: fileChunk };
};
/***/ }),
/* 3 */
/***/ (function(module, exports, __webpack_require__) {
;
var __read = (this && this.__read) || function (o, n) {
var m = typeof Symbol === "function" && o[Symbol.iterator];
if (!m) return o;
var i = m.call(o), r, ar = [], e;
try {
while ((n === void 0 || n-- > 0) && !(r = i.next()).done) ar.push(r.value);
}
catch (error) { e = { error: error }; }
finally {
try {
if (r && !r.done && (m = i["return"])) m.call(i);
}
finally { if (e) throw e.error; }
}
return ar;
};
var __spread = (this && this.__spread) || function () {
for (var ar = [], i = 0; i < arguments.length; i++) ar = ar.concat(__read(arguments[i]));
return ar;
};
Object.defineProperty(exports, "__esModule", { value: true });
var LogLevel;
(function (LogLevel) {
LogLevel[LogLevel["DEBUG"] = 0] = "DEBUG";
LogLevel[LogLevel["INFO"] = 1] = "INFO";
LogLevel[LogLevel["WARN"] = 2] = "WARN";
LogLevel[LogLevel["ERROR"] = 3] = "ERROR";
LogLevel[LogLevel["OFF"] = 4] = "OFF";
})(LogLevel = exports.LogLevel || (exports.LogLevel = {}));
var Logger = /** @class */ (function () {
function Logger(level) {
if (level === void 0) { level = LogLevel.INFO; }
this.level = level;
}
Logger.prototype.setLevel = function (newLevel) {
this.level = newLevel;
};
Logger.prototype.debug = function () {
var msg = [];
for (var _i = 0; _i < arguments.length; _i++) {
msg[_i] = arguments[_i];
}
this.print(LogLevel.DEBUG, 'DEBUG', msg);
};
Logger.prototype.info = function () {
var msg = [];
for (var _i = 0; _i < arguments.length; _i++) {
msg[_i] = arguments[_i];
}
this.print(LogLevel.INFO, 'INFO', msg);
};
Logger.prototype.warn = function () {
var msg = [];
for (var _i = 0; _i < arguments.length; _i++) {
msg[_i] = arguments[_i];
}
this.print(LogLevel.WARN, 'WARN', msg);
};
Logger.prototype.error = function () {
var msg = [];
for (var _i = 0; _i < arguments.length; _i++) {
msg[_i] = arguments[_i];
}
this.print(LogLevel.ERROR, 'ERROR', msg);
};
Logger.prototype.print = function (level, label, msg) {
if (level >= this.level) {
switch (level) {
case LogLevel.DEBUG:
console.debug.apply(console, __spread([this.prettify(label)], msg));
break;
case LogLevel.INFO:
console.info.apply(console, __spread([this.prettify(label)], msg));
break;
case LogLevel.WARN:
console.warn.apply(console, __spread([this.prettify(label)], msg));
break;
case LogLevel.ERROR:
console.error.apply(console, __spread([this.prettify(label)], msg));
break;
default:
console.log.apply(console, __spread([this.prettify(label)], msg));
break;
}
}
};
Logger.prototype.prettify = function (label) {
return label + "::" + Date.now() + "::";
};
return Logger;
}());
exports.Logger = Logger;
/***/ }),
/* 4 */
/***/ (function(module, exports) {
module.exports = __WEBPACK_EXTERNAL_MODULE__4__;
/***/ }),
/* 5 */
/***/ (function(module, exports) {
module.exports = __WEBPACK_EXTERNAL_MODULE__5__;
/***/ }),
/* 6 */
/***/ (function(module, exports) {
module.exports = __WEBPACK_EXTERNAL_MODULE__6__;
/***/ }),
/* 7 */
/***/ (function(module, exports, __webpack_require__) {
;
function __export(m) {
for (var p in m) if (!exports.hasOwnProperty(p)) exports[p] = m[p];
}
Object.defineProperty(exports, "__esModule", { value: true });
__export(__webpack_require__(8));
/***/ }),
/* 8 */
/***/ (function(module, exports, __webpack_require__) {
;
var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
return new (P || (P = Promise))(function (resolve, reject) {
function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
function step(result) { result.done ? resolve(result.value) : new P(function (resolve) { resolve(result.value); }).then(fulfilled, rejected); }
step((generator = generator.apply(thisArg, _arguments || [])).next());
});
};
var __generator = (this && this.__generator) || function (thisArg, body) {
var _ = { label: 0, sent: function() { if (t[0] & 1) throw t[1]; return t[1]; }, trys: [], ops: [] }, f, y, t, g;
return g = { next: verb(0), "throw": verb(1), "return": verb(2) }, typeof Symbol === "function" && (g[Symbol.iterator] = function() { return this; }), g;
function verb(n) { return function (v) { return step([n, v]); }; }
function step(op) {
if (f) throw new TypeError("Generator is already executing.");
while (_) try {
if (f = 1, y && (t = op[0] & 2 ? y["return"] : op[0] ? y["throw"] || ((t = y["return"]) && t.call(y), 0) : y.next) && !(t = t.call(y, op[1])).done) return t;
if (y = 0, t) op = [op[0] & 2, t.value];
switch (op[0]) {
case 0: case 1: t = op; break;
case 4: _.label++; return { value: op[1], done: false };
case 5: _.label++; y = op[1]; op = [0]; continue;
case 7: op = _.ops.pop(); _.trys.pop(); continue;
default:
if (!(t = _.trys, t = t.length > 0 && t[t.length - 1]) && (op[0] === 6 || op[0] === 2)) { _ = 0; continue; }
if (op[0] === 3 && (!t || (op[1] > t[0] && op[1] < t[3]))) { _.label = op[1]; break; }
if (op[0] === 6 && _.label < t[1]) { _.label = t[1]; t = op; break; }
if (t && _.label < t[2]) { _.label = t[2]; _.ops.push(op); break; }
if (t[2]) _.ops.pop();
_.trys.pop(); continue;
}
op = body.call(thisArg, _);
} catch (e) { op = [6, e]; y = 0; } finally { f = t = 0; }
if (op[0] & 5) throw op[1]; return { value: op[0] ? op[1] : void 0, done: true };
}
};
Object.defineProperty(exports, "__esModule", { value: true });
var prefetch_plugin_1 = __webpack_require__(9);
var prefetch_aot_plugin_1 = __webpack_require__(12);
var ga_provider_1 = __webpack_require__(15);
var asset_observer_1 = __webpack_require__(20);
var extractRoutes = function (config) {
if (config.routeProvider === false || config.routeProvider === undefined) {
return Promise.resolve([]);
}
if (typeof config.routeProvider === 'function') {
return Promise.resolve(config.routeProvider());
}
throw new Error('The routeProvider should be either set to false or a function which returns the routes in the app.');
};
var GuessPlugin = /** @class */ (function () {
function GuessPlugin(_config) {
this._config = _config;
if ((this._config.GA || this._config.jwt) && this._config.reportProvider) {
throw new Error('Only a single report provider is allowed. You have specified `GA` and/or ' +
'a GA authentication provider (used by Google Analytics provider) and `reportProvider`');
}
if (!this._config.GA && !this._config.reportProvider) {
throw new Error('Report provider not specified. You should specify either a `GA` (Google Analytics view ID) or `reportProvider`.');
}
}
GuessPlugin.prototype.apply = function (compiler) {
var _this = this;
var assetObserver = new asset_observer_1.AssetObserver();
if (!this._config.runtime || !this._config.runtime.delegate) {
compiler.hooks.assetEmitted.tapAsync('GuessPlugin', function (file, _, callback) {
return assetObserver.addAsset({
name: file,
callback: callback
});
});
}
compiler.hooks.emit.tapAsync({
stage: 0,
name: 'GuessPlugin'
}, function (compilation, cb) { return _this._execute(compiler, compilation, assetObserver, cb); });
};
GuessPlugin.prototype._execute = function (compiler, compilation, assetObserver, cb) {
var _this = this;
extractRoutes(this._config).then(function (routes) { return __awaiter(_this, void 0, void 0, function () {
var data, err_1;
return __generator(this, function (_a) {
switch (_a.label) {
case 0:
_a.trys.push([0, 2, , 3]);
return [4 /*yield*/, this._getReport(routes)];
case 1:
data = _a.sent();
return [2 /*return*/, this._executePrefetchPlugin(data, routes, compiler, compilation, assetObserver, cb)];
case 2:
err_1 = _a.sent();
console.error(err_1);
cb();
throw err_1;
case 3: return [2 /*return*/];
}
});
}); });
};
GuessPlugin.prototype._getReport = function (routes) {
if (this._config.GA) {
return ga_provider_1.getReport({
jwt: this._config.jwt,
viewId: this._config.GA,
routes: routes,
formatter: this._config.routeFormatter,
period: this._config.period
});
}
else {
return this._config.reportProvider();
}
};
GuessPlugin.prototype._executePrefetchPlugin = function (data, routes, compiler, compilation, assetObserver, cb) {
var runtime = this._config.runtime;
if (runtime && runtime.delegate) {
new prefetch_plugin_1.PrefetchPlugin({
data: data,
debug: this._config.debug,
basePath: runtime
? runtime.base === undefined
? ''
: runtime.base
: '',
prefetchConfig: runtime ? runtime.prefetchConfig : undefined,
routes: routes,
delegate: runtime ? !!runtime.delegate : true
}).execute(compilation, cb);
}
else {
new prefetch_aot_plugin_1.PrefetchAotPlugin({
data: data,
debug: this._config.debug,
base: runtime
? runtime.base === undefined
? ''
: runtime.base
: '',
prefetchConfig: runtime ? runtime.prefetchConfig : undefined,
routes: routes
}).execute(compiler, compilation, assetObserver, cb);
}
};
return GuessPlugin;
}());
exports.GuessPlugin = GuessPlugin;
/***/ }),
/* 9 */
/***/ (function(module, exports, __webpack_require__) {
;
var __assign = (this && this.__assign) || function () {
__assign = Object.assign || function(t) {
for (var s, i = 1, n = arguments.length; i < n; i++) {
s = arguments[i];
for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p))
t[p] = s[p];
}
return t;
};
return __assign.apply(this, arguments);
};
Object.defineProperty(exports, "__esModule", { value: true });
var fs_1 = __webpack_require__(1);
var compress_1 = __webpack_require__(10);
var path_1 = __webpack_require__(0);
var utils_1 = __webpack_require__(2);
var logger_1 = __webpack_require__(3);
var template = __webpack_require__(4);
var ConcatSource = __webpack_require__(11).ConcatSource;
var PrefetchPlugin = /** @class */ (function () {
function PrefetchPlugin(_config) {
this._config = _config;
this.logger = new logger_1.Logger();
if (!_config.data) {
throw new Error('Page graph not provided');
}
}
PrefetchPlugin.prototype.execute = function (compilation, callback) {
var mainName = null;
var fileChunk = {};
try {
var res = utils_1.getCompilationMapping(compilation, new Set(this._config.routes.map(function (r) { return utils_1.stripExtension(r.modulePath); })), this.logger);
mainName = res.mainName;
fileChunk = res.fileChunk;
}
catch (e) {
callback();
console.error(e);
}
if (mainName === null) {
callback();
throw new Error('Cannot find the main chunk of the application');
}
var newConfig = {};
var initialGraph = utils_1.buildMap(this._config.routes.map(function (r) {
return __assign({}, r, { modulePath: utils_1.stripExtension(r.modulePath), parentModulePath: r.parentModulePath ? utils_1.stripExtension(r.parentModulePath) : null });
}), this._config.data, this.logger, !!this._config.debug);
Object.keys(initialGraph).forEach(function (c) {
newConfig[c] = [];
initialGraph[c].forEach(function (p) {
var node = fileChunk[p.file];
var newTransition = {
probability: p.probability,
route: p.route,
// In delegate mode we don't care about chunks
// so it's fine if the mapping file/chunk is missing.
chunk: (node || { file: '' }).file
};
newConfig[c].push(newTransition);
});
});
var old = compilation.assets[mainName];
var _a = compress_1.compressGraph(newConfig, 3), graph = _a.graph, graphMap = _a.graphMap;
var codeTemplate = 'runtime.tpl';
var runtimeTemplate = fs_1.readFileSync(path_1.join(__dirname, codeTemplate)).toString();
var runtimeLogic = template(runtimeTemplate)({
BASE_PATH: this._config.basePath,
GRAPH: JSON.stringify(graph),
GRAPH_MAP: JSON.stringify(graphMap),
THRESHOLDS: JSON.stringify(Object.assign({}, utils_1.defaultPrefetchConfig, this._config.prefetchConfig))
});
var MemoryFileSystem = __webpack_require__(5);
var memoryFs = new MemoryFileSystem();
memoryFs.mkdirpSync('/src');
memoryFs.writeFileSync('/src/index.js', runtimeLogic, 'utf-8');
memoryFs.writeFileSync('/src/guess.js', fs_1.readFileSync(path_1.join(__dirname, 'guess.js')).toString(), 'utf-8');
memoryFs.writeFileSync('/src/runtime.js', fs_1.readFileSync(path_1.join(__dirname, 'runtime.js')).toString(), 'utf-8');
var compiler = __webpack_require__(6)({
context: '/src/',
mode: 'production',
entry: './index.js',
target: 'node',
output: {
filename: './output.js'
}
});
compiler.inputFileSystem = memoryFs;
compiler.outputFileSystem = memoryFs;
compiler.resolvers.normal.fileSystem = memoryFs;
compiler.resolvers.context.fileSystem = memoryFs;
compiler.run(function (err, stats) {
if (err) {
callback();
throw err;
}
compilation.assets[mainName] = new ConcatSource(stats.compilation.assets['./output.js'], '\n', old.source());
callback();
});
};
return PrefetchPlugin;
}());
exports.PrefetchPlugin = PrefetchPlugin;
/***/ }),
/* 10 */
/***/ (function(module, exports, __webpack_require__) {
;
Object.defineProperty(exports, "__esModule", { value: true });
exports.compressGraph = function (input, precision) {
var currentChunk = 0;
var currentRoute = 0;
var chunks = [];
var routes = [];
var chunkToID = {};
var routeToID = {};
var graphMap = { chunks: chunks, routes: routes };
var graph = [];
Object.keys(input).forEach(function (route) {
if (routeToID[route] === undefined) {
routes[currentRoute] = route;
routeToID[route] = currentRoute++;
}
graph[routeToID[route]] = [];
input[route].forEach(function (n) {
if (routeToID[n.route] === undefined) {
routes[currentRoute] = n.route;
routeToID[n.route] = currentRoute++;
}
if (chunkToID[n.chunk] === undefined) {
chunks[currentChunk] = n.chunk;
chunkToID[n.chunk] = currentChunk++;
}
graph[routeToID[route]].push([
parseFloat(n.probability.toFixed(precision)),
routeToID[n.route],
chunkToID[n.chunk]
]);
});
});
return { graph: graph, graphMap: graphMap };
};
/***/ }),
/* 11 */
/***/ (function(module, exports) {
module.exports = __WEBPACK_EXTERNAL_MODULE__11__;
/***/ }),
/* 12 */
/***/ (function(module, exports, __webpack_require__) {
;
var __assign = (this && this.__assign) || function () {
__assign = Object.assign || function(t) {
for (var s, i = 1, n = arguments.length; i < n; i++) {
s = arguments[i];
for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p))
t[p] = s[p];
}
return t;
};
return __assign.apply(this, arguments);
};
var __read = (this && this.__read) || function (o, n) {
var m = typeof Symbol === "function" && o[Symbol.iterator];
if (!m) return o;
var i = m.call(o), r, ar = [], e;
try {
while ((n === void 0 || n-- > 0) && !(r = i.next()).done) ar.push(r.value);
}
catch (error) { e = { error: error }; }
finally {
try {
if (r && !r.done && (m = i["return"])) m.call(i);
}
finally { if (e) throw e.error; }
}
return ar;
};
var __spread = (this && this.__spread) || function () {
for (var ar = [], i = 0; i < arguments.length; i++) ar = ar.concat(__read(arguments[i]));
return ar;
};
Object.defineProperty(exports, "__esModule", { value: true });
var fs_1 = __webpack_require__(1);
var path_1 = __webpack_require__(0);
var chalk_1 = __webpack_require__(13);
var utils_1 = __webpack_require__(2);
var logger_1 = __webpack_require__(3);
var template = __webpack_require__(4);
var table = __webpack_require__(14).table;
var alterChunk = function (compiler, chunkName, original, toAlter, toBundle) {
var promise = !toBundle
? Promise.resolve(toAlter)
: new Promise(function (resolve, reject) {
var MemoryFileSystem = __webpack_require__(5);
var memoryFs = new MemoryFileSystem();
memoryFs.mkdirpSync('/src');
memoryFs.writeFileSync('/src/index.js', toAlter, 'utf-8');
memoryFs.writeFileSync('/src/guess-aot.js', fs_1.readFileSync(path_1.join(__dirname, 'guess-aot.js')).toString(), 'utf-8');
var inMemoryCompiler = __webpack_require__(6)({
context: '/src/',
mode: 'production',
entry: './index.js',
target: 'node',
output: {
filename: './output.js'
}
});
inMemoryCompiler.inputFileSystem = memoryFs;
inMemoryCompiler.outputFileSystem = memoryFs;
inMemoryCompiler.resolvers.normal.fileSystem = memoryFs;
inMemoryCompiler.resolvers.context.fileSystem = memoryFs;
inMemoryCompiler.run(function (err, stats) {
if (err) {
reject();
throw err;
}
resolve(stats.compilation.assets['./output.js'].source());
});
});
return promise.then(function (output) {
return new Promise(function (resolve, reject) {
fs_1.writeFile(path_1.join(compiler.outputPath, chunkName), original + '\n' + output, function (err) {
if (err) {
reject(err);
}
resolve();
});
});
});
};
var PrefetchAotPlugin = /** @class */ (function () {
function PrefetchAotPlugin(_config) {
this._config = _config;
this.logger = new logger_1.Logger();
if (!_config.data) {
throw new Error('Page graph not provided');
}
if (this._config.debug) {
this.logger.setLevel(logger_1.LogLevel.DEBUG);
}
}
PrefetchAotPlugin.prototype.execute = function (compiler, compilation, assetObserver, callback) {
var _this = this;
this.logger.debug('Inside PrefetchAotPlugin');
var mainName = null;
var fileChunk = {};
try {
var res = utils_1.getCompilationMapping(compilation, new Set(this._config.routes.map(function (r) { return utils_1.stripExtension(r.modulePath); })), this.logger);
mainName = res.mainName;
fileChunk = res.fileChunk;
}
catch (e) {
callback();
this.logger.error(e);
return;
}
this.logger.debug('Mapping between chunk name and entry point', JSON.stringify(fileChunk, null, 2));
if (!mainName) {
callback();
throw new Error('Cannot find the main chunk of the application');
}
var newConfig = {};
var chunkRoute = {};
var initialGraph = utils_1.buildMap(this._config.routes.map(function (r) {
return __assign({}, r, { modulePath: utils_1.stripExtension(r.modulePath), parentModulePath: r.parentModulePath
? utils_1.stripExtension(r.parentModulePath)
: null });
}), this._config.data, this.logger, !!this._config.debug);
this.logger.debug('Initial mapping between routes and probability', JSON.stringify(initialGraph, null, 2));
Object.keys(initialGraph).forEach(function (route) {
newConfig[route] = [];
initialGraph[route].forEach(function (neighbor) {
var node = fileChunk[neighbor.file];
if (!node) {
_this.logger.debug('No chunk for file', neighbor.file);
return;
}
chunkRoute[node.file] = neighbor.route;
var newTransition = {
probability: neighbor.probability,
chunks: __spread(new Set(__spread([node.file], node.deps)))
};
newConfig[route].push(newTransition);
});
});
this.logger.debug('Built the model', JSON.stringify(newConfig, null, 2));
this.logger.debug('File to chunk mapping', JSON.stringify(fileChunk, null, 2));
this.logger.debug('Chunk to route mapping is', JSON.stringify(chunkRoute, null, 2));
chunkRoute[mainName] = '/';
var tableOutput = [['Prefetcher', 'Target', 'Probability']];
var generateNeighbors = function (route, currentChunk, c) {
if (!c.chunks || !c.chunks.length) {
_this.logger.debug('Cannot find chunk name for', c, 'from route', route);
return false;
}
tableOutput.push([currentChunk, c.chunks[0], c.probability]);
return [
c.probability,
"[" + parseFloat(c.probability.toFixed(2)) + "," + c.chunks
.map(function (chunk) { return "'" + chunk + "'"; })
.join(',') + "]"
];
};
var chunksLeft = Object.keys(chunkRoute).length;
var conf = this._config.prefetchConfig || utils_1.defaultPrefetchConfig;
var minProbability = Math.min(conf['2g'], conf['3g'], conf['4g'], conf['slow-2g']);
var handleAsset = function (asset) {
var chunkName = asset.name;
var route = chunkRoute[chunkName];
if (!route) {
_this.logger.debug("Cannot find the route \"" + route + "\" for chunk \"" + chunkName + "\"");
asset.callback();
return;
}
var neighbors = (newConfig[route] || [])
.map(generateNeighbors.bind(null, route, chunkName))
.filter(Boolean)
.sort(function (a, b) { return (a === false || b === false ? 0 : b[0] - a[0]); })
.filter(function (n) { return n === false ? false : n[0] >= minProbability; })
.map(function (n) { return (n === false ? null : n[1]); });
if (newConfig[route]) {
_this.logger.debug('Adding', neighbors);
}
else {
_this.logger.debug('Nothing to prefetch from', route);
}
var newCode = newConfig[route]
? "__GUESS__.p(" + neighbors.join(',') + ")"
: '';
var isMainChunk = mainName === chunkName;
if (isMainChunk) {
_this.logger.debug('Adding prefetching logic in', mainName);
var codeTemplate = 'aot.tpl';
var runtimeTemplate = fs_1.readFileSync(path_1.join(__dirname, codeTemplate)).toString();
var prefetchingLogic = template(runtimeTemplate)({
THRESHOLDS: JSON.stringify(Object.assign({}, utils_1.defaultPrefetchConfig, _this._config.prefetchConfig)),
BASE_PATH: _this._config.base
});
newCode = prefetchingLogic + ';' + newCode;
_this.logger.debug('Altering the main chunk');
}
alterChunk(compiler, chunkName, fs_1.readFileSync(path_1.join(compiler.outputPath, chunkName)).toString(), newCode, isMainChunk).finally(asset.callback);
chunksLeft -= 1;
if (!chunksLeft) {
_this.logger.info(chalk_1.default.blue('\n\n\n🔮 Guess.js introduced the following prefetching instructions:'));
_this.logger.info('\n\n' + table(tableOutput));
}
};
assetObserver.onAsset(handleAsset);
assetObserver.buffer.forEach(handleAsset);
callback();
};
return PrefetchAotPlugin;
}());
exports.PrefetchAotPlugin = PrefetchAotPlugin;
/***/ }),
/* 13 */
/***/ (function(module, exports) {
module.exports = __WEBPACK_EXTERNAL_MODULE__13__;
/***/ }),
/* 14 */
/***/ (function(module, exports) {
module.exports = __WEBPACK_EXTERNAL_MODULE__14__;
/***/ }),
/* 15 */
/***/ (function(module, exports, __webpack_require__) {
;
Object.defineProperty(exports, "__esModule", { value: true });
var google_oauth2_node_1 = __webpack_require__(16);
var guess_ga_1 = __webpack_require__(17);
var clientId = '329457372673-hda3mp2vghisfobn213jpj8ck1uohi2d.apps.googleusercontent.com';
var clientSecret = '4camaoQPOz9edR-Oz19vg-lN';
var scope = 'https://www.googleapis.com/auth/analytics.readonly';
var year = 365 * 24 * 60 * 60 * 1000;
var flatCache = __webpack_require__(18);
var cache = flatCache.load('guess-plugin');
var id = function (r) { return r; };
var serializePeriod = function (period) { return period.startDate.getTime() + "-" + period.endDate.getTime(); };
exports.getReport = function (c) {
var period = c.period || { startDate: new Date(Date.now() - year), endDate: new Date() };
var key = c.viewId + "-" + serializePeriod(period);
var report = cache.getKey(key);
if (report) {
return Promise.resolve(JSON.parse(report));
}
var google = __webpack_require__(19).google;
var client;
if (!c.jwt) {
client = google_oauth2_node_1.auth({
clientId: clientId,
clientSecret: clientSecret,
scope: scope
}).then(function (token) {
var oauth2Client = new google.auth.OAuth2();
oauth2Client.setCredentials(token);
return oauth2Client;
});
}
else {
client = Promise.resolve(new google.auth.JWT(c.jwt.client_email, null, c.jwt.private_key, [scope], null));
}
return client
.then(function (auth) {
return guess_ga_1.fetch({
viewId: c.viewId,
auth: auth,
period: period,
routes: c.routes.map(function (r) { return r.path; }),
formatter: c.formatter || id
});
})
.then(function (g) {
cache.setKey(key, JSON.stringify(g));
cache.save();
return g;
});
};
/***/ }),
/* 16 */
/***/ (function(module, exports) {
module.exports = __WEBPACK_EXTERNAL_MODULE__16__;
/***/ }),
/* 17 */
/***/ (function(module, exports) {
module.exports = __WEBPACK_EXTERNAL_MODULE__17__;
/***/ }),
/* 18 */
/***/ (function(module, exports) {
module.exports = __WEBPACK_EXTERNAL_MODULE__18__;
/***/ }),
/* 19 */
/***/ (function(module, exports) {
module.exports = __WEBPACK_EXTERNAL_MODULE__19__;
/***/ }),
/* 20 */
/***/ (function(module, exports, __webpack_require__) {
;
Object.defineProperty(exports, "__esModule", { value: true });
var AssetObserver = /** @class */ (function () {
function AssetObserver() {
this.buffer = [];
this._callbacks = [];
}
AssetObserver.prototype.onAsset = function (cb) {
this._callbacks.push(cb);
};
AssetObserver.prototype.addAsset = function (asset) {
this._callbacks.forEach(function (cb) { return cb(asset); });
};
return AssetObserver;
}());
exports.AssetObserver = AssetObserver;
/***/ })
/******/ ]);
});