EvalDevToolModulePlugin.js 3.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117
  1. /*
  2. MIT License http://www.opensource.org/licenses/mit-license.php
  3. Author Tobias Koppers @sokra
  4. */
  5. "use strict";
  6. const { ConcatSource, RawSource } = require("webpack-sources");
  7. const ExternalModule = require("./ExternalModule");
  8. const ModuleFilenameHelpers = require("./ModuleFilenameHelpers");
  9. const RuntimeGlobals = require("./RuntimeGlobals");
  10. const JavascriptModulesPlugin = require("./javascript/JavascriptModulesPlugin");
  11. /** @typedef {import("webpack-sources").Source} Source */
  12. /** @typedef {import("./Compiler")} Compiler */
  13. /** @type {WeakMap<Source, Source>} */
  14. const cache = new WeakMap();
  15. const devtoolWarning = new RawSource(`/*
  16. * ATTENTION: The "eval" devtool has been used (maybe by default in mode: "development").
  17. * This devtool is neither made for production nor for readable output files.
  18. * It uses "eval()" calls to create a separate source file in the browser devtools.
  19. * If you are trying to read the output file, select a different devtool (https://webpack.js.org/configuration/devtool/)
  20. * or disable the default devtool with "devtool: false".
  21. * If you are looking for production-ready output files, see mode: "production" (https://webpack.js.org/configuration/mode/).
  22. */
  23. `);
  24. class EvalDevToolModulePlugin {
  25. constructor(options) {
  26. this.namespace = options.namespace || "";
  27. this.sourceUrlComment = options.sourceUrlComment || "\n//# sourceURL=[url]";
  28. this.moduleFilenameTemplate =
  29. options.moduleFilenameTemplate ||
  30. "webpack://[namespace]/[resourcePath]?[loaders]";
  31. }
  32. /**
  33. * Apply the plugin
  34. * @param {Compiler} compiler the compiler instance
  35. * @returns {void}
  36. */
  37. apply(compiler) {
  38. compiler.hooks.compilation.tap("EvalDevToolModulePlugin", compilation => {
  39. const hooks = JavascriptModulesPlugin.getCompilationHooks(compilation);
  40. hooks.renderModuleContent.tap(
  41. "EvalDevToolModulePlugin",
  42. (source, module, { runtimeTemplate, chunkGraph }) => {
  43. const cacheEntry = cache.get(source);
  44. if (cacheEntry !== undefined) return cacheEntry;
  45. if (module instanceof ExternalModule) {
  46. cache.set(source, source);
  47. return source;
  48. }
  49. const content = source.source();
  50. const str = ModuleFilenameHelpers.createFilename(
  51. module,
  52. {
  53. moduleFilenameTemplate: this.moduleFilenameTemplate,
  54. namespace: this.namespace
  55. },
  56. {
  57. requestShortener: runtimeTemplate.requestShortener,
  58. chunkGraph,
  59. hashFunction: compilation.outputOptions.hashFunction
  60. }
  61. );
  62. const footer =
  63. "\n" +
  64. this.sourceUrlComment.replace(
  65. /\[url\]/g,
  66. encodeURI(str)
  67. .replace(/%2F/g, "/")
  68. .replace(/%20/g, "_")
  69. .replace(/%5E/g, "^")
  70. .replace(/%5C/g, "\\")
  71. .replace(/^\//, "")
  72. );
  73. const result = new RawSource(
  74. `eval(${
  75. compilation.outputOptions.trustedTypes
  76. ? `${RuntimeGlobals.createScript}(${JSON.stringify(
  77. content + footer
  78. )})`
  79. : JSON.stringify(content + footer)
  80. });`
  81. );
  82. cache.set(source, result);
  83. return result;
  84. }
  85. );
  86. hooks.inlineInRuntimeBailout.tap(
  87. "EvalDevToolModulePlugin",
  88. () => "the eval devtool is used."
  89. );
  90. hooks.render.tap(
  91. "EvalDevToolModulePlugin",
  92. source => new ConcatSource(devtoolWarning, source)
  93. );
  94. hooks.chunkHash.tap("EvalDevToolModulePlugin", (chunk, hash) => {
  95. hash.update("EvalDevToolModulePlugin");
  96. hash.update("2");
  97. });
  98. if (compilation.outputOptions.trustedTypes) {
  99. compilation.hooks.additionalModuleRuntimeRequirements.tap(
  100. "EvalDevToolModulePlugin",
  101. (module, set, context) => {
  102. set.add(RuntimeGlobals.createScript);
  103. }
  104. );
  105. }
  106. });
  107. }
  108. }
  109. module.exports = EvalDevToolModulePlugin;