no-hide-core-modules.js 4.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144
  1. /**
  2. * @author Toru Nagashima
  3. * See LICENSE file in root directory for full license.
  4. *
  5. * @deprecated since v4.2.0
  6. * This rule was based on an invalid assumption.
  7. * No meaning.
  8. */
  9. "use strict"
  10. const path = require("path")
  11. const resolve = require("resolve")
  12. const getPackageJson = require("../util/get-package-json")
  13. const getRequireTargets = require("../util/get-require-targets")
  14. const getImportExportTargets = require("../util/get-import-export-targets")
  15. const CORE_MODULES = new Set([
  16. "assert",
  17. "buffer",
  18. "child_process",
  19. "cluster",
  20. "console",
  21. "constants",
  22. "crypto",
  23. "dgram",
  24. "dns",
  25. /* "domain", */ "events",
  26. "fs",
  27. "http",
  28. "https",
  29. "module",
  30. "net",
  31. "os",
  32. "path",
  33. /* "punycode", */ "querystring",
  34. "readline",
  35. "repl",
  36. "stream",
  37. "string_decoder",
  38. "timers",
  39. "tls",
  40. "tty",
  41. "url",
  42. "util",
  43. "vm",
  44. "zlib",
  45. ])
  46. const BACK_SLASH = /\\/gu
  47. module.exports = {
  48. meta: {
  49. docs: {
  50. description:
  51. "disallow third-party modules which are hiding core modules",
  52. category: "Possible Errors",
  53. recommended: false,
  54. url:
  55. "https://github.com/mysticatea/eslint-plugin-node/blob/v8.0.1/docs/rules/no-hide-core-modules.md",
  56. },
  57. type: "problem",
  58. deprecated: true,
  59. fixable: null,
  60. schema: [
  61. {
  62. type: "object",
  63. properties: {
  64. allow: {
  65. type: "array",
  66. items: { enum: Array.from(CORE_MODULES) },
  67. additionalItems: false,
  68. uniqueItems: true,
  69. },
  70. ignoreDirectDependencies: { type: "boolean" },
  71. ignoreIndirectDependencies: { type: "boolean" },
  72. },
  73. additionalProperties: false,
  74. },
  75. ],
  76. },
  77. create(context) {
  78. if (context.getFilename() === "<input>") {
  79. return {}
  80. }
  81. const filePath = path.resolve(context.getFilename())
  82. const dirPath = path.dirname(filePath)
  83. const packageJson = getPackageJson(filePath)
  84. const deps = new Set(
  85. [].concat(
  86. Object.keys((packageJson && packageJson.dependencies) || {}),
  87. Object.keys((packageJson && packageJson.devDependencies) || {})
  88. )
  89. )
  90. const options = context.options[0] || {}
  91. const allow = options.allow || []
  92. const ignoreDirectDependencies = Boolean(
  93. options.ignoreDirectDependencies
  94. )
  95. const ignoreIndirectDependencies = Boolean(
  96. options.ignoreIndirectDependencies
  97. )
  98. return {
  99. "Program:exit"(node) {
  100. const targets = []
  101. .concat(
  102. getRequireTargets(context, true),
  103. getImportExportTargets(context, node, true)
  104. )
  105. .filter(t => CORE_MODULES.has(t.moduleName))
  106. for (const target of targets) {
  107. const name = target.moduleName
  108. const allowed =
  109. allow.indexOf(name) !== -1 ||
  110. (ignoreDirectDependencies && deps.has(name)) ||
  111. (ignoreIndirectDependencies && !deps.has(name))
  112. if (allowed) {
  113. continue
  114. }
  115. const resolved = resolve.sync(name, { basedir: dirPath })
  116. const isCore = resolved === name
  117. if (isCore) {
  118. continue
  119. }
  120. context.report({
  121. node: target.node,
  122. loc: target.node.loc,
  123. message:
  124. "Unexpected import of third-party module '{{name}}'.",
  125. data: {
  126. name: path
  127. .relative(dirPath, resolved)
  128. .replace(BACK_SLASH, "/"),
  129. },
  130. })
  131. }
  132. },
  133. }
  134. },
  135. }