HarmonyDetectionParserPlugin.js 2.5 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192
  1. /*
  2. MIT License http://www.opensource.org/licenses/mit-license.php
  3. Author Tobias Koppers @sokra
  4. */
  5. "use strict";
  6. const HarmonyCompatibilityDependency = require("./HarmonyCompatibilityDependency");
  7. const HarmonyInitDependency = require("./HarmonyInitDependency");
  8. module.exports = class HarmonyDetectionParserPlugin {
  9. apply(parser) {
  10. parser.hooks.program.tap("HarmonyDetectionParserPlugin", ast => {
  11. const isStrictHarmony = parser.state.module.type === "javascript/esm";
  12. const isHarmony =
  13. isStrictHarmony ||
  14. ast.body.some(statement => {
  15. return /^(Import|Export).*Declaration$/.test(statement.type);
  16. });
  17. if (isHarmony) {
  18. const module = parser.state.module;
  19. const compatDep = new HarmonyCompatibilityDependency(module);
  20. compatDep.loc = {
  21. start: {
  22. line: -1,
  23. column: 0
  24. },
  25. end: {
  26. line: -1,
  27. column: 0
  28. },
  29. index: -3
  30. };
  31. module.addDependency(compatDep);
  32. const initDep = new HarmonyInitDependency(module);
  33. initDep.loc = {
  34. start: {
  35. line: -1,
  36. column: 0
  37. },
  38. end: {
  39. line: -1,
  40. column: 0
  41. },
  42. index: -2
  43. };
  44. module.addDependency(initDep);
  45. parser.state.harmonyParserScope = parser.state.harmonyParserScope || {};
  46. parser.scope.isStrict = true;
  47. module.buildMeta.exportsType = "namespace";
  48. module.buildInfo.strict = true;
  49. module.buildInfo.exportsArgument = "__webpack_exports__";
  50. if (isStrictHarmony) {
  51. module.buildMeta.strictHarmonyModule = true;
  52. module.buildInfo.moduleArgument = "__webpack_module__";
  53. }
  54. }
  55. });
  56. const skipInHarmony = () => {
  57. const module = parser.state.module;
  58. if (module && module.buildMeta && module.buildMeta.exportsType) {
  59. return true;
  60. }
  61. };
  62. const nullInHarmony = () => {
  63. const module = parser.state.module;
  64. if (module && module.buildMeta && module.buildMeta.exportsType) {
  65. return null;
  66. }
  67. };
  68. const nonHarmonyIdentifiers = ["define", "exports"];
  69. for (const identifer of nonHarmonyIdentifiers) {
  70. parser.hooks.evaluateTypeof
  71. .for(identifer)
  72. .tap("HarmonyDetectionParserPlugin", nullInHarmony);
  73. parser.hooks.typeof
  74. .for(identifer)
  75. .tap("HarmonyDetectionParserPlugin", skipInHarmony);
  76. parser.hooks.evaluate
  77. .for(identifer)
  78. .tap("HarmonyDetectionParserPlugin", nullInHarmony);
  79. parser.hooks.expression
  80. .for(identifer)
  81. .tap("HarmonyDetectionParserPlugin", skipInHarmony);
  82. parser.hooks.call
  83. .for(identifer)
  84. .tap("HarmonyDetectionParserPlugin", skipInHarmony);
  85. }
  86. }
  87. };