EnableLibraryPlugin.js 8.2 KB

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