NodeStuffPlugin.js 3.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118
  1. /*
  2. MIT License http://www.opensource.org/licenses/mit-license.php
  3. Author Tobias Koppers @sokra
  4. */
  5. "use strict";
  6. const path = require("path");
  7. const ParserHelpers = require("./ParserHelpers");
  8. const ConstDependency = require("./dependencies/ConstDependency");
  9. const NullFactory = require("./NullFactory");
  10. class NodeStuffPlugin {
  11. constructor(options) {
  12. this.options = options;
  13. }
  14. apply(compiler) {
  15. const options = this.options;
  16. compiler.hooks.compilation.tap(
  17. "NodeStuffPlugin",
  18. (compilation, { normalModuleFactory }) => {
  19. compilation.dependencyFactories.set(ConstDependency, new NullFactory());
  20. compilation.dependencyTemplates.set(
  21. ConstDependency,
  22. new ConstDependency.Template()
  23. );
  24. const handler = (parser, parserOptions) => {
  25. if (parserOptions.node === false) return;
  26. let localOptions = options;
  27. if (parserOptions.node) {
  28. localOptions = Object.assign({}, localOptions, parserOptions.node);
  29. }
  30. const setConstant = (expressionName, value) => {
  31. parser.hooks.expression
  32. .for(expressionName)
  33. .tap("NodeStuffPlugin", () => {
  34. parser.state.current.addVariable(
  35. expressionName,
  36. JSON.stringify(value)
  37. );
  38. return true;
  39. });
  40. };
  41. const setModuleConstant = (expressionName, fn) => {
  42. parser.hooks.expression
  43. .for(expressionName)
  44. .tap("NodeStuffPlugin", () => {
  45. parser.state.current.addVariable(
  46. expressionName,
  47. JSON.stringify(fn(parser.state.module))
  48. );
  49. return true;
  50. });
  51. };
  52. const context = compiler.context;
  53. if (localOptions.__filename) {
  54. if (localOptions.__filename === "mock") {
  55. setConstant("__filename", "/index.js");
  56. } else {
  57. setModuleConstant("__filename", module =>
  58. path.relative(context, module.resource)
  59. );
  60. }
  61. parser.hooks.evaluateIdentifier
  62. .for("__filename")
  63. .tap("NodeStuffPlugin", expr => {
  64. if (!parser.state.module) return;
  65. const resource = parser.state.module.resource;
  66. const i = resource.indexOf("?");
  67. return ParserHelpers.evaluateToString(
  68. i < 0 ? resource : resource.substr(0, i)
  69. )(expr);
  70. });
  71. }
  72. if (localOptions.__dirname) {
  73. if (localOptions.__dirname === "mock") {
  74. setConstant("__dirname", "/");
  75. } else {
  76. setModuleConstant("__dirname", module =>
  77. path.relative(context, module.context)
  78. );
  79. }
  80. parser.hooks.evaluateIdentifier
  81. .for("__dirname")
  82. .tap("NodeStuffPlugin", expr => {
  83. if (!parser.state.module) return;
  84. return ParserHelpers.evaluateToString(
  85. parser.state.module.context
  86. )(expr);
  87. });
  88. }
  89. parser.hooks.expression
  90. .for("require.extensions")
  91. .tap(
  92. "NodeStuffPlugin",
  93. ParserHelpers.expressionIsUnsupported(
  94. parser,
  95. "require.extensions is not supported by webpack. Use a loader instead."
  96. )
  97. );
  98. };
  99. normalModuleFactory.hooks.parser
  100. .for("javascript/auto")
  101. .tap("NodeStuffPlugin", handler);
  102. normalModuleFactory.hooks.parser
  103. .for("javascript/dynamic")
  104. .tap("NodeStuffPlugin", handler);
  105. }
  106. );
  107. }
  108. }
  109. module.exports = NodeStuffPlugin;