import-js/eslint-plugin-import

AST analysis cannot be performed with a properly configured parser when the imported file type is inconsistent with the current lint file type

Open

#2,719 建立於 2023年2月16日

在 GitHub 查看
 (12 留言) (1 反應) (0 負責人)JavaScript (4,946 star) (1,540 fork)batch import
bughelp wanted

描述

AST analysis cannot be performed with a properly configured parser when the imported file type is inconsistent with the current lint file type

index.ts

import foo from 'foo.js';
import bar from 'bar.ts';

index.ts is the file I want to lint, It imports a js file and a ts file respectively

.eslintrc.js

module.exports =  {
  plugins: ['import'],
  settings: {
    'import/resolver': [
      require.resolve('eslint-import-resolver-typescript'),
      require.resolve('eslint-import-resolver-node'),
    ],
    'import/extensions':['.js', '.jsx', '.ts', '.tsx'],
    'import/parsers': {
      [require.resolve('@typescript-eslint/parser')]: ['.ts', '.tsx'],
      [require.resolve('@babel/eslint-parser')]: ['.js', 'jsx'],
    },
    },
  },
  rules: {
    'import/no-cycle': 1,
  },
  overrides: [
    {
      files: ['*.ts', '*.tsx'],
      parser: require.resolve('@typescript-eslint/parser'),
      parserOptions: tsParserOptions,
    },
    {
      files: ['*.js', '*.jsx'],
      parser: require.resolve('@babel/eslint-parser'),
      parserOptions: jsParserOptions,
    },
  ],
}

@typescript-eslint/parser is used on index.ts when linting, but it is still used in imported foo.js even though my intention is to use @babel/eslint-parser. This may result in the following error

Error while xxx/foo.js
Line 24, column 24: Property or signature expected.
`parseForESLint` from parser `xxx/node_modules/@typescript-eslint/parser/dist/index.js` is invalid and will just be ignored

I found out that the root cause is in src/ExportMap.js

function childContext(path, context) {
  const { settings, parserOptions, parserPath } = context;
  return {
    settings,
    parserOptions,
    parserPath,
    path,
  };
}

Because the parser is only obtained based on the first lint file, and cannot be replaced dynamically later

In the future, is it considered to support the dynamic use of the configured parser according to the type of file to be parsed? Can it also support dynamic parser options?

for example:

function childContext(path, context) {
  let {
    settings,
    parserOptions: finalParserOptions,
    parserPath: finalParserPath,
  } = context;
  const parsers = settings['import/parsers'];
  const parserOptions = settings['import/parser-options'];
  if (parsers != null) {
    const extension = _path.extname(path);
    for (const p in parsers) {
      if (parsers[p].indexOf(extension) > -1) {
        finalParserPath = p;
        if (parserOptions != null && parserOptions[p] != null) {
          finalParserOptions = parserOptions[p]
        }
        break;
      }
    }
  }
  return {
    settings,
    parserOptions: finalParserOptions,
    parserPath: finalParserPath,
    path,
  };
} 

eslintrc.js

const tsParserOptions = {
  ecmaFeatures: {
    jsx: true,
    generators: false,
    globalReturn: false,
  },
  sourceType: 'module',
  ecmaVersion: 9,
};

const jsParserOptions = {
  requireConfigFile: false,
  ecmaVersion: 9,
  babelOptions: {
    plugins: [
      '@babel/plugin-transform-react-jsx',
      '@babel/plugin-syntax-flow',
      [
        '@babel/plugin-proposal-decorators',
        {
          decoratorsBeforeExport: true,
          legacy: false,
        },
      ],
    ],
  },
};

module.exports =  {
  plugins: ['import'],
  settings: {
    'import/resolver': [
      require.resolve('eslint-import-resolver-typescript'),
      require.resolve('eslint-import-resolver-node'),
    ],
    'import/extensions':['.js', '.jsx', '.ts', '.tsx'],
    'import/parsers': {
      [require.resolve('@typescript-eslint/parser')]: ['.ts', '.tsx'],
      [require.resolve('@babel/eslint-parser')]: ['.js', 'jsx'],
    },
    /**
     * Added configuration option
     */
    'import/parser-options': {
      [require.resolve('@typescript-eslint/parser')]: tsParserOptions,
      [require.resolve('@babel/eslint-parser')]: jsParserOptions,
    },
  },
  overrides: [
    {
      files: ['*.ts', '*.tsx'],
      parser: require.resolve('@typescript-eslint/parser'),
      parserOptions: tsParserOptions,
    },
    {
      files: ['*.js', '*.jsx'],
      parser: require.resolve('@babel/eslint-parser'),
      parserOptions: jsParserOptions,
    },
  ],
};

貢獻者指南

AST analysis cannot be performed with a properly configured parser when the imported file type is inconsistent with the current lint file type · import-js/eslint-plugin-import#2719 | Good First Issue