From e06ec920f7a5d784e674c4c4b4e6d1da3dc7391d Mon Sep 17 00:00:00 2001 From: Piotr Russ Date: Mon, 16 Nov 2020 00:10:28 +0100 Subject: api, login, auth --- .../webpack/lib/web/JsonpMainTemplatePlugin.js | 615 +++++++++++++++++++++ 1 file changed, 615 insertions(+) create mode 100644 node_modules/webpack/lib/web/JsonpMainTemplatePlugin.js (limited to 'node_modules/webpack/lib/web/JsonpMainTemplatePlugin.js') diff --git a/node_modules/webpack/lib/web/JsonpMainTemplatePlugin.js b/node_modules/webpack/lib/web/JsonpMainTemplatePlugin.js new file mode 100644 index 0000000..5fcc8d8 --- /dev/null +++ b/node_modules/webpack/lib/web/JsonpMainTemplatePlugin.js @@ -0,0 +1,615 @@ +/* + MIT License http://www.opensource.org/licenses/mit-license.php + Author Tobias Koppers @sokra +*/ +"use strict"; + +const { SyncWaterfallHook } = require("tapable"); +const Template = require("../Template"); + +class JsonpMainTemplatePlugin { + apply(mainTemplate) { + const needChunkOnDemandLoadingCode = chunk => { + for (const chunkGroup of chunk.groupsIterable) { + if (chunkGroup.getNumberOfChildren() > 0) return true; + } + return false; + }; + const needChunkLoadingCode = chunk => { + for (const chunkGroup of chunk.groupsIterable) { + if (chunkGroup.chunks.length > 1) return true; + if (chunkGroup.getNumberOfChildren() > 0) return true; + } + return false; + }; + const needEntryDeferringCode = chunk => { + for (const chunkGroup of chunk.groupsIterable) { + if (chunkGroup.chunks.length > 1) return true; + } + return false; + }; + const needPrefetchingCode = chunk => { + const allPrefetchChunks = chunk.getChildIdsByOrdersMap(true).prefetch; + return allPrefetchChunks && Object.keys(allPrefetchChunks).length; + }; + + // TODO webpack 5, no adding to .hooks, use WeakMap and static methods + ["jsonpScript", "linkPreload", "linkPrefetch"].forEach(hook => { + if (!mainTemplate.hooks[hook]) { + mainTemplate.hooks[hook] = new SyncWaterfallHook([ + "source", + "chunk", + "hash" + ]); + } + }); + + const getScriptSrcPath = (hash, chunk, chunkIdExpression) => { + const chunkFilename = mainTemplate.outputOptions.chunkFilename; + const chunkMaps = chunk.getChunkMaps(); + return mainTemplate.getAssetPath(JSON.stringify(chunkFilename), { + hash: `" + ${mainTemplate.renderCurrentHashCode(hash)} + "`, + hashWithLength: length => + `" + ${mainTemplate.renderCurrentHashCode(hash, length)} + "`, + chunk: { + id: `" + ${chunkIdExpression} + "`, + hash: `" + ${JSON.stringify( + chunkMaps.hash + )}[${chunkIdExpression}] + "`, + hashWithLength(length) { + const shortChunkHashMap = Object.create(null); + for (const chunkId of Object.keys(chunkMaps.hash)) { + if (typeof chunkMaps.hash[chunkId] === "string") { + shortChunkHashMap[chunkId] = chunkMaps.hash[chunkId].substr( + 0, + length + ); + } + } + return `" + ${JSON.stringify( + shortChunkHashMap + )}[${chunkIdExpression}] + "`; + }, + name: `" + (${JSON.stringify( + chunkMaps.name + )}[${chunkIdExpression}]||${chunkIdExpression}) + "`, + contentHash: { + javascript: `" + ${JSON.stringify( + chunkMaps.contentHash.javascript + )}[${chunkIdExpression}] + "` + }, + contentHashWithLength: { + javascript: length => { + const shortContentHashMap = {}; + const contentHash = chunkMaps.contentHash.javascript; + for (const chunkId of Object.keys(contentHash)) { + if (typeof contentHash[chunkId] === "string") { + shortContentHashMap[chunkId] = contentHash[chunkId].substr( + 0, + length + ); + } + } + return `" + ${JSON.stringify( + shortContentHashMap + )}[${chunkIdExpression}] + "`; + } + } + }, + contentHashType: "javascript" + }); + }; + mainTemplate.hooks.localVars.tap( + "JsonpMainTemplatePlugin", + (source, chunk, hash) => { + const extraCode = []; + if (needChunkLoadingCode(chunk)) { + extraCode.push( + "", + "// object to store loaded and loading chunks", + "// undefined = chunk not loaded, null = chunk preloaded/prefetched", + "// Promise = chunk loading, 0 = chunk loaded", + "var installedChunks = {", + Template.indent( + chunk.ids.map(id => `${JSON.stringify(id)}: 0`).join(",\n") + ), + "};", + "", + needEntryDeferringCode(chunk) + ? needPrefetchingCode(chunk) + ? "var deferredModules = [], deferredPrefetch = [];" + : "var deferredModules = [];" + : "" + ); + } + if (needChunkOnDemandLoadingCode(chunk)) { + extraCode.push( + "", + "// script path function", + "function jsonpScriptSrc(chunkId) {", + Template.indent([ + `return ${mainTemplate.requireFn}.p + ${getScriptSrcPath( + hash, + chunk, + "chunkId" + )}` + ]), + "}" + ); + } + if (extraCode.length === 0) return source; + return Template.asString([source, ...extraCode]); + } + ); + + mainTemplate.hooks.jsonpScript.tap( + "JsonpMainTemplatePlugin", + (_, chunk, hash) => { + const crossOriginLoading = + mainTemplate.outputOptions.crossOriginLoading; + const chunkLoadTimeout = mainTemplate.outputOptions.chunkLoadTimeout; + const jsonpScriptType = mainTemplate.outputOptions.jsonpScriptType; + + return Template.asString([ + "var script = document.createElement('script');", + "var onScriptComplete;", + jsonpScriptType + ? `script.type = ${JSON.stringify(jsonpScriptType)};` + : "", + "script.charset = 'utf-8';", + `script.timeout = ${chunkLoadTimeout / 1000};`, + `if (${mainTemplate.requireFn}.nc) {`, + Template.indent( + `script.setAttribute("nonce", ${mainTemplate.requireFn}.nc);` + ), + "}", + "script.src = jsonpScriptSrc(chunkId);", + crossOriginLoading + ? Template.asString([ + "if (script.src.indexOf(window.location.origin + '/') !== 0) {", + Template.indent( + `script.crossOrigin = ${JSON.stringify(crossOriginLoading)};` + ), + "}" + ]) + : "", + "// create error before stack unwound to get useful stacktrace later", + "var error = new Error();", + "onScriptComplete = function (event) {", + Template.indent([ + "// avoid mem leaks in IE.", + "script.onerror = script.onload = null;", + "clearTimeout(timeout);", + "var chunk = installedChunks[chunkId];", + "if(chunk !== 0) {", + Template.indent([ + "if(chunk) {", + Template.indent([ + "var errorType = event && (event.type === 'load' ? 'missing' : event.type);", + "var realSrc = event && event.target && event.target.src;", + "error.message = 'Loading chunk ' + chunkId + ' failed.\\n(' + errorType + ': ' + realSrc + ')';", + "error.name = 'ChunkLoadError';", + "error.type = errorType;", + "error.request = realSrc;", + "chunk[1](error);" + ]), + "}", + "installedChunks[chunkId] = undefined;" + ]), + "}" + ]), + "};", + "var timeout = setTimeout(function(){", + Template.indent([ + "onScriptComplete({ type: 'timeout', target: script });" + ]), + `}, ${chunkLoadTimeout});`, + "script.onerror = script.onload = onScriptComplete;" + ]); + } + ); + mainTemplate.hooks.linkPreload.tap( + "JsonpMainTemplatePlugin", + (_, chunk, hash) => { + const crossOriginLoading = + mainTemplate.outputOptions.crossOriginLoading; + const jsonpScriptType = mainTemplate.outputOptions.jsonpScriptType; + + return Template.asString([ + "var link = document.createElement('link');", + jsonpScriptType + ? `link.type = ${JSON.stringify(jsonpScriptType)};` + : "", + "link.charset = 'utf-8';", + `if (${mainTemplate.requireFn}.nc) {`, + Template.indent( + `link.setAttribute("nonce", ${mainTemplate.requireFn}.nc);` + ), + "}", + 'link.rel = "preload";', + 'link.as = "script";', + "link.href = jsonpScriptSrc(chunkId);", + crossOriginLoading + ? Template.asString([ + "if (link.href.indexOf(window.location.origin + '/') !== 0) {", + Template.indent( + `link.crossOrigin = ${JSON.stringify(crossOriginLoading)};` + ), + "}" + ]) + : "" + ]); + } + ); + mainTemplate.hooks.linkPrefetch.tap( + "JsonpMainTemplatePlugin", + (_, chunk, hash) => { + const crossOriginLoading = + mainTemplate.outputOptions.crossOriginLoading; + + return Template.asString([ + "var link = document.createElement('link');", + crossOriginLoading + ? `link.crossOrigin = ${JSON.stringify(crossOriginLoading)};` + : "", + `if (${mainTemplate.requireFn}.nc) {`, + Template.indent( + `link.setAttribute("nonce", ${mainTemplate.requireFn}.nc);` + ), + "}", + 'link.rel = "prefetch";', + 'link.as = "script";', + "link.href = jsonpScriptSrc(chunkId);" + ]); + } + ); + mainTemplate.hooks.requireEnsure.tap( + "JsonpMainTemplatePlugin load", + (source, chunk, hash) => { + return Template.asString([ + source, + "", + "// JSONP chunk loading for javascript", + "", + "var installedChunkData = installedChunks[chunkId];", + 'if(installedChunkData !== 0) { // 0 means "already installed".', + Template.indent([ + "", + '// a Promise means "currently loading".', + "if(installedChunkData) {", + Template.indent(["promises.push(installedChunkData[2]);"]), + "} else {", + Template.indent([ + "// setup Promise in chunk cache", + "var promise = new Promise(function(resolve, reject) {", + Template.indent([ + "installedChunkData = installedChunks[chunkId] = [resolve, reject];" + ]), + "});", + "promises.push(installedChunkData[2] = promise);", + "", + "// start chunk loading", + mainTemplate.hooks.jsonpScript.call("", chunk, hash), + "document.head.appendChild(script);" + ]), + "}" + ]), + "}" + ]); + } + ); + mainTemplate.hooks.requireEnsure.tap( + { + name: "JsonpMainTemplatePlugin preload", + stage: 10 + }, + (source, chunk, hash) => { + const chunkMap = chunk.getChildIdsByOrdersMap().preload; + if (!chunkMap || Object.keys(chunkMap).length === 0) return source; + return Template.asString([ + source, + "", + "// chunk preloadng for javascript", + "", + `var chunkPreloadMap = ${JSON.stringify(chunkMap, null, "\t")};`, + "", + "var chunkPreloadData = chunkPreloadMap[chunkId];", + "if(chunkPreloadData) {", + Template.indent([ + "chunkPreloadData.forEach(function(chunkId) {", + Template.indent([ + "if(installedChunks[chunkId] === undefined) {", + Template.indent([ + "installedChunks[chunkId] = null;", + mainTemplate.hooks.linkPreload.call("", chunk, hash), + "document.head.appendChild(link);" + ]), + "}" + ]), + "});" + ]), + "}" + ]); + } + ); + mainTemplate.hooks.requireExtensions.tap( + "JsonpMainTemplatePlugin", + (source, chunk) => { + if (!needChunkOnDemandLoadingCode(chunk)) return source; + + return Template.asString([ + source, + "", + "// on error function for async loading", + `${mainTemplate.requireFn}.oe = function(err) { console.error(err); throw err; };` + ]); + } + ); + mainTemplate.hooks.bootstrap.tap( + "JsonpMainTemplatePlugin", + (source, chunk, hash) => { + if (needChunkLoadingCode(chunk)) { + const withDefer = needEntryDeferringCode(chunk); + const withPrefetch = needPrefetchingCode(chunk); + return Template.asString([ + source, + "", + "// install a JSONP callback for chunk loading", + "function webpackJsonpCallback(data) {", + Template.indent([ + "var chunkIds = data[0];", + "var moreModules = data[1];", + withDefer ? "var executeModules = data[2];" : "", + withPrefetch ? "var prefetchChunks = data[3] || [];" : "", + '// add "moreModules" to the modules object,', + '// then flag all "chunkIds" as loaded and fire callback', + "var moduleId, chunkId, i = 0, resolves = [];", + "for(;i < chunkIds.length; i++) {", + Template.indent([ + "chunkId = chunkIds[i];", + "if(Object.prototype.hasOwnProperty.call(installedChunks, chunkId) && installedChunks[chunkId]) {", + Template.indent("resolves.push(installedChunks[chunkId][0]);"), + "}", + "installedChunks[chunkId] = 0;" + ]), + "}", + "for(moduleId in moreModules) {", + Template.indent([ + "if(Object.prototype.hasOwnProperty.call(moreModules, moduleId)) {", + Template.indent( + mainTemplate.renderAddModule( + hash, + chunk, + "moduleId", + "moreModules[moduleId]" + ) + ), + "}" + ]), + "}", + "if(parentJsonpFunction) parentJsonpFunction(data);", + withPrefetch + ? withDefer + ? "deferredPrefetch.push.apply(deferredPrefetch, prefetchChunks);" + : Template.asString([ + "// chunk prefetching for javascript", + "prefetchChunks.forEach(function(chunkId) {", + Template.indent([ + "if(installedChunks[chunkId] === undefined) {", + Template.indent([ + "installedChunks[chunkId] = null;", + mainTemplate.hooks.linkPrefetch.call("", chunk, hash), + "document.head.appendChild(link);" + ]), + "}" + ]), + "});" + ]) + : "", + "while(resolves.length) {", + Template.indent("resolves.shift()();"), + "}", + withDefer + ? Template.asString([ + "", + "// add entry modules from loaded chunk to deferred list", + "deferredModules.push.apply(deferredModules, executeModules || []);", + "", + "// run deferred modules when all chunks ready", + "return checkDeferredModules();" + ]) + : "" + ]), + "};", + withDefer + ? Template.asString([ + "function checkDeferredModules() {", + Template.indent([ + "var result;", + "for(var i = 0; i < deferredModules.length; i++) {", + Template.indent([ + "var deferredModule = deferredModules[i];", + "var fulfilled = true;", + "for(var j = 1; j < deferredModule.length; j++) {", + Template.indent([ + "var depId = deferredModule[j];", + "if(installedChunks[depId] !== 0) fulfilled = false;" + ]), + "}", + "if(fulfilled) {", + Template.indent([ + "deferredModules.splice(i--, 1);", + "result = " + + mainTemplate.requireFn + + "(" + + mainTemplate.requireFn + + ".s = deferredModule[0]);" + ]), + "}" + ]), + "}", + withPrefetch + ? Template.asString([ + "if(deferredModules.length === 0) {", + Template.indent([ + "// chunk prefetching for javascript", + "deferredPrefetch.forEach(function(chunkId) {", + Template.indent([ + "if(installedChunks[chunkId] === undefined) {", + Template.indent([ + "installedChunks[chunkId] = null;", + mainTemplate.hooks.linkPrefetch.call( + "", + chunk, + hash + ), + "document.head.appendChild(link);" + ]), + "}" + ]), + "});", + "deferredPrefetch.length = 0;" + ]), + "}" + ]) + : "", + "return result;" + ]), + "}" + ]) + : "" + ]); + } + return source; + } + ); + mainTemplate.hooks.beforeStartup.tap( + "JsonpMainTemplatePlugin", + (source, chunk, hash) => { + if (needChunkLoadingCode(chunk)) { + var jsonpFunction = mainTemplate.outputOptions.jsonpFunction; + var globalObject = mainTemplate.outputOptions.globalObject; + return Template.asString([ + `var jsonpArray = ${globalObject}[${JSON.stringify( + jsonpFunction + )}] = ${globalObject}[${JSON.stringify(jsonpFunction)}] || [];`, + "var oldJsonpFunction = jsonpArray.push.bind(jsonpArray);", + "jsonpArray.push = webpackJsonpCallback;", + "jsonpArray = jsonpArray.slice();", + "for(var i = 0; i < jsonpArray.length; i++) webpackJsonpCallback(jsonpArray[i]);", + "var parentJsonpFunction = oldJsonpFunction;", + "", + source + ]); + } + return source; + } + ); + mainTemplate.hooks.afterStartup.tap( + "JsonpMainTemplatePlugin", + (source, chunk, hash) => { + const prefetchChunks = chunk.getChildIdsByOrders().prefetch; + if ( + needChunkLoadingCode(chunk) && + prefetchChunks && + prefetchChunks.length + ) { + return Template.asString([ + source, + `webpackJsonpCallback([[], {}, 0, ${JSON.stringify( + prefetchChunks + )}]);` + ]); + } + return source; + } + ); + mainTemplate.hooks.startup.tap( + "JsonpMainTemplatePlugin", + (source, chunk, hash) => { + if (needEntryDeferringCode(chunk)) { + if (chunk.hasEntryModule()) { + const entries = [chunk.entryModule].filter(Boolean).map(m => + [m.id].concat( + Array.from(chunk.groupsIterable)[0] + .chunks.filter(c => c !== chunk) + .map(c => c.id) + ) + ); + return Template.asString([ + "// add entry module to deferred list", + `deferredModules.push(${entries + .map(e => JSON.stringify(e)) + .join(", ")});`, + "// run deferred modules when ready", + "return checkDeferredModules();" + ]); + } else { + return Template.asString([ + "// run deferred modules from other chunks", + "checkDeferredModules();" + ]); + } + } + return source; + } + ); + mainTemplate.hooks.hotBootstrap.tap( + "JsonpMainTemplatePlugin", + (source, chunk, hash) => { + const globalObject = mainTemplate.outputOptions.globalObject; + const hotUpdateChunkFilename = + mainTemplate.outputOptions.hotUpdateChunkFilename; + const hotUpdateMainFilename = + mainTemplate.outputOptions.hotUpdateMainFilename; + const crossOriginLoading = + mainTemplate.outputOptions.crossOriginLoading; + const hotUpdateFunction = mainTemplate.outputOptions.hotUpdateFunction; + const currentHotUpdateChunkFilename = mainTemplate.getAssetPath( + JSON.stringify(hotUpdateChunkFilename), + { + hash: `" + ${mainTemplate.renderCurrentHashCode(hash)} + "`, + hashWithLength: length => + `" + ${mainTemplate.renderCurrentHashCode(hash, length)} + "`, + chunk: { + id: '" + chunkId + "' + } + } + ); + const currentHotUpdateMainFilename = mainTemplate.getAssetPath( + JSON.stringify(hotUpdateMainFilename), + { + hash: `" + ${mainTemplate.renderCurrentHashCode(hash)} + "`, + hashWithLength: length => + `" + ${mainTemplate.renderCurrentHashCode(hash, length)} + "` + } + ); + const runtimeSource = Template.getFunctionContent( + require("./JsonpMainTemplate.runtime") + ) + .replace(/\/\/\$semicolon/g, ";") + .replace(/\$require\$/g, mainTemplate.requireFn) + .replace( + /\$crossOriginLoading\$/g, + crossOriginLoading ? JSON.stringify(crossOriginLoading) : "null" + ) + .replace(/\$hotMainFilename\$/g, currentHotUpdateMainFilename) + .replace(/\$hotChunkFilename\$/g, currentHotUpdateChunkFilename) + .replace(/\$hash\$/g, JSON.stringify(hash)); + return `${source} +function hotDisposeChunk(chunkId) { + delete installedChunks[chunkId]; +} +var parentHotUpdateCallback = ${globalObject}[${JSON.stringify( + hotUpdateFunction + )}]; +${globalObject}[${JSON.stringify(hotUpdateFunction)}] = ${runtimeSource}`; + } + ); + mainTemplate.hooks.hash.tap("JsonpMainTemplatePlugin", hash => { + hash.update("jsonp"); + hash.update("6"); + }); + } +} +module.exports = JsonpMainTemplatePlugin; -- cgit v1.2.3