import-js / eslint-plugin-import

ESLint plugin with rules that help validate proper imports.

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

import plugin breaking in nx based mono-repo

rishavpandey43 opened this issue · comments

I have been encountering a weird issue.

I have a react+typescript based project it was working fine.

Now, I migrated everything to nx-based mono-repo, and I'm getting the following error -

   Maximum call stack size exceeded

   Occurred while linting /Users/rishavpandey/Professional Work/Skuad/skuad-fe/apps/pay-platform/src/App.tsx:2
   Rule: "import/namespace

These are imports in App.tsx -

import { useEffect } from 'react';
import { datadogRum } from '@datadog/browser-rum';

import HeaderSidebarWrapper from '@pay/old/components/HeaderSidebarWrapper';
import useGetConfig from '@pay/old/hooks/useGetConfig/useGetConfig';
import {
  Accessors,
  ConfigType,
} from '@pay/old/queries/graphql/types/coreTypes';
import useSetMixPanelUserId from '@pay/old/hooks/useSetMixPanelUserId';
import useTrackPageViews from '@pay/old/hooks/useTrackPageViews';
import { ContractContextProvider } from '@pay/old/contextData/contractCreationContext';
import { setGaUserSession } from '@pay/old/hooks/useGoogleAnalytics';
import useClarity from '@pay/old/hooks/useClarity';
import { useMainContext } from '@pay/contexts/MainContextProvider';
import { useContextState } from '@pay/old/contextData/mainAppContext';

import MainRouter from './router';

This is my current eslintrc config the internal app-

apps/pay-platform/.eslintrc.js -

const dotenv = require('dotenv');
dotenv.config();

module.exports = {
  root: true,
  parserOptions: {
    project: 'apps/pay-platform/tsconfig.*?.json',
  },
  plugins: ['react', 'import', 'jsx-a11y', 'graphql'],
  extends: [
    'plugin:react/recommended',
    'plugin:react-hooks/recommended',
    // 'plugin:import/recommended',
    // 'plugin:import/typescript',
    'plugin:jsx-a11y/recommended',
    '../../.eslintrc.js',
  ],
  settings: {
    react: {
      version: 'detect',
    },
    // 'import/resolver': {
    //   typescript: {
    //     alwaysTryTypes: true,
    //     project: './tsconfig.*?.json',
    //   },
    //   node: {
    //     extensions: [',.js', ',.jsx', ',.ts', ',.tsx'],
    //   },
    // },
  },
  rules: {
    // // *** Import Rules ***
    // 'import/no-named-as-default-member': 'error', // * Stricter than default
    // 'import/no-named-as-default': 'error', // * Stricter than default
    // 'import/no-duplicates': 'error', // * Stricter than default
    'import/order': [
      'error',
      {
        groups: [
          'builtin',
          'external',
          'internal',
          'parent',
          'sibling',
          'index',
        ],
        pathGroups: [
          {
            pattern: '@pay/**',
            group: 'internal',
            position: 'before',
          },
        ],
        'newlines-between': 'always',
      },
    ],
  },
  overrides: [],
};

As soon as I comment on anything related to the import plugin, Eslint will break.

The same config was working fine in an earlier standalone project, but now it's failing.

This is root level eslint config -

const tsNamingConvention = require('./ts-naming-convention');

module.exports = {
  root: true,
  parser: '@typescript-eslint/parser',
  parserOptions: {
    ecmaVersion: 2020,
    sourceType: 'module',
    project: ['./tsconfig.base.json'],
    tsconfigRootDir: '.',
    lib: ['dom', 'esnext'],
    ecmaFeatures: {
      jsx: true,
    },
  },
  plugins: ['@nx', 'prettier', '@typescript-eslint'],
  extends: [
    'eslint:recommended',
    'plugin:@nx/typescript',
    'plugin:@nx/javascript',
    'plugin:@typescript-eslint/recommended',
    'plugin:prettier/recommended',
    'prettier', // Ensure "prettier" is last
  ],
  env: {
    browser: true,
    node: true,
    es6: true,
  },
  globals: {
    document: true,
    window: true,
    location: true,
    fetch: true,
  },
  ignorePatterns: [
    'node_modules/',
    'dist/',
    '**/*.spec.ts',
    '**/*.generated.tsx',
    '**/*.generated.ts',
    '**/*.coreTypes.ts',
    '**/*.cmsTypes.ts',
  ],
  rules: {
    // *** ESLint Recommended Rules with Stricter Settings ***
    eqeqeq: 'error', // Enforce strict equality.
    'array-callback-return': 'error', // Ensure a return statement in array callbacks.
    'no-sequences': 'error', // Disallow comma operator.
    'no-useless-concat': 'error', // Disallow unnecessary concatenation.
    'no-redeclare': 'error', // Disallow variable redeclaration.
    'no-lone-blocks': 'error', // Disallow unnecessary nested blocks.
    'no-extra-boolean-cast': 'error', // Disallow unnecessary boolean casts.
    'no-unexpected-multiline': 'error', // Disallow confusing multiline expressions.
    'no-var': 'error', // Require let or const instead of var.
    'prefer-spread': 'error', // Suggest using spread syntax instead of .apply().
    'prefer-rest-params': 'error', // Suggest using rest parameters instead of arguments.
    'no-console': ['error', { allow: ['warn', 'error'] }], // Disallow console logs.
    'max-lines': [
      'warn',
      { max: 500, skipComments: true, skipBlankLines: true },
    ],

    // *** General JavaScript Rules ***
    'no-template-curly-in-string': 'error', // Disallow template literal placeholder syntax in regular strings.
    'no-restricted-globals': 'error', // Disallow specified global variables.

    // *** Naming Convention Rules ***
    '@typescript-eslint/naming-convention': tsNamingConvention,
  },
  overrides: [
    {
      files: ['*.ts', '*.tsx', '*.js', '*.jsx'],
      rules: {
        '@nx/enforce-module-boundaries': [
          'error',
          {
            enforceBuildableLibDependency: true,
            allow: [],
            depConstraints: [
              {
                sourceTag: '*',
                onlyDependOnLibsWithTags: ['*'],
              },
            ],
          },
        ],
      },
    },
  ],
};

You do need those import/resolver settings.

Still, there is the same issue.
Btw in my standalone app, I needed settings for import/resolver so that it identifies absolute import path definitions like @pay.

In the standalone app, everything is perfect, even --fix is working for import/order but here its breaking.

What version of eslint and this plugin are you using?

It would be most helpful if you could create a minimal repro repo - I realize this is a tough ask.

    "@typescript-eslint/eslint-plugin": "^6.2.1",
    "@typescript-eslint/parser": "^6.2.1",
    "eslint": "^8.56.0",
    "eslint-config-prettier": "^9.1.0",
    "eslint-import-resolver-typescript": "^3.6.1",
    "eslint-plugin-graphql": "^4.0.0",
    "eslint-plugin-import": "^2.29.1",
    "eslint-plugin-jsx-a11y": "^6.8.0",
    "eslint-plugin-prettier": "^5.0.0",
    "eslint-plugin-react": "^7.34.1",
    "eslint-plugin-react-hooks": "^4.6.2",
    "eslint-plugin-redux": "^0.1.0",
    "eslint-plugin-redux-saga": "^1.3.2",
    "eslint-plugin-cypress": "^2.13.4",
    "eslint-plugin-unused-imports": "^2.0.0",

I tried adding off for a few rules 'import/namespace': 'off', 'import/default': 'off', but then it's breaking for another one.

only import/order is working.

Do I need to make extra changes since this is mono-repo?

I found these tips https://nx.dev/recipes/tips-n-tricks/eslint on nx, on how to use tsconfig.json in eslint which is not commonly done in a standalone app, but even after this import plugin is breaking.

Also, I remembered, import/resolver is necessary when creating path aliasing, Otherwise you will get error of Unable to resolve path to module '@pay/old/hooks/useGetConfig/useGetConfig'.eslint[import/no-unresolved](https://github.com/import-js/eslint-plugin-import/blob/v2.29.1/docs/rules/no-unresolved.md)

Let me try creating a test app, I'll have to create several dummy files/folders with code to ensure we solve the problem correctly.