LibraryTemplatePlugin.js 4.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153
  1. /*
  2. MIT License http://www.opensource.org/licenses/mit-license.php
  3. Author Tobias Koppers @sokra
  4. */
  5. "use strict";
  6. const SetVarMainTemplatePlugin = require("./SetVarMainTemplatePlugin");
  7. /** @typedef {import("./Compiler")} Compiler */
  8. /**
  9. * @param {string[]} accessor the accessor to convert to path
  10. * @returns {string} the path
  11. */
  12. const accessorToObjectAccess = accessor => {
  13. return accessor.map(a => `[${JSON.stringify(a)}]`).join("");
  14. };
  15. /**
  16. * @param {string=} base the path prefix
  17. * @param {string|string[]} accessor the accessor
  18. * @param {string=} joinWith the element separator
  19. * @returns {string} the path
  20. */
  21. const accessorAccess = (base, accessor, joinWith = "; ") => {
  22. const accessors = Array.isArray(accessor) ? accessor : [accessor];
  23. return accessors
  24. .map((_, idx) => {
  25. const a = base
  26. ? base + accessorToObjectAccess(accessors.slice(0, idx + 1))
  27. : accessors[0] + accessorToObjectAccess(accessors.slice(1, idx + 1));
  28. if (idx === accessors.length - 1) return a;
  29. if (idx === 0 && typeof base === "undefined") {
  30. return `${a} = typeof ${a} === "object" ? ${a} : {}`;
  31. }
  32. return `${a} = ${a} || {}`;
  33. })
  34. .join(joinWith);
  35. };
  36. class LibraryTemplatePlugin {
  37. /**
  38. * @param {string} name name of library
  39. * @param {string} target type of library
  40. * @param {boolean} umdNamedDefine setting this to true will name the UMD module
  41. * @param {string|TODO} auxiliaryComment comment in the UMD wrapper
  42. * @param {string|string[]} exportProperty which export should be exposed as library
  43. */
  44. constructor(name, target, umdNamedDefine, auxiliaryComment, exportProperty) {
  45. this.name = name;
  46. this.target = target;
  47. this.umdNamedDefine = umdNamedDefine;
  48. this.auxiliaryComment = auxiliaryComment;
  49. this.exportProperty = exportProperty;
  50. }
  51. /**
  52. * @param {Compiler} compiler the compiler instance
  53. * @returns {void}
  54. */
  55. apply(compiler) {
  56. compiler.hooks.thisCompilation.tap("LibraryTemplatePlugin", compilation => {
  57. if (this.exportProperty) {
  58. const ExportPropertyMainTemplatePlugin = require("./ExportPropertyMainTemplatePlugin");
  59. new ExportPropertyMainTemplatePlugin(this.exportProperty).apply(
  60. compilation
  61. );
  62. }
  63. switch (this.target) {
  64. case "var":
  65. new SetVarMainTemplatePlugin(
  66. `var ${accessorAccess(undefined, this.name)}`,
  67. false
  68. ).apply(compilation);
  69. break;
  70. case "assign":
  71. new SetVarMainTemplatePlugin(
  72. accessorAccess(undefined, this.name),
  73. false
  74. ).apply(compilation);
  75. break;
  76. case "this":
  77. case "self":
  78. case "window":
  79. if (this.name) {
  80. new SetVarMainTemplatePlugin(
  81. accessorAccess(this.target, this.name),
  82. false
  83. ).apply(compilation);
  84. } else {
  85. new SetVarMainTemplatePlugin(this.target, true).apply(compilation);
  86. }
  87. break;
  88. case "global":
  89. if (this.name) {
  90. new SetVarMainTemplatePlugin(
  91. accessorAccess(
  92. compilation.runtimeTemplate.outputOptions.globalObject,
  93. this.name
  94. ),
  95. false
  96. ).apply(compilation);
  97. } else {
  98. new SetVarMainTemplatePlugin(
  99. compilation.runtimeTemplate.outputOptions.globalObject,
  100. true
  101. ).apply(compilation);
  102. }
  103. break;
  104. case "commonjs":
  105. if (this.name) {
  106. new SetVarMainTemplatePlugin(
  107. accessorAccess("exports", this.name),
  108. false
  109. ).apply(compilation);
  110. } else {
  111. new SetVarMainTemplatePlugin("exports", true).apply(compilation);
  112. }
  113. break;
  114. case "commonjs2":
  115. case "commonjs-module":
  116. new SetVarMainTemplatePlugin("module.exports", false).apply(
  117. compilation
  118. );
  119. break;
  120. case "amd": {
  121. const AmdMainTemplatePlugin = require("./AmdMainTemplatePlugin");
  122. new AmdMainTemplatePlugin(this.name).apply(compilation);
  123. break;
  124. }
  125. case "umd":
  126. case "umd2": {
  127. const UmdMainTemplatePlugin = require("./UmdMainTemplatePlugin");
  128. new UmdMainTemplatePlugin(this.name, {
  129. optionalAmdExternalAsGlobal: this.target === "umd2",
  130. namedDefine: this.umdNamedDefine,
  131. auxiliaryComment: this.auxiliaryComment
  132. }).apply(compilation);
  133. break;
  134. }
  135. case "jsonp": {
  136. const JsonpExportMainTemplatePlugin = require("./web/JsonpExportMainTemplatePlugin");
  137. new JsonpExportMainTemplatePlugin(this.name).apply(compilation);
  138. break;
  139. }
  140. default:
  141. throw new Error(`${this.target} is not a valid Library target`);
  142. }
  143. });
  144. }
  145. }
  146. module.exports = LibraryTemplatePlugin;