NodeStuffPlugin.js 3.8 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697
  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.plugin("compilation", (compilation, params) => {
  17. compilation.dependencyFactories.set(ConstDependency, new NullFactory());
  18. compilation.dependencyTemplates.set(ConstDependency, new ConstDependency.Template());
  19. params.normalModuleFactory.plugin("parser", (parser, parserOptions) => {
  20. if(parserOptions.node === false)
  21. return;
  22. let localOptions = options;
  23. if(parserOptions.node)
  24. localOptions = Object.assign({}, localOptions, parserOptions.node);
  25. function setConstant(expressionName, value) {
  26. parser.plugin(`expression ${expressionName}`, function() {
  27. this.state.current.addVariable(expressionName, JSON.stringify(value));
  28. return true;
  29. });
  30. }
  31. function setModuleConstant(expressionName, fn) {
  32. parser.plugin(`expression ${expressionName}`, function() {
  33. this.state.current.addVariable(expressionName, JSON.stringify(fn(this.state.module)));
  34. return true;
  35. });
  36. }
  37. const context = compiler.context;
  38. if(localOptions.__filename === "mock") {
  39. setConstant("__filename", "/index.js");
  40. } else if(localOptions.__filename) {
  41. setModuleConstant("__filename", module => path.relative(context, module.resource));
  42. }
  43. parser.plugin("evaluate Identifier __filename", function(expr) {
  44. if(!this.state.module) return;
  45. const resource = this.state.module.resource;
  46. const i = resource.indexOf("?");
  47. return ParserHelpers.evaluateToString(i < 0 ? resource : resource.substr(0, i))(expr);
  48. });
  49. if(localOptions.__dirname === "mock") {
  50. setConstant("__dirname", "/");
  51. } else if(localOptions.__dirname) {
  52. setModuleConstant("__dirname", module => path.relative(context, module.context));
  53. }
  54. parser.plugin("evaluate Identifier __dirname", function(expr) {
  55. if(!this.state.module) return;
  56. return ParserHelpers.evaluateToString(this.state.module.context)(expr);
  57. });
  58. parser.plugin("expression require.main", ParserHelpers.toConstantDependency("__webpack_require__.c[__webpack_require__.s]"));
  59. parser.plugin(
  60. "expression require.extensions",
  61. ParserHelpers.expressionIsUnsupported("require.extensions is not supported by webpack. Use a loader instead.")
  62. );
  63. parser.plugin("expression module.loaded", ParserHelpers.toConstantDependency("module.l"));
  64. parser.plugin("expression module.id", ParserHelpers.toConstantDependency("module.i"));
  65. parser.plugin("expression module.exports", function() {
  66. const module = this.state.module;
  67. const isHarmony = module.meta && module.meta.harmonyModule;
  68. if(!isHarmony)
  69. return true;
  70. });
  71. parser.plugin("evaluate Identifier module.hot", ParserHelpers.evaluateToBoolean(false));
  72. parser.plugin("expression module", function() {
  73. const module = this.state.module;
  74. const isHarmony = module.meta && module.meta.harmonyModule;
  75. let moduleJsPath = path.join(__dirname, "..", "buildin", isHarmony ? "harmony-module.js" : "module.js");
  76. if(module.context) {
  77. moduleJsPath = path.relative(this.state.module.context, moduleJsPath);
  78. if(!/^[A-Z]:/i.test(moduleJsPath)) {
  79. moduleJsPath = `./${moduleJsPath.replace(/\\/g, "/")}`;
  80. }
  81. }
  82. return ParserHelpers.addParsedVariableToModule(this, "module", `require(${JSON.stringify(moduleJsPath)})(module)`);
  83. });
  84. });
  85. });
  86. }
  87. }
  88. module.exports = NodeStuffPlugin;