UseStrictPlugin.js 2.7 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182
  1. /*
  2. MIT License http://www.opensource.org/licenses/mit-license.php
  3. Author Tobias Koppers @sokra
  4. */
  5. "use strict";
  6. const {
  7. JAVASCRIPT_MODULE_TYPE_AUTO,
  8. JAVASCRIPT_MODULE_TYPE_DYNAMIC,
  9. JAVASCRIPT_MODULE_TYPE_ESM
  10. } = require("./ModuleTypeConstants");
  11. const ConstDependency = require("./dependencies/ConstDependency");
  12. /** @typedef {import("../declarations/WebpackOptions").JavascriptParserOptions} JavascriptParserOptions */
  13. /** @typedef {import("./Compiler")} Compiler */
  14. /** @typedef {import("./Dependency").DependencyLocation} DependencyLocation */
  15. /** @typedef {import("./Module").BuildInfo} BuildInfo */
  16. /** @typedef {import("./javascript/JavascriptParser")} JavascriptParser */
  17. /** @typedef {import("./javascript/JavascriptParser").Range} Range */
  18. const PLUGIN_NAME = "UseStrictPlugin";
  19. class UseStrictPlugin {
  20. /**
  21. * Applies the plugin by registering its hooks on the compiler.
  22. * @param {Compiler} compiler the compiler instance
  23. * @returns {void}
  24. */
  25. apply(compiler) {
  26. compiler.hooks.compilation.tap(
  27. PLUGIN_NAME,
  28. (compilation, { normalModuleFactory }) => {
  29. /**
  30. * Handles the hook callback for this code path.
  31. * @param {JavascriptParser} parser the parser
  32. * @param {JavascriptParserOptions} parserOptions the javascript parser options
  33. */
  34. const handler = (parser, parserOptions) => {
  35. parser.hooks.program.tap(PLUGIN_NAME, (ast) => {
  36. const firstNode = ast.body[0];
  37. if (
  38. firstNode &&
  39. firstNode.type === "ExpressionStatement" &&
  40. firstNode.expression.type === "Literal" &&
  41. firstNode.expression.value === "use strict"
  42. ) {
  43. // Remove "use strict" expression. It will be added later by the renderer again.
  44. // This is necessary in order to not break the strict mode when webpack prepends code.
  45. // @see https://github.com/webpack/webpack/issues/1970
  46. const dep = new ConstDependency(
  47. "",
  48. /** @type {Range} */ (firstNode.range)
  49. );
  50. dep.loc = /** @type {DependencyLocation} */ (firstNode.loc);
  51. parser.state.module.addPresentationalDependency(dep);
  52. /** @type {BuildInfo} */
  53. (parser.state.module.buildInfo).strict = true;
  54. }
  55. if (parserOptions.overrideStrict) {
  56. /** @type {BuildInfo} */
  57. (parser.state.module.buildInfo).strict =
  58. parserOptions.overrideStrict === "strict";
  59. }
  60. });
  61. };
  62. normalModuleFactory.hooks.parser
  63. .for(JAVASCRIPT_MODULE_TYPE_AUTO)
  64. .tap(PLUGIN_NAME, handler);
  65. normalModuleFactory.hooks.parser
  66. .for(JAVASCRIPT_MODULE_TYPE_DYNAMIC)
  67. .tap(PLUGIN_NAME, handler);
  68. normalModuleFactory.hooks.parser
  69. .for(JAVASCRIPT_MODULE_TYPE_ESM)
  70. .tap(PLUGIN_NAME, handler);
  71. }
  72. );
  73. }
  74. }
  75. module.exports = UseStrictPlugin;