line_push/node_modules/webpack-external-import/webpack/index.js
2022-07-17 13:16:16 +08:00

525 lines
22 KiB
JavaScript

"use strict";
function _slicedToArray(arr, i) { return _arrayWithHoles(arr) || _iterableToArrayLimit(arr, i) || _nonIterableRest(); }
function _nonIterableRest() { throw new TypeError("Invalid attempt to destructure non-iterable instance"); }
function _iterableToArrayLimit(arr, i) { if (!(Symbol.iterator in Object(arr) || Object.prototype.toString.call(arr) === "[object Arguments]")) { return; } 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"] != null) _i["return"](); } finally { if (_d) throw _e; } } return _arr; }
function _arrayWithHoles(arr) { if (Array.isArray(arr)) return arr; }
function ownKeys(object, enumerableOnly) { var keys = Object.keys(object); if (Object.getOwnPropertySymbols) { var symbols = Object.getOwnPropertySymbols(object); if (enumerableOnly) symbols = symbols.filter(function (sym) { return Object.getOwnPropertyDescriptor(object, sym).enumerable; }); keys.push.apply(keys, symbols); } return keys; }
function _objectSpread(target) { for (var i = 1; i < arguments.length; i++) { var source = arguments[i] != null ? arguments[i] : {}; if (i % 2) { ownKeys(Object(source), true).forEach(function (key) { _defineProperty(target, key, source[key]); }); } else if (Object.getOwnPropertyDescriptors) { Object.defineProperties(target, Object.getOwnPropertyDescriptors(source)); } else { ownKeys(Object(source)).forEach(function (key) { Object.defineProperty(target, key, Object.getOwnPropertyDescriptor(source, key)); }); } } return target; }
function _defineProperty(obj, key, value) { if (key in obj) { Object.defineProperty(obj, key, { value: value, enumerable: true, configurable: true, writable: true }); } else { obj[key] = value; } return obj; }
function _typeof(obj) { "@babel/helpers - typeof"; if (typeof Symbol === "function" && typeof Symbol.iterator === "symbol") { _typeof = function _typeof(obj) { return typeof obj; }; } else { _typeof = function _typeof(obj) { return obj && typeof Symbol === "function" && obj.constructor === Symbol && obj !== Symbol.prototype ? "symbol" : typeof obj; }; } return _typeof(obj); }
function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }
function _defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } }
function _createClass(Constructor, protoProps, staticProps) { if (protoProps) _defineProperties(Constructor.prototype, protoProps); if (staticProps) _defineProperties(Constructor, staticProps); return Constructor; }
var path = require("path");
var fse = require("fs-extra");
var createHash = require("webpack/lib/util/createHash");
var fs = require("fs");
var ExternalModuleFactoryPlugin = require("./ExternalModuleFactory"); // const FunctionModuleTemplatePlugin = require("webpack/lib/FunctionModuleTemplatePlugin");
var _require = require("./utils"),
mergeDeep = _require.mergeDeep;
var _require2 = require("./requireExtentions"),
addInterleaveExtension = _require2.addInterleaveExtension,
addInterleaveRequire = _require2.addInterleaveRequire;
var _require3 = require("./beforeStartup"),
addWebpackRegister = _require3.addWebpackRegister;
var _require4 = require("./chunkSplitting"),
interleaveStyleConfig = _require4.interleaveStyleConfig,
interleaveStyleJsConfig = _require4.interleaveStyleJsConfig,
interleaveConfig = _require4.interleaveConfig,
hasExternalizedModuleViaJson = _require4.hasExternalizedModuleViaJson;
var _require5 = require("./localVars"),
addLocalVars = _require5.addLocalVars;
var _require6 = require("./optimizeChunk"),
wrapChunks = _require6.wrapChunks;
var emitCountMap = new Map();
function getFileType(str) {
var split = str.replace(/\?.*/, "").split(".");
return split.pop();
}
var URLImportPlugin =
/*#__PURE__*/
function () {
function URLImportPlugin(opts) {
_classCallCheck(this, URLImportPlugin);
var debug = (typeof v8debug === "undefined" ? "undefined" : _typeof(v8debug)) === "object" || /--debug|--inspect/.test(process.execArgv.join(" "));
if (!opts.manifestName) {
throw new Error("URLImportPlugin: You MUST specify a manifestName in your options. Something unique. Like {manifestName: my-special-build}");
}
this.opts = _objectSpread({
publicPath: null,
debug: debug || false,
testPath: "src",
basePath: "",
manifestName: "unknown-project",
fileName: "importManifest.js",
writeToFileEmit: false,
seed: null,
filter: null,
hashDigest: "base64",
hashDigestLength: 5,
context: null,
hashFunction: "md4"
}, opts || {});
}
_createClass(URLImportPlugin, [{
key: "apply",
value: function apply(compiler) {
var _options$optimization,
_options$optimization2,
_this = this,
_options$optimization3;
if (this.opts.debug) {}
var options = compiler === null || compiler === void 0 ? void 0 : compiler.options;
if (options.externals) {
throw new Error("URLImportPlugin: Externals must be applied via the plugin, not via webpack config object. Please see useExternals on the plugin documentation");
} // add to the existing webpack config
// adding a new splitChunks cache group called interleave
var chunkSplitting = (options === null || options === void 0 ? void 0 : (_options$optimization = options.optimization) === null || _options$optimization === void 0 ? void 0 : (_options$optimization2 = _options$optimization.splitChunks) === null || _options$optimization2 === void 0 ? void 0 : _options$optimization2.cacheGroups) || {};
chunkSplitting.stylejs = interleaveStyleJsConfig(this.opts);
chunkSplitting.style = interleaveStyleConfig(this.opts); // interleaveConfig figures out if a file meets the paramaters for interleaving
chunkSplitting.interleave = interleaveConfig(this.opts);
if (options.mode === "production") {
chunkSplitting.vendors = {
name: "".concat(this.opts.manifestName, "-vendors"),
test: /node_modules/,
priority: -10,
enforce: true,
maxSize: 50000
};
Object.assign(chunkSplitting["default"], {
maxSize: 50000
});
}
Object.assign(options.optimization || {}, {
namedChunks: true,
// dont rename exports when hoisting and tree shaking
providedExports: false
}); // likely will be refactored or removed, used for entryManifest.js to map chunks (this is V1 where its outside the runtime still)
if (this.opts.debug) {} // merge my added splitChunks config into the webpack config object passed in
Object.assign(options.optimization.splitChunks, {
chunks: "all"
});
mergeDeep(options, {
optimization: {
splitChunks: {
chunks: "all",
cacheGroups: chunkSplitting
}
}
});
Object.keys(chunkSplitting).forEach(function (key) {
var _chunkSplitting$key;
if (key === "interleave") {
return;
}
chunkSplitting[key].automaticNamePrefix = "".concat(_this.opts.manifestName, "~").concat((chunkSplitting === null || chunkSplitting === void 0 ? void 0 : (_chunkSplitting$key = chunkSplitting[key]) === null || _chunkSplitting$key === void 0 ? void 0 : _chunkSplitting$key.automaticNamePrefix) || "");
});
Object.assign(options.optimization, {
// node debugger breaks with TerserPlugin
minimizer: this.opts.debug ? [] : options.optimization.minimizer,
splitChunks: ((_options$optimization3 = options.optimization) === null || _options$optimization3 === void 0 ? void 0 : _options$optimization3.splitChunks) || {}
}); // forcefully mutate it
Object.assign(options.optimization.splitChunks, {
chunks: "all",
cacheGroups: chunkSplitting
});
if (this.opts.debug) {} // eslint-disable-next-line no-unused-vars
compiler.hooks.thisCompilation.tap("URLImportPlugin", function (compilation) {// TODO: throw warning when changing module ID type
// if (options.ignoreOrder) {
// compilation.warnings.push(
// new Error(
// `chunk ${chunk.name || chunk.id} [${pluginName}]\n`
// + 'Conflicting order between:\n'
// + ` * ${fallbackModule.readableIdentifier(
// requestShortener,
// )}\n`
// + `${bestMatchDeps
// .map(m => ` * ${m.readableIdentifier(requestShortener)}`)
// .join('\n')}`,
// ),
// );
// }
});
var moduleAssets = {};
var outputFolder = compiler.options.output.path;
var outputFile = path.resolve(outputFolder, this.opts.fileName);
var outputName = path.relative(outputFolder, outputFile);
var moduleAsset = function moduleAsset(_ref, file) {
var userRequest = _ref.userRequest;
if (userRequest) {
moduleAssets[file] = path.join(path.dirname(file), path.basename(userRequest));
}
};
var emit = function emit(compilation, compileCallback) {
var emitCount = emitCountMap.get(outputFile) - 1;
emitCountMap.set(outputFile, emitCount);
var seed = _this.opts.seed || {};
var publicPath = _this.opts.publicPath != null ? _this.opts.publicPath : compilation.options.output.publicPath;
var stats = compilation.getStats().toJson();
if (_this.opts.debug) {}
var files = compilation.chunks.reduce(function (f, chunk) {
return chunk.files.reduce(function (fx, filePath) {
var name = chunk.id ? chunk.id : null;
if (name) {
name = "".concat(name, ".").concat(getFileType(filePath));
} else {
// For nameless chunks, just map the files directly.
name = filePath;
}
return fx.concat({
path: filePath,
chunk: chunk,
name: name,
isChunk: true,
isAsset: false,
isModuleAsset: false
});
}, f);
}, []); // module assets don't show up in assetsByChunkName.
// we're getting them this way;
files = stats.assets.reduce(function (fx, asset) {
var name = moduleAssets[asset.name];
if (name) {
return fx.concat({
path: asset.name,
name: name
});
}
var isEntryAsset = asset.chunks.length > 0;
if (isEntryAsset) {
return fx;
}
return fx.concat({
path: asset.name,
name: asset.name
});
}, files);
files = files.filter(function (file) {
// Don't add hot updates to manifest
var isUpdateChunk = file.path.includes("hot-update"); // Don't add manifest from another instance
var isManifest = emitCountMap.get(path.join(outputFolder, file.name)) !== undefined;
return !isUpdateChunk && !isManifest;
});
if (_this.opts.debug) {} // Append optional basepath onto all references.
// This allows output path to be reflected in the manifest.
if (_this.opts.basePath) {
files = files.map(function (file) {
return _objectSpread({}, file, {
name: _this.opts.basePath + file.name
});
});
}
if (publicPath) {
// Similar to basePath but only affects the value (similar to how
// output.publicPath turns require('foo/bar') into '/public/foo/bar', see
// https://github.com/webpack/docs/wiki/configuration#outputpublicpath
files = files.map(function (file) {
return _objectSpread({}, file, {
path: publicPath + file.path
});
});
}
files = files.map(function (file) {
return _objectSpread({}, file, {
name: file.name.replace(/\\/g, "/"),
path: file.path.replace(/\\/g, "/")
});
});
if (_this.opts.filter) {
files = files.filter(_this.opts.filter);
}
if (_this.opts.debug) {}
var manifest = files.reduce(function (m, file) {
return _objectSpread({}, m, _defineProperty({}, file.name, {
path: file.path
}));
}, seed);
if (_this.opts.debug) {}
var isLastEmit = emitCount === 0;
if (isLastEmit) {
var cleanedManifest = Object.entries(manifest).reduce(function (acc, _ref2) {
var _asset$path;
var _ref3 = _slicedToArray(_ref2, 2),
key = _ref3[0],
asset = _ref3[1];
if (!(asset === null || asset === void 0 ? void 0 : (_asset$path = asset.path) === null || _asset$path === void 0 ? void 0 : _asset$path.includes(".map"))) {
return Object.assign(acc, _defineProperty({}, key, asset));
}
return acc;
}, {});
var serialize = function serialize(manifest) {
return "if(!window.entryManifest) {window.entryManifest = {}}; window.entryManifest[\"".concat(_this.opts.manifestName, "\"] = ").concat(JSON.stringify(manifest));
};
var output = serialize(cleanedManifest);
if (_this.opts.debug) {} // eslint-disable-next-line no-param-reassign
compilation.assets[outputName] = {
source: function source() {
return output;
},
size: function size() {
return output.length;
}
};
if (_this.opts.writeToFileEmit) {
fse.outputFileSync(outputFile, output);
}
}
if (compiler.hooks) {
compiler.hooks.webpackURLImportPluginAfterEmit.call(manifest);
} else {
compilation.applyPluginsAsync("webpack-manifest-plugin-after-emit", manifest, compileCallback);
}
};
function beforeRun(comp, callback) {
var emitCount = emitCountMap.get(outputFile) || 0;
emitCountMap.set(outputFile, emitCount + 1);
if (callback) {
callback();
}
}
if (compiler.hooks) {
var _require7 = require("tapable"),
SyncWaterfallHook = _require7.SyncWaterfallHook;
var pluginOptions = {
name: "URLImportPlugin",
stage: Infinity
}; // eslint-disable-next-line no-param-reassign
compiler.hooks.webpackURLImportPluginAfterEmit = new SyncWaterfallHook(["manifest"]);
compiler.hooks.compile.tap("ExternalsPlugin", function (_ref4) {
var normalModuleFactory = _ref4.normalModuleFactory;
new ExternalModuleFactoryPlugin(options.output.libraryTarget, _this.opts.useExternals).apply(normalModuleFactory);
});
compiler.hooks.compilation.tap("URLImportPlugin", function (compilation) {
var mainTemplate = compilation.mainTemplate; // Add another webpack__require method to the webpack runtime
// this new method will allow a interleaved component to be required and automatically download its dependencies
// it returns a promise so the actual interleaved module is not executed until any missing dependencies are loaded
mainTemplate.hooks.requireExtensions.tap("URLImportPlugin", function (source) {
return [addInterleaveExtension, addInterleaveRequire].reduce(function (sourceCode, extension) {
return extension(sourceCode, mainTemplate.requireFn, _this.opts);
}, source);
}); // TODO add an option for this
if (_this.afterOptimizations) {
// before chunk files are optimized
compilation.hooks.beforeOptimizeChunkAssets.tap("URLImportPlugin", function (chunks) {
// access all chunks webpack created, then add some code to each chunk file, which is run when a chunk is
// loaded on a page as <script>
wrapChunks(compilation, chunks);
});
} else {
// adfter chunk files are optimized
compilation.hooks.optimizeChunkAssets.tapAsync("URLImportPlugin", function (chunks, done) {
wrapChunks(compilation, chunks);
done();
});
} // Expose chunk registration functions and bindings from webpack runtime to the window
// webpack does this and its how code splitting works. It exposes window.webpackJsonP
// This registration system works just like webpacks, it exposes a function that allows information to be passed
// into webpack runtime, because the function is in webpack runtime, i have access to all of webpacks internals
mainTemplate.hooks.beforeStartup.tap("URLImportPlugin", function (source) {
return addWebpackRegister(source, options.output.jsonpFunction);
}); // add variables to webpack runtime which are available throughout all functions and closures within the runtime
// localVars are like global variables for webpack, anything can access them.
mainTemplate.hooks.localVars.tap("URLImportPlugin", addLocalVars);
});
compiler.hooks.compilation.tap("URLImportPlugin", function (compilation) {
var usedIds = new Set(); // creates hashed module IDs based on the contents of the file - works like [contenthash] but for each module
compilation.hooks.beforeModuleIds.tap("URLImportPlugin", function (modules) {
var _this$opts;
var provideExternals = Object.keys(((_this$opts = _this.opts) === null || _this$opts === void 0 ? void 0 : _this$opts.provideExternals) || {}); // eslint-disable-next-line no-restricted-syntax
var _iteratorNormalCompletion = true;
var _didIteratorError = false;
var _iteratorError = undefined;
try {
for (var _iterator = modules[Symbol.iterator](), _step; !(_iteratorNormalCompletion = (_step = _iterator.next()).done); _iteratorNormalCompletion = true) {
var _module = _step.value;
if (provideExternals.includes(_module.rawRequest)) {
_module.id = _module.rawRequest;
}
if (_module.id === null && _module.resource) {
var hash = createHash(_this.opts.hashFunction);
var resourcePath = _module.resource;
if (resourcePath.indexOf("?") > -1) {
var _resourcePath$split = resourcePath.split("?");
var _resourcePath$split2 = _slicedToArray(_resourcePath$split, 1);
resourcePath = _resourcePath$split2[0];
}
try {
var exports = "";
if (Array.isArray(_module.usedExports)) {
exports = _module.usedExports.join(".");
}
hash.update(fs.readFileSync(resourcePath) + exports);
} catch (ex) {
throw ex;
}
var hashId = hash.digest(_this.opts.hashDigest);
var len = _this.opts.hashDigestLength;
while (usedIds.has(hashId.substr(0, len))) {
len++;
}
_module.id = hashId.substr(0, len);
usedIds.add(_module.id);
} else if (_this.opts.debug) {// console.log("Module with no ID", module);
}
var externalModule = hasExternalizedModuleViaJson(_module.resource);
if (externalModule || false) {
var _module$buildMeta;
// add exports back to usedExports, prevents tree shaking on module
Object.assign(_module, {
usedExports: (_module === null || _module === void 0 ? void 0 : (_module$buildMeta = _module.buildMeta) === null || _module$buildMeta === void 0 ? void 0 : _module$buildMeta.providedExports) || true
});
if (externalModule) {
_module.id = externalModule;
}
}
}
} catch (err) {
_didIteratorError = true;
_iteratorError = err;
} finally {
try {
if (!_iteratorNormalCompletion && _iterator["return"] != null) {
_iterator["return"]();
}
} finally {
if (_didIteratorError) {
throw _iteratorError;
}
}
}
});
});
compiler.hooks.compilation.tap(pluginOptions, function (_ref5) {
var hooks = _ref5.hooks;
// TODO: remove in ^2.2
hooks.moduleAsset.tap(pluginOptions, moduleAsset);
}); // writes the importManifest file containing a map of Chunk IDs to the cache busted JS files
compiler.hooks.emit.tap(pluginOptions, emit);
compiler.hooks.run.tap(pluginOptions, beforeRun);
compiler.hooks.watchRun.tap(pluginOptions, beforeRun);
} else {
compiler.plugin("compilation", function (compilation) {
compilation.plugin("module-asset", moduleAsset);
});
compiler.plugin("emit", emit);
compiler.plugin("before-run", beforeRun);
compiler.plugin("watch-run", beforeRun);
}
}
}]);
return URLImportPlugin;
}();
module.exports = URLImportPlugin;