ConditionalInitFragment.js 3.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112
  1. /*
  2. MIT License http://www.opensource.org/licenses/mit-license.php
  3. Author Tobias Koppers @sokra
  4. */
  5. "use strict";
  6. const { ConcatSource, PrefixSource } = require("webpack-sources");
  7. const InitFragment = require("./InitFragment");
  8. const Template = require("./Template");
  9. const { mergeRuntime } = require("./util/runtime");
  10. /** @typedef {import("webpack-sources").Source} Source */
  11. /** @typedef {import("./Generator").GenerateContext} GenerateContext */
  12. /** @typedef {import("./util/runtime").RuntimeSpec} RuntimeSpec */
  13. const wrapInCondition = (condition, source) => {
  14. if (typeof source === "string") {
  15. return Template.asString([
  16. `if (${condition}) {`,
  17. Template.indent(source),
  18. "}",
  19. ""
  20. ]);
  21. } else {
  22. return new ConcatSource(
  23. `if (${condition}) {\n`,
  24. new PrefixSource("\t", source),
  25. "}\n"
  26. );
  27. }
  28. };
  29. /**
  30. * @typedef {GenerateContext} Context
  31. */
  32. class ConditionalInitFragment extends InitFragment {
  33. /**
  34. * @param {string|Source} content the source code that will be included as initialization code
  35. * @param {number} stage category of initialization code (contribute to order)
  36. * @param {number} position position in the category (contribute to order)
  37. * @param {string} key unique key to avoid emitting the same initialization code twice
  38. * @param {RuntimeSpec | boolean} runtimeCondition in which runtime this fragment should be executed
  39. * @param {string|Source=} endContent the source code that will be included at the end of the module
  40. */
  41. constructor(
  42. content,
  43. stage,
  44. position,
  45. key,
  46. runtimeCondition = true,
  47. endContent
  48. ) {
  49. super(content, stage, position, key, endContent);
  50. this.runtimeCondition = runtimeCondition;
  51. }
  52. /**
  53. * @param {Context} context context
  54. * @returns {string|Source} the source code that will be included as initialization code
  55. */
  56. getContent(context) {
  57. if (this.runtimeCondition === false || !this.content) return "";
  58. if (this.runtimeCondition === true) return this.content;
  59. const expr = context.runtimeTemplate.runtimeConditionExpression({
  60. chunkGraph: context.chunkGraph,
  61. runtimeRequirements: context.runtimeRequirements,
  62. runtime: context.runtime,
  63. runtimeCondition: this.runtimeCondition
  64. });
  65. if (expr === "true") return this.content;
  66. return wrapInCondition(expr, this.content);
  67. }
  68. /**
  69. * @param {Context} context context
  70. * @returns {string|Source=} the source code that will be included at the end of the module
  71. */
  72. getEndContent(context) {
  73. if (this.runtimeCondition === false || !this.endContent) return "";
  74. if (this.runtimeCondition === true) return this.endContent;
  75. const expr = context.runtimeTemplate.runtimeConditionExpression({
  76. chunkGraph: context.chunkGraph,
  77. runtimeRequirements: context.runtimeRequirements,
  78. runtime: context.runtime,
  79. runtimeCondition: this.runtimeCondition
  80. });
  81. if (expr === "true") return this.endContent;
  82. return wrapInCondition(expr, this.endContent);
  83. }
  84. merge(other) {
  85. if (this.runtimeCondition === true) return this;
  86. if (other.runtimeCondition === true) return other;
  87. if (this.runtimeCondition === false) return other;
  88. if (other.runtimeCondition === false) return this;
  89. const runtimeCondition = mergeRuntime(
  90. this.runtimeCondition,
  91. other.runtimeCondition
  92. );
  93. return new ConditionalInitFragment(
  94. this.content,
  95. this.stage,
  96. this.position,
  97. this.key,
  98. runtimeCondition,
  99. this.endContent
  100. );
  101. }
  102. }
  103. module.exports = ConditionalInitFragment;