EnableLibraryPlugin.js 7.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306
  1. /*
  2. MIT License http://www.opensource.org/licenses/mit-license.php
  3. Author Tobias Koppers @sokra
  4. */
  5. "use strict";
  6. /** @typedef {import("../../declarations/WebpackOptions").LibraryType} LibraryType */
  7. /** @typedef {import("../Compiler")} Compiler */
  8. /** @typedef {Set<LibraryType>} LibraryTypes */
  9. /** @type {WeakMap<Compiler, LibraryTypes>} */
  10. const enabledTypes = new WeakMap();
  11. /**
  12. * @typedef {object} EnableLibraryPluginOptions
  13. * @property {() => void=} additionalApply function that runs when applying the current plugin.
  14. */
  15. /**
  16. * @param {Compiler} compiler the compiler instance
  17. * @returns {LibraryTypes} enabled types
  18. */
  19. const getEnabledTypes = (compiler) => {
  20. let set = enabledTypes.get(compiler);
  21. if (set === undefined) {
  22. /** @type {LibraryTypes} */
  23. set = new Set();
  24. enabledTypes.set(compiler, set);
  25. }
  26. return set;
  27. };
  28. class EnableLibraryPlugin {
  29. /**
  30. * @param {LibraryType} type library type that should be available
  31. * @param {EnableLibraryPluginOptions} options options of EnableLibraryPlugin
  32. */
  33. constructor(type, options = {}) {
  34. /** @type {LibraryType} */
  35. this.type = type;
  36. /** @type {EnableLibraryPluginOptions} */
  37. this.options = options;
  38. }
  39. /**
  40. * @param {Compiler} compiler the compiler instance
  41. * @param {LibraryType} type type of library
  42. * @returns {void}
  43. */
  44. static setEnabled(compiler, type) {
  45. getEnabledTypes(compiler).add(type);
  46. }
  47. /**
  48. * @param {Compiler} compiler the compiler instance
  49. * @param {LibraryType} type type of library
  50. * @returns {void}
  51. */
  52. static checkEnabled(compiler, type) {
  53. if (!getEnabledTypes(compiler).has(type)) {
  54. throw new Error(
  55. `Library type "${type}" is not enabled. ` +
  56. "EnableLibraryPlugin need to be used to enable this type of library. " +
  57. 'This usually happens through the "output.enabledLibraryTypes" option. ' +
  58. 'If you are using a function as entry which sets "library", you need to add all potential library types to "output.enabledLibraryTypes". ' +
  59. `These types are enabled: ${[...getEnabledTypes(compiler)].join(", ")}`
  60. );
  61. }
  62. }
  63. /**
  64. * Apply the plugin
  65. * @param {Compiler} compiler the compiler instance
  66. * @returns {void}
  67. */
  68. apply(compiler) {
  69. const { type, options } = this;
  70. // Only enable once
  71. const enabled = getEnabledTypes(compiler);
  72. if (enabled.has(type)) return;
  73. enabled.add(type);
  74. if (typeof options.additionalApply === "function") {
  75. options.additionalApply();
  76. }
  77. if (typeof type === "string") {
  78. const enableExportProperty = () => {
  79. const ExportPropertyLibraryPlugin = require("./ExportPropertyLibraryPlugin");
  80. new ExportPropertyLibraryPlugin({
  81. type
  82. }).apply(compiler);
  83. };
  84. switch (type) {
  85. case "var": {
  86. // @ts-expect-error https://github.com/microsoft/TypeScript/issues/41697
  87. const AssignLibraryPlugin = require("./AssignLibraryPlugin");
  88. new AssignLibraryPlugin({
  89. type,
  90. prefix: [],
  91. declare: "var",
  92. unnamed: "error"
  93. }).apply(compiler);
  94. break;
  95. }
  96. case "assign-properties": {
  97. // @ts-expect-error https://github.com/microsoft/TypeScript/issues/41697
  98. const AssignLibraryPlugin = require("./AssignLibraryPlugin");
  99. new AssignLibraryPlugin({
  100. type,
  101. prefix: [],
  102. declare: false,
  103. unnamed: "error",
  104. named: "copy"
  105. }).apply(compiler);
  106. break;
  107. }
  108. case "assign": {
  109. // @ts-expect-error https://github.com/microsoft/TypeScript/issues/41697
  110. const AssignLibraryPlugin = require("./AssignLibraryPlugin");
  111. new AssignLibraryPlugin({
  112. type,
  113. prefix: [],
  114. declare: false,
  115. unnamed: "error"
  116. }).apply(compiler);
  117. break;
  118. }
  119. case "this": {
  120. // @ts-expect-error https://github.com/microsoft/TypeScript/issues/41697
  121. const AssignLibraryPlugin = require("./AssignLibraryPlugin");
  122. new AssignLibraryPlugin({
  123. type,
  124. prefix: ["this"],
  125. declare: false,
  126. unnamed: "copy"
  127. }).apply(compiler);
  128. break;
  129. }
  130. case "window": {
  131. // @ts-expect-error https://github.com/microsoft/TypeScript/issues/41697
  132. const AssignLibraryPlugin = require("./AssignLibraryPlugin");
  133. new AssignLibraryPlugin({
  134. type,
  135. prefix: ["window"],
  136. declare: false,
  137. unnamed: "copy"
  138. }).apply(compiler);
  139. break;
  140. }
  141. case "self": {
  142. // @ts-expect-error https://github.com/microsoft/TypeScript/issues/41697
  143. const AssignLibraryPlugin = require("./AssignLibraryPlugin");
  144. new AssignLibraryPlugin({
  145. type,
  146. prefix: ["self"],
  147. declare: false,
  148. unnamed: "copy"
  149. }).apply(compiler);
  150. break;
  151. }
  152. case "global": {
  153. // @ts-expect-error https://github.com/microsoft/TypeScript/issues/41697
  154. const AssignLibraryPlugin = require("./AssignLibraryPlugin");
  155. new AssignLibraryPlugin({
  156. type,
  157. prefix: "global",
  158. declare: false,
  159. unnamed: "copy"
  160. }).apply(compiler);
  161. break;
  162. }
  163. case "commonjs": {
  164. // @ts-expect-error https://github.com/microsoft/TypeScript/issues/41697
  165. const AssignLibraryPlugin = require("./AssignLibraryPlugin");
  166. new AssignLibraryPlugin({
  167. type,
  168. prefix: ["exports"],
  169. declare: false,
  170. unnamed: "copy"
  171. }).apply(compiler);
  172. break;
  173. }
  174. case "commonjs-static": {
  175. // @ts-expect-error https://github.com/microsoft/TypeScript/issues/41697
  176. const AssignLibraryPlugin = require("./AssignLibraryPlugin");
  177. new AssignLibraryPlugin({
  178. type,
  179. prefix: ["exports"],
  180. declare: false,
  181. unnamed: "static"
  182. }).apply(compiler);
  183. break;
  184. }
  185. case "commonjs2":
  186. case "commonjs-module": {
  187. // @ts-expect-error https://github.com/microsoft/TypeScript/issues/41697
  188. const AssignLibraryPlugin = require("./AssignLibraryPlugin");
  189. new AssignLibraryPlugin({
  190. type,
  191. prefix: ["module", "exports"],
  192. declare: false,
  193. unnamed: "assign"
  194. }).apply(compiler);
  195. break;
  196. }
  197. case "amd":
  198. case "amd-require": {
  199. enableExportProperty();
  200. const AmdLibraryPlugin = require("./AmdLibraryPlugin");
  201. new AmdLibraryPlugin({
  202. type,
  203. requireAsWrapper: type === "amd-require"
  204. }).apply(compiler);
  205. break;
  206. }
  207. case "umd":
  208. case "umd2": {
  209. if (compiler.options.output.iife === false) {
  210. compiler.options.output.iife = true;
  211. class WarnFalseIifeUmdPlugin {
  212. /**
  213. * @param {Compiler} compiler the compiler instance
  214. */
  215. apply(compiler) {
  216. compiler.hooks.thisCompilation.tap(
  217. "WarnFalseIifeUmdPlugin",
  218. (compilation) => {
  219. const FalseIIFEUmdWarning = require("../FalseIIFEUmdWarning");
  220. compilation.warnings.push(new FalseIIFEUmdWarning());
  221. }
  222. );
  223. }
  224. }
  225. new WarnFalseIifeUmdPlugin().apply(compiler);
  226. }
  227. enableExportProperty();
  228. const UmdLibraryPlugin = require("./UmdLibraryPlugin");
  229. new UmdLibraryPlugin({
  230. type,
  231. optionalAmdExternalAsGlobal: type === "umd2"
  232. }).apply(compiler);
  233. break;
  234. }
  235. case "system": {
  236. enableExportProperty();
  237. const SystemLibraryPlugin = require("./SystemLibraryPlugin");
  238. new SystemLibraryPlugin({
  239. type
  240. }).apply(compiler);
  241. break;
  242. }
  243. case "jsonp": {
  244. enableExportProperty();
  245. const JsonpLibraryPlugin = require("./JsonpLibraryPlugin");
  246. new JsonpLibraryPlugin({
  247. type
  248. }).apply(compiler);
  249. break;
  250. }
  251. case "module":
  252. case "modern-module": {
  253. const ModuleLibraryPlugin = require("./ModuleLibraryPlugin");
  254. new ModuleLibraryPlugin({
  255. type
  256. }).apply(compiler);
  257. break;
  258. }
  259. default:
  260. throw new Error(`Unsupported library type ${type}.
  261. Plugins which provide custom library types must call EnableLibraryPlugin.setEnabled(compiler, type) to disable this error.`);
  262. }
  263. } else {
  264. // TODO support plugin instances here
  265. // apply them to the compiler
  266. }
  267. }
  268. }
  269. module.exports = EnableLibraryPlugin;