From fc715196af54c32633a25179229a4f32b68580ca Mon Sep 17 00:00:00 2001 From: Tommy Nguyen <4123478+tido64@users.noreply.github.com> Date: Thu, 4 Nov 2021 18:49:43 +0100 Subject: [PATCH] fix(eslint-plugin): prefer `module` over `main` and add debug options (#809) --- .github/workflows/pr.yml | 4 +- ...-29a319c1-ec26-4fab-bfd1-80955a49180b.json | 7 +++ package.json | 3 + .../eslint-plugin/src/rules/no-export-all.js | 63 ++++++++++++++----- 4 files changed, 58 insertions(+), 19 deletions(-) create mode 100644 change/@rnx-kit-eslint-plugin-29a319c1-ec26-4fab-bfd1-80955a49180b.json diff --git a/.github/workflows/pr.yml b/.github/workflows/pr.yml index 9f3c8aeca..bb466bc59 100644 --- a/.github/workflows/pr.yml +++ b/.github/workflows/pr.yml @@ -20,7 +20,7 @@ jobs: uses: actions/cache@v2.1.6 with: path: .yarn-offline-mirror - key: ${{ hashFiles('yarn.lock') }} + key: ${{ runner.os }}-${{ hashFiles('yarn.lock') }} - name: Install package dependencies run: yarn ci env: @@ -66,7 +66,7 @@ jobs: uses: actions/cache@v2.1.6 with: path: .yarn-offline-mirror - key: ${{ hashFiles('yarn.lock') }} + key: ${{ runner.os }}-${{ hashFiles('yarn.lock') }} - name: Install package dependencies run: yarn ci - name: Build and test packages diff --git a/change/@rnx-kit-eslint-plugin-29a319c1-ec26-4fab-bfd1-80955a49180b.json b/change/@rnx-kit-eslint-plugin-29a319c1-ec26-4fab-bfd1-80955a49180b.json new file mode 100644 index 000000000..b995f4132 --- /dev/null +++ b/change/@rnx-kit-eslint-plugin-29a319c1-ec26-4fab-bfd1-80955a49180b.json @@ -0,0 +1,7 @@ +{ + "type": "patch", + "comment": "Adds `module` to the list of main fields to consider, and options for setting max depth and enabling debug output.", + "packageName": "@rnx-kit/eslint-plugin", + "email": "4123478+tido64@users.noreply.github.com", + "dependentChangeType": "none" +} diff --git a/package.json b/package.json index c3db75870..4b025cca4 100644 --- a/package.json +++ b/package.json @@ -50,6 +50,9 @@ "prettier": "^2.3.0", "suggestion-bot": "^1.2.2" }, + "engines": { + "node": ">=14.15" + }, "resolutions": { "micromatch": "^4.0.0" }, diff --git a/packages/eslint-plugin/src/rules/no-export-all.js b/packages/eslint-plugin/src/rules/no-export-all.js index 8850cf2d0..0dced5904 100644 --- a/packages/eslint-plugin/src/rules/no-export-all.js +++ b/packages/eslint-plugin/src/rules/no-export-all.js @@ -8,7 +8,10 @@ * * @typedef {{ * id: ESLintRuleContext["id"]; - * options: ESLintRuleContext["options"]; + * options: { + * debug: boolean; + * maxDepth: number; + * }; * settings: ESLintRuleContext["settings"]; * parserPath: ESLintRuleContext["parserPath"]; * parserOptions: ESLintRuleContext["parserOptions"]; @@ -33,8 +36,6 @@ const DEFAULT_CONFIG = { eslintScopeManager: true, }; -const MAX_DEPTH = 5; - /** * Returns whether there are any named exports. * @param {NamedExports?} namedExports @@ -74,6 +75,7 @@ const resolveFrom = const resolve = require("enhanced-resolve").create.sync({ extensions: [".ts", ".tsx", ".js", ".jsx"], + mainFields: ["module", "main"], }); return (fromDir, moduleId) => { @@ -94,9 +96,17 @@ const resolveFrom = * @returns {RuleContext} */ function toRuleContext(context) { + const defaultOptions = { + debug: false, + maxDepth: 5, + }; + return { id: context.id, - options: context.options, + options: { + ...defaultOptions, + ...(context.options && context.options[0]), + }, settings: context.settings, parserPath: context.parserPath, parserOptions: context.parserOptions, @@ -111,7 +121,7 @@ function toRuleContext(context) { * @param {string} moduleId * @returns {{ ast: Node; filename: string; } | null} */ -function parse({ filename, parserPath, parserOptions }, moduleId) { +function parse({ filename, options, parserPath, parserOptions }, moduleId) { const { parseForESLint } = require(parserPath); if (typeof parseForESLint !== "function") { return null; @@ -129,8 +139,10 @@ function parse({ filename, parserPath, parserOptions }, moduleId) { }).ast, filename: modulePath, }; - } catch (_) { - /* ignore */ + } catch (e) { + if (options.debug) { + console.error(e); + } } return null; @@ -140,16 +152,16 @@ function parse({ filename, parserPath, parserOptions }, moduleId) { * Extracts exports from specified file. * @param {RuleContext} context * @param {unknown} moduleId - * @param {number=} depth + * @param {number} depth * @returns {NamedExports | null} */ -function extractExports(context, moduleId, depth = 0) { - if (depth >= MAX_DEPTH || typeof moduleId !== "string") { +function extractExports(context, moduleId, depth) { + if (depth === 0 || typeof moduleId !== "string") { return null; } const parseResult = parse(context, moduleId); - if (!parseResult?.ast) { + if (!parseResult || !parseResult.ast) { return null; } @@ -211,7 +223,7 @@ function extractExports(context, moduleId, depth = 0) { const namedExports = extractExports( { ...context, filename }, source, - depth + 1 + depth - 1 ); if (namedExports) { result.exports.push(...namedExports.exports); @@ -224,8 +236,10 @@ function extractExports(context, moduleId, depth = 0) { }, }); return result; - } catch (_) { - /* ignore */ + } catch (e) { + if (context.options.debug) { + console.error(e); + } } return null; @@ -242,14 +256,29 @@ module.exports = { url: require("../../package.json").homepage, }, fixable: "code", - schema: [], // no options + schema: [ + { + type: "object", + properties: { + debug: { + type: "boolean", + }, + maxDepth: { + type: "number", + }, + }, + additionalProperties: false, + }, + ], }, create: (context) => { + const ruleContext = toRuleContext(context); return { ExportAllDeclaration: (node) => { const result = extractExports( - toRuleContext(context), - node.source.value + ruleContext, + node.source.value, + ruleContext.options.maxDepth ); context.report({ node,