TransformParserPlugin.js 3.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162
  1. const relateContext = require('./util/relate-context');
  2. const pluginCompat = require('./util/plugin-compat');
  3. const ParserSchemas3 = [['Parser', 'options']];
  4. const ParserSchemas4 = [
  5. ['JsonParser', 'options'],
  6. ['Parser', 'options', 'sourceType'],
  7. ['WebAssemblyParser', 'options'],
  8. ];
  9. try {
  10. ParserSchemas3[0].Parser = require('webpack/lib/Parser');
  11. } catch (_) {}
  12. try {
  13. ParserSchemas4[0].Parser = require('webpack/lib/JsonParser');
  14. ParserSchemas4[1].Parser = require('webpack/lib/Parser');
  15. try {
  16. ParserSchemas4[2].Parser = require('webpack/lib/WebAssemblyParser');
  17. } catch (_) {
  18. ParserSchemas4[2].Parser = require('webpack/lib/wasm/WebAssemblyParser');
  19. }
  20. } catch (_) {}
  21. const freezeArgument = {};
  22. const thawArgument = {};
  23. function freezeParser(parser, extra, methods) {
  24. const schemas = extra.schemas;
  25. for (let i = 0; i < schemas.length; i++) {
  26. if (parser.constructor === schemas[i].Parser) {
  27. const frozen = {
  28. type: schemas[i][0],
  29. };
  30. for (let j = 1; j < schemas[i].length; j++) {
  31. let arg = parser[schemas[i][j]];
  32. if (freezeArgument[schemas[i][j]]) {
  33. arg = freezeArgument[schemas[i][j]](arg, parser, extra, methods);
  34. }
  35. frozen[schemas[i][j]] = arg;
  36. }
  37. return frozen;
  38. }
  39. }
  40. }
  41. function thawParser(frozen, extra, methods) {
  42. const schemas = extra.schemas;
  43. for (let i = 0; i < schemas.length; i++) {
  44. if (frozen.type === schemas[i][0]) {
  45. const Parser = schemas[i].Parser;
  46. const args = [];
  47. for (let j = 1; j < schemas[i].length; j++) {
  48. let arg = frozen[schemas[i][j]];
  49. if (thawArgument[schemas[i][j]]) {
  50. arg = thawArgument[schemas[i][j]](arg, frozen, extra, methods);
  51. }
  52. args.push(arg);
  53. }
  54. try {
  55. return new Parser(...args);
  56. } catch (_) {
  57. return new (Function.prototype.bind.apply(
  58. Parser,
  59. [null].concat(args),
  60. ))();
  61. }
  62. }
  63. }
  64. }
  65. class TransformParserPlugin {
  66. constructor(options) {
  67. this.options = options || {};
  68. }
  69. apply(compiler) {
  70. const schema = this.options.schema;
  71. let schemas = ParserSchemas4;
  72. if (schema < 4) {
  73. schemas = ParserSchemas3;
  74. }
  75. pluginCompat.register(
  76. compiler,
  77. '_hardSourceBeforeFreezeParser',
  78. 'syncWaterfall',
  79. ['frozen', 'item', 'extra'],
  80. );
  81. pluginCompat.register(
  82. compiler,
  83. '_hardSourceFreezeParser',
  84. 'syncWaterfall',
  85. ['frozen', 'item', 'extra'],
  86. );
  87. pluginCompat.register(
  88. compiler,
  89. '_hardSourceAfterFreezeParser',
  90. 'syncWaterfall',
  91. ['frozen', 'item', 'extra'],
  92. );
  93. pluginCompat.register(
  94. compiler,
  95. '_hardSourceBeforeThawParser',
  96. 'syncWaterfall',
  97. ['item', 'frozen', 'extra'],
  98. );
  99. pluginCompat.register(compiler, '_hardSourceThawParser', 'syncWaterfall', [
  100. 'item',
  101. 'frozen',
  102. 'extra',
  103. ]);
  104. pluginCompat.register(
  105. compiler,
  106. '_hardSourceAfterThawParser',
  107. 'syncWaterfall',
  108. ['item', 'frozen', 'extra'],
  109. );
  110. let methods;
  111. pluginCompat.tap(
  112. compiler,
  113. '_hardSourceMethods',
  114. 'TransformParserPlugin',
  115. _methods => {
  116. methods = _methods;
  117. },
  118. );
  119. pluginCompat.tap(
  120. compiler,
  121. '_hardSourceFreezeParser',
  122. 'TransformParserPlugin freeze',
  123. (frozen, parser, extra) => {
  124. extra.schemas = schemas;
  125. frozen = freezeParser(parser, extra, methods);
  126. if (schema === 4) {
  127. frozen.moduleType = extra.module.type;
  128. }
  129. return frozen;
  130. },
  131. );
  132. pluginCompat.tap(
  133. compiler,
  134. '_hardSourceThawParser',
  135. 'TransformParserPlugin thaw',
  136. (parser, { options, moduleType }, { normalModuleFactory }) => {
  137. if (schema < 4) {
  138. return normalModuleFactory.getParser(options);
  139. } else {
  140. return normalModuleFactory.getParser(moduleType, options);
  141. }
  142. },
  143. );
  144. }
  145. }
  146. module.exports = TransformParserPlugin;