123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369 |
- /*
- MIT License http://www.opensource.org/licenses/mit-license.php
- Author Tobias Koppers @sokra
- */
- "use strict";
- const { ConcatSource, OriginalSource } = require("webpack-sources");
- const ExternalModule = require("../ExternalModule");
- const Template = require("../Template");
- const AbstractLibraryPlugin = require("./AbstractLibraryPlugin");
- /** @typedef {import("webpack-sources").Source} Source */
- /** @typedef {import("../../declarations/WebpackOptions").LibraryCustomUmdCommentObject} LibraryCustomUmdCommentObject */
- /** @typedef {import("../../declarations/WebpackOptions").LibraryCustomUmdObject} LibraryCustomUmdObject */
- /** @typedef {import("../../declarations/WebpackOptions").LibraryName} LibraryName */
- /** @typedef {import("../../declarations/WebpackOptions").LibraryOptions} LibraryOptions */
- /** @typedef {import("../../declarations/WebpackOptions").LibraryType} LibraryType */
- /** @typedef {import("../Compiler")} Compiler */
- /** @typedef {import("../javascript/JavascriptModulesPlugin").RenderContext} RenderContext */
- /** @typedef {import("../ExternalModule").RequestRecord} RequestRecord */
- /** @typedef {import("../util/Hash")} Hash */
- /**
- * @template T
- * @typedef {import("./AbstractLibraryPlugin").LibraryContext<T>}
- * LibraryContext<T>
- */
- /**
- * @param {string[]} accessor the accessor to convert to path
- * @returns {string} the path
- */
- const accessorToObjectAccess = accessor => {
- return accessor.map(a => `[${JSON.stringify(a)}]`).join("");
- };
- /**
- * @param {string|undefined} base the path prefix
- * @param {string|string[]} accessor the accessor
- * @param {string=} joinWith the element separator
- * @returns {string} the path
- */
- const accessorAccess = (base, accessor, joinWith = ", ") => {
- const accessors = Array.isArray(accessor) ? accessor : [accessor];
- return accessors
- .map((_, idx) => {
- const a = base
- ? base + accessorToObjectAccess(accessors.slice(0, idx + 1))
- : accessors[0] + accessorToObjectAccess(accessors.slice(1, idx + 1));
- if (idx === accessors.length - 1) return a;
- if (idx === 0 && base === undefined)
- return `${a} = typeof ${a} === "object" ? ${a} : {}`;
- return `${a} = ${a} || {}`;
- })
- .join(joinWith);
- };
- /** @typedef {string | string[] | LibraryCustomUmdObject} UmdLibraryPluginName */
- /**
- * @typedef {object} UmdLibraryPluginOptions
- * @property {LibraryType} type
- * @property {boolean=} optionalAmdExternalAsGlobal
- */
- /**
- * @typedef {object} UmdLibraryPluginParsed
- * @property {string | string[]} name
- * @property {LibraryCustomUmdObject} names
- * @property {string | LibraryCustomUmdCommentObject} auxiliaryComment
- * @property {boolean} namedDefine
- */
- /**
- * @typedef {UmdLibraryPluginParsed} T
- * @extends {AbstractLibraryPlugin<UmdLibraryPluginParsed>}
- */
- class UmdLibraryPlugin extends AbstractLibraryPlugin {
- /**
- * @param {UmdLibraryPluginOptions} options the plugin option
- */
- constructor(options) {
- super({
- pluginName: "UmdLibraryPlugin",
- type: options.type
- });
- this.optionalAmdExternalAsGlobal = options.optionalAmdExternalAsGlobal;
- }
- /**
- * @param {LibraryOptions} library normalized library option
- * @returns {T | false} preprocess as needed by overriding
- */
- parseOptions(library) {
- /** @type {LibraryName} */
- let name;
- /** @type {LibraryCustomUmdObject} */
- let names;
- if (typeof library.name === "object" && !Array.isArray(library.name)) {
- name = library.name.root || library.name.amd || library.name.commonjs;
- names = library.name;
- } else {
- name = library.name;
- const singleName = Array.isArray(name) ? name[0] : name;
- names = {
- commonjs: singleName,
- root: library.name,
- amd: singleName
- };
- }
- return {
- name,
- names,
- auxiliaryComment: library.auxiliaryComment,
- namedDefine: library.umdNamedDefine
- };
- }
- /**
- * @param {Source} source source
- * @param {RenderContext} renderContext render context
- * @param {LibraryContext<T>} libraryContext context
- * @returns {Source} source with library export
- */
- render(
- source,
- { chunkGraph, runtimeTemplate, chunk, moduleGraph },
- { options, compilation }
- ) {
- const modules = chunkGraph
- .getChunkModules(chunk)
- .filter(
- m =>
- m instanceof ExternalModule &&
- (m.externalType === "umd" || m.externalType === "umd2")
- );
- let externals = /** @type {ExternalModule[]} */ (modules);
- /** @type {ExternalModule[]} */
- const optionalExternals = [];
- /** @type {ExternalModule[]} */
- let requiredExternals = [];
- if (this.optionalAmdExternalAsGlobal) {
- for (const m of externals) {
- if (m.isOptional(moduleGraph)) {
- optionalExternals.push(m);
- } else {
- requiredExternals.push(m);
- }
- }
- externals = requiredExternals.concat(optionalExternals);
- } else {
- requiredExternals = externals;
- }
- /**
- * @param {string} str the string to replace
- * @returns {string} the replaced keys
- */
- const replaceKeys = str => {
- return compilation.getPath(str, {
- chunk
- });
- };
- /**
- * @param {ExternalModule[]} modules external modules
- * @returns {string} result
- */
- const externalsDepsArray = modules => {
- return `[${replaceKeys(
- modules
- .map(m =>
- JSON.stringify(
- typeof m.request === "object"
- ? /** @type {RequestRecord} */
- (m.request).amd
- : m.request
- )
- )
- .join(", ")
- )}]`;
- };
- /**
- * @param {ExternalModule[]} modules external modules
- * @returns {string} result
- */
- const externalsRootArray = modules => {
- return replaceKeys(
- modules
- .map(m => {
- let request = m.request;
- if (typeof request === "object")
- request =
- /** @type {RequestRecord} */
- (request).root;
- return `root${accessorToObjectAccess([].concat(request))}`;
- })
- .join(", ")
- );
- };
- /**
- * @param {string} type the type
- * @returns {string} external require array
- */
- const externalsRequireArray = type => {
- return replaceKeys(
- externals
- .map(m => {
- let expr;
- let request = m.request;
- if (typeof request === "object") {
- request =
- /** @type {RequestRecord} */
- (request)[type];
- }
- if (request === undefined) {
- throw new Error(
- "Missing external configuration for type:" + type
- );
- }
- if (Array.isArray(request)) {
- expr = `require(${JSON.stringify(
- request[0]
- )})${accessorToObjectAccess(request.slice(1))}`;
- } else {
- expr = `require(${JSON.stringify(request)})`;
- }
- if (m.isOptional(moduleGraph)) {
- expr = `(function webpackLoadOptionalExternalModule() { try { return ${expr}; } catch(e) {} }())`;
- }
- return expr;
- })
- .join(", ")
- );
- };
- /**
- * @param {ExternalModule[]} modules external modules
- * @returns {string} arguments
- */
- const externalsArguments = modules => {
- return modules
- .map(
- m =>
- `__WEBPACK_EXTERNAL_MODULE_${Template.toIdentifier(
- `${chunkGraph.getModuleId(m)}`
- )}__`
- )
- .join(", ");
- };
- /**
- * @param {string| string[]} library library name
- * @returns {string} stringified library name
- */
- const libraryName = library => {
- return JSON.stringify(
- replaceKeys(/** @type {string[]} */ ([]).concat(library).pop())
- );
- };
- let amdFactory;
- if (optionalExternals.length > 0) {
- const wrapperArguments = externalsArguments(requiredExternals);
- const factoryArguments =
- requiredExternals.length > 0
- ? externalsArguments(requiredExternals) +
- ", " +
- externalsRootArray(optionalExternals)
- : externalsRootArray(optionalExternals);
- amdFactory =
- `function webpackLoadOptionalExternalModuleAmd(${wrapperArguments}) {\n` +
- ` return factory(${factoryArguments});\n` +
- " }";
- } else {
- amdFactory = "factory";
- }
- const { auxiliaryComment, namedDefine, names } = options;
- /**
- * @param {keyof LibraryCustomUmdCommentObject} type type
- * @returns {string} comment
- */
- const getAuxiliaryComment = type => {
- if (auxiliaryComment) {
- if (typeof auxiliaryComment === "string")
- return "\t//" + auxiliaryComment + "\n";
- if (auxiliaryComment[type])
- return "\t//" + auxiliaryComment[type] + "\n";
- }
- return "";
- };
- return new ConcatSource(
- new OriginalSource(
- "(function webpackUniversalModuleDefinition(root, factory) {\n" +
- getAuxiliaryComment("commonjs2") +
- " if(typeof exports === 'object' && typeof module === 'object')\n" +
- " module.exports = factory(" +
- externalsRequireArray("commonjs2") +
- ");\n" +
- getAuxiliaryComment("amd") +
- " else if(typeof define === 'function' && define.amd)\n" +
- (requiredExternals.length > 0
- ? names.amd && namedDefine === true
- ? " define(" +
- libraryName(names.amd) +
- ", " +
- externalsDepsArray(requiredExternals) +
- ", " +
- amdFactory +
- ");\n"
- : " define(" +
- externalsDepsArray(requiredExternals) +
- ", " +
- amdFactory +
- ");\n"
- : names.amd && namedDefine === true
- ? " define(" +
- libraryName(names.amd) +
- ", [], " +
- amdFactory +
- ");\n"
- : " define([], " + amdFactory + ");\n") +
- (names.root || names.commonjs
- ? getAuxiliaryComment("commonjs") +
- " else if(typeof exports === 'object')\n" +
- " exports[" +
- libraryName(names.commonjs || names.root) +
- "] = factory(" +
- externalsRequireArray("commonjs") +
- ");\n" +
- getAuxiliaryComment("root") +
- " else\n" +
- " " +
- replaceKeys(
- accessorAccess("root", names.root || names.commonjs)
- ) +
- " = factory(" +
- externalsRootArray(externals) +
- ");\n"
- : " else {\n" +
- (externals.length > 0
- ? " var a = typeof exports === 'object' ? factory(" +
- externalsRequireArray("commonjs") +
- ") : factory(" +
- externalsRootArray(externals) +
- ");\n"
- : " var a = factory();\n") +
- " for(var i in a) (typeof exports === 'object' ? exports : root)[i] = a[i];\n" +
- " }\n") +
- `})(${runtimeTemplate.outputOptions.globalObject}, ${
- runtimeTemplate.supportsArrowFunction()
- ? `(${externalsArguments(externals)}) =>`
- : `function(${externalsArguments(externals)})`
- } {\nreturn `,
- "webpack/universalModuleDefinition"
- ),
- source,
- ";\n})"
- );
- }
- }
- module.exports = UmdLibraryPlugin;
|