fix(eslint-plugin): prefer `module` over `main` and add debug options (#809)

This commit is contained in:
Tommy Nguyen 2021-11-04 18:49:43 +01:00 коммит произвёл GitHub
Родитель 0e60942f2a
Коммит fc715196af
Не найден ключ, соответствующий данной подписи
Идентификатор ключа GPG: 4AEE18F83AFDEB23
4 изменённых файлов: 58 добавлений и 19 удалений

4
.github/workflows/pr.yml поставляемый
Просмотреть файл

@ -20,7 +20,7 @@ jobs:
uses: actions/cache@v2.1.6 uses: actions/cache@v2.1.6
with: with:
path: .yarn-offline-mirror path: .yarn-offline-mirror
key: ${{ hashFiles('yarn.lock') }} key: ${{ runner.os }}-${{ hashFiles('yarn.lock') }}
- name: Install package dependencies - name: Install package dependencies
run: yarn ci run: yarn ci
env: env:
@ -66,7 +66,7 @@ jobs:
uses: actions/cache@v2.1.6 uses: actions/cache@v2.1.6
with: with:
path: .yarn-offline-mirror path: .yarn-offline-mirror
key: ${{ hashFiles('yarn.lock') }} key: ${{ runner.os }}-${{ hashFiles('yarn.lock') }}
- name: Install package dependencies - name: Install package dependencies
run: yarn ci run: yarn ci
- name: Build and test packages - name: Build and test packages

Просмотреть файл

@ -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"
}

Просмотреть файл

@ -50,6 +50,9 @@
"prettier": "^2.3.0", "prettier": "^2.3.0",
"suggestion-bot": "^1.2.2" "suggestion-bot": "^1.2.2"
}, },
"engines": {
"node": ">=14.15"
},
"resolutions": { "resolutions": {
"micromatch": "^4.0.0" "micromatch": "^4.0.0"
}, },

Просмотреть файл

@ -8,7 +8,10 @@
* *
* @typedef {{ * @typedef {{
* id: ESLintRuleContext["id"]; * id: ESLintRuleContext["id"];
* options: ESLintRuleContext["options"]; * options: {
* debug: boolean;
* maxDepth: number;
* };
* settings: ESLintRuleContext["settings"]; * settings: ESLintRuleContext["settings"];
* parserPath: ESLintRuleContext["parserPath"]; * parserPath: ESLintRuleContext["parserPath"];
* parserOptions: ESLintRuleContext["parserOptions"]; * parserOptions: ESLintRuleContext["parserOptions"];
@ -33,8 +36,6 @@ const DEFAULT_CONFIG = {
eslintScopeManager: true, eslintScopeManager: true,
}; };
const MAX_DEPTH = 5;
/** /**
* Returns whether there are any named exports. * Returns whether there are any named exports.
* @param {NamedExports?} namedExports * @param {NamedExports?} namedExports
@ -74,6 +75,7 @@ const resolveFrom =
const resolve = require("enhanced-resolve").create.sync({ const resolve = require("enhanced-resolve").create.sync({
extensions: [".ts", ".tsx", ".js", ".jsx"], extensions: [".ts", ".tsx", ".js", ".jsx"],
mainFields: ["module", "main"],
}); });
return (fromDir, moduleId) => { return (fromDir, moduleId) => {
@ -94,9 +96,17 @@ const resolveFrom =
* @returns {RuleContext} * @returns {RuleContext}
*/ */
function toRuleContext(context) { function toRuleContext(context) {
const defaultOptions = {
debug: false,
maxDepth: 5,
};
return { return {
id: context.id, id: context.id,
options: context.options, options: {
...defaultOptions,
...(context.options && context.options[0]),
},
settings: context.settings, settings: context.settings,
parserPath: context.parserPath, parserPath: context.parserPath,
parserOptions: context.parserOptions, parserOptions: context.parserOptions,
@ -111,7 +121,7 @@ function toRuleContext(context) {
* @param {string} moduleId * @param {string} moduleId
* @returns {{ ast: Node; filename: string; } | null} * @returns {{ ast: Node; filename: string; } | null}
*/ */
function parse({ filename, parserPath, parserOptions }, moduleId) { function parse({ filename, options, parserPath, parserOptions }, moduleId) {
const { parseForESLint } = require(parserPath); const { parseForESLint } = require(parserPath);
if (typeof parseForESLint !== "function") { if (typeof parseForESLint !== "function") {
return null; return null;
@ -129,8 +139,10 @@ function parse({ filename, parserPath, parserOptions }, moduleId) {
}).ast, }).ast,
filename: modulePath, filename: modulePath,
}; };
} catch (_) { } catch (e) {
/* ignore */ if (options.debug) {
console.error(e);
}
} }
return null; return null;
@ -140,16 +152,16 @@ function parse({ filename, parserPath, parserOptions }, moduleId) {
* Extracts exports from specified file. * Extracts exports from specified file.
* @param {RuleContext} context * @param {RuleContext} context
* @param {unknown} moduleId * @param {unknown} moduleId
* @param {number=} depth * @param {number} depth
* @returns {NamedExports | null} * @returns {NamedExports | null}
*/ */
function extractExports(context, moduleId, depth = 0) { function extractExports(context, moduleId, depth) {
if (depth >= MAX_DEPTH || typeof moduleId !== "string") { if (depth === 0 || typeof moduleId !== "string") {
return null; return null;
} }
const parseResult = parse(context, moduleId); const parseResult = parse(context, moduleId);
if (!parseResult?.ast) { if (!parseResult || !parseResult.ast) {
return null; return null;
} }
@ -211,7 +223,7 @@ function extractExports(context, moduleId, depth = 0) {
const namedExports = extractExports( const namedExports = extractExports(
{ ...context, filename }, { ...context, filename },
source, source,
depth + 1 depth - 1
); );
if (namedExports) { if (namedExports) {
result.exports.push(...namedExports.exports); result.exports.push(...namedExports.exports);
@ -224,8 +236,10 @@ function extractExports(context, moduleId, depth = 0) {
}, },
}); });
return result; return result;
} catch (_) { } catch (e) {
/* ignore */ if (context.options.debug) {
console.error(e);
}
} }
return null; return null;
@ -242,14 +256,29 @@ module.exports = {
url: require("../../package.json").homepage, url: require("../../package.json").homepage,
}, },
fixable: "code", fixable: "code",
schema: [], // no options schema: [
{
type: "object",
properties: {
debug: {
type: "boolean",
},
maxDepth: {
type: "number",
},
},
additionalProperties: false,
},
],
}, },
create: (context) => { create: (context) => {
const ruleContext = toRuleContext(context);
return { return {
ExportAllDeclaration: (node) => { ExportAllDeclaration: (node) => {
const result = extractExports( const result = extractExports(
toRuleContext(context), ruleContext,
node.source.value node.source.value,
ruleContext.options.maxDepth
); );
context.report({ context.report({
node, node,