AsyncModuleRuntimeModule.js 4.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130
  1. /*
  2. MIT License http://www.opensource.org/licenses/mit-license.php
  3. */
  4. "use strict";
  5. const RuntimeGlobals = require("../RuntimeGlobals");
  6. const Template = require("../Template");
  7. const HelperRuntimeModule = require("./HelperRuntimeModule");
  8. class AsyncModuleRuntimeModule extends HelperRuntimeModule {
  9. constructor() {
  10. super("async module");
  11. }
  12. /**
  13. * @returns {string} runtime code
  14. */
  15. generate() {
  16. const { runtimeTemplate } = this.compilation;
  17. const fn = RuntimeGlobals.asyncModule;
  18. return Template.asString([
  19. 'var webpackQueues = typeof Symbol === "function" ? Symbol("webpack queues") : "__webpack_queues__";',
  20. 'var webpackExports = typeof Symbol === "function" ? Symbol("webpack exports") : "__webpack_exports__";',
  21. 'var webpackError = typeof Symbol === "function" ? Symbol("webpack error") : "__webpack_error__";',
  22. `var resolveQueue = ${runtimeTemplate.basicFunction("queue", [
  23. "if(queue && !queue.d) {",
  24. Template.indent([
  25. "queue.d = 1;",
  26. `queue.forEach(${runtimeTemplate.expressionFunction(
  27. "fn.r--",
  28. "fn"
  29. )});`,
  30. `queue.forEach(${runtimeTemplate.expressionFunction(
  31. "fn.r-- ? fn.r++ : fn()",
  32. "fn"
  33. )});`
  34. ]),
  35. "}"
  36. ])}`,
  37. `var wrapDeps = ${runtimeTemplate.returningFunction(
  38. `deps.map(${runtimeTemplate.basicFunction("dep", [
  39. 'if(dep !== null && typeof dep === "object") {',
  40. Template.indent([
  41. "if(dep[webpackQueues]) return dep;",
  42. "if(dep.then) {",
  43. Template.indent([
  44. "var queue = [];",
  45. "queue.d = 0;",
  46. `dep.then(${runtimeTemplate.basicFunction("r", [
  47. "obj[webpackExports] = r;",
  48. "resolveQueue(queue);"
  49. ])}, ${runtimeTemplate.basicFunction("e", [
  50. "obj[webpackError] = e;",
  51. "resolveQueue(queue);"
  52. ])});`,
  53. "var obj = {};",
  54. `obj[webpackQueues] = ${runtimeTemplate.expressionFunction(
  55. `fn(queue)`,
  56. "fn"
  57. )};`,
  58. "return obj;"
  59. ]),
  60. "}"
  61. ]),
  62. "}",
  63. "var ret = {};",
  64. `ret[webpackQueues] = ${runtimeTemplate.emptyFunction()};`,
  65. "ret[webpackExports] = dep;",
  66. "return ret;"
  67. ])})`,
  68. "deps"
  69. )};`,
  70. `${fn} = ${runtimeTemplate.basicFunction("module, body, hasAwait", [
  71. "var queue;",
  72. "hasAwait && ((queue = []).d = 1);",
  73. "var depQueues = new Set();",
  74. "var exports = module.exports;",
  75. "var currentDeps;",
  76. "var outerResolve;",
  77. "var reject;",
  78. `var promise = new Promise(${runtimeTemplate.basicFunction(
  79. "resolve, rej",
  80. ["reject = rej;", "outerResolve = resolve;"]
  81. )});`,
  82. "promise[webpackExports] = exports;",
  83. `promise[webpackQueues] = ${runtimeTemplate.expressionFunction(
  84. `queue && fn(queue), depQueues.forEach(fn), promise["catch"](${runtimeTemplate.emptyFunction()})`,
  85. "fn"
  86. )};`,
  87. "module.exports = promise;",
  88. `body(${runtimeTemplate.basicFunction("deps", [
  89. "currentDeps = wrapDeps(deps);",
  90. "var fn;",
  91. `var getResult = ${runtimeTemplate.returningFunction(
  92. `currentDeps.map(${runtimeTemplate.basicFunction("d", [
  93. "if(d[webpackError]) throw d[webpackError];",
  94. "return d[webpackExports];"
  95. ])})`
  96. )}`,
  97. `var promise = new Promise(${runtimeTemplate.basicFunction(
  98. "resolve",
  99. [
  100. `fn = ${runtimeTemplate.expressionFunction(
  101. "resolve(getResult)",
  102. ""
  103. )};`,
  104. "fn.r = 0;",
  105. `var fnQueue = ${runtimeTemplate.expressionFunction(
  106. "q !== queue && !depQueues.has(q) && (depQueues.add(q), q && !q.d && (fn.r++, q.push(fn)))",
  107. "q"
  108. )};`,
  109. `currentDeps.map(${runtimeTemplate.expressionFunction(
  110. "dep[webpackQueues](fnQueue)",
  111. "dep"
  112. )});`
  113. ]
  114. )});`,
  115. "return fn.r ? promise : getResult();"
  116. ])}, ${runtimeTemplate.expressionFunction(
  117. "(err ? reject(promise[webpackError] = err) : outerResolve(exports)), resolveQueue(queue)",
  118. "err"
  119. )});`,
  120. "queue && (queue.d = 0);"
  121. ])};`
  122. ]);
  123. }
  124. }
  125. module.exports = AsyncModuleRuntimeModule;