getESLint.js 3.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155
  1. "use strict";
  2. Object.defineProperty(exports, "__esModule", {
  3. value: true
  4. });
  5. exports.default = getESLint;
  6. exports.loadESLint = loadESLint;
  7. exports.loadESLintThreaded = loadESLintThreaded;
  8. var _os = require("os");
  9. var _jestWorker = require("jest-worker");
  10. var _options = require("./options");
  11. var _utils = require("./utils");
  12. /** @type {{[key: string]: any}} */
  13. const cache = {};
  14. /** @typedef {import('eslint').ESLint} ESLint */
  15. /** @typedef {import('eslint').ESLint.LintResult} LintResult */
  16. /** @typedef {import('./options').Options} Options */
  17. /** @typedef {() => Promise<void>} AsyncTask */
  18. /** @typedef {(files: string|string[]) => Promise<LintResult[]>} LintTask */
  19. /** @typedef {JestWorker & {lintFiles: LintTask}} Worker */
  20. /** @typedef {{threads: number, ESLint: ESLint, eslint: ESLint, lintFiles: LintTask, cleanup: AsyncTask}} Linter */
  21. /**
  22. * @param {Options} options
  23. * @returns {Linter}
  24. */
  25. function loadESLint(options) {
  26. const {
  27. eslintPath
  28. } = options;
  29. const {
  30. ESLint
  31. } = require(eslintPath || 'eslint'); // Filter out loader options before passing the options to ESLint.
  32. const eslint = new ESLint((0, _options.getESLintOptions)(options));
  33. return {
  34. threads: 1,
  35. ESLint,
  36. eslint,
  37. lintFiles: async files => {
  38. const results = await eslint.lintFiles(files); // istanbul ignore else
  39. if (options.fix) {
  40. await ESLint.outputFixes(results);
  41. }
  42. return results;
  43. },
  44. // no-op for non-threaded
  45. cleanup: async () => {}
  46. };
  47. }
  48. /**
  49. * @param {string|undefined} key
  50. * @param {number} poolSize
  51. * @param {Options} options
  52. * @returns {Linter}
  53. */
  54. function loadESLintThreaded(key, poolSize, options) {
  55. const cacheKey = getCacheKey(key, options);
  56. const {
  57. eslintPath = 'eslint'
  58. } = options;
  59. const source = require.resolve('./worker');
  60. const workerOptions = {
  61. enableWorkerThreads: true,
  62. numWorkers: poolSize,
  63. setupArgs: [{
  64. eslintPath,
  65. eslintOptions: (0, _options.getESLintOptions)(options)
  66. }]
  67. };
  68. const local = loadESLint(options);
  69. /** @type {Worker?} */
  70. // prettier-ignore
  71. let worker =
  72. /** @type {Worker} */
  73. new _jestWorker.Worker(source, workerOptions);
  74. /** @type {Linter} */
  75. const context = { ...local,
  76. threads: poolSize,
  77. lintFiles: async files => worker && (await worker.lintFiles(files)) ||
  78. /* istanbul ignore next */
  79. [],
  80. cleanup: async () => {
  81. cache[cacheKey] = local;
  82. context.lintFiles = files => local.lintFiles(files);
  83. if (worker) {
  84. worker.end();
  85. worker = null;
  86. }
  87. }
  88. };
  89. return context;
  90. }
  91. /**
  92. * @param {string|undefined} key
  93. * @param {Options} options
  94. * @returns {Linter}
  95. */
  96. function getESLint(key, {
  97. threads,
  98. ...options
  99. }) {
  100. const max = typeof threads !== 'number' ? threads ? (0, _os.cpus)().length - 1 : 1 :
  101. /* istanbul ignore next */
  102. threads;
  103. const cacheKey = getCacheKey(key, {
  104. threads,
  105. ...options
  106. });
  107. if (!cache[cacheKey]) {
  108. cache[cacheKey] = max > 1 ? loadESLintThreaded(key, max, options) : loadESLint(options);
  109. }
  110. return cache[cacheKey];
  111. }
  112. /**
  113. * @param {string|undefined} key
  114. * @param {Options} options
  115. * @returns {string}
  116. */
  117. function getCacheKey(key, options) {
  118. return JSON.stringify({
  119. key,
  120. options
  121. }, _utils.jsonStringifyReplacerSortKeys);
  122. }