getESLint.js 3.4 KB

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