Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

v2.21 recursion error at import statement #1816

Open
fubar opened this issue Jun 10, 2020 · 7 comments
Open

v2.21 recursion error at import statement #1816

fubar opened this issue Jun 10, 2020 · 7 comments

Comments

@fubar
Copy link

fubar commented Jun 10, 2020

v2.20.2 works as expected
v2.21.2 pins the process at 100% CPU, then throws a call stack exceeded error after ~90s:

Oops! Something went wrong! :(

ESLint: 7.2.0

RangeError: Maximum call stack size exceeded
Occurred while linting (redacted)/foo.ts:5
    at Object.join (path.js:1033:7)
    at walkForTsConfig ((redacted)/node_modules/tsconfig-paths/lib/tsconfig-loader.js:56:27)
    at walkForTsConfig ((redacted)/node_modules/tsconfig-paths/lib/tsconfig-loader.js:65:12)
    at walkForTsConfig ((redacted)/node_modules/tsconfig-paths/lib/tsconfig-loader.js:65:12)
    at walkForTsConfig ((redacted)/node_modules/tsconfig-paths/lib/tsconfig-loader.js:65:12)
    at walkForTsConfig ((redacted)/node_modules/tsconfig-paths/lib/tsconfig-loader.js:65:12)
    at walkForTsConfig ((redacted)/node_modules/tsconfig-paths/lib/tsconfig-loader.js:65:12)
    at walkForTsConfig ((redacted)/node_modules/tsconfig-paths/lib/tsconfig-loader.js:65:12)
    at walkForTsConfig ((redacted)/node_modules/tsconfig-paths/lib/tsconfig-loader.js:65:12)
    at walkForTsConfig ((redacted)/node_modules/tsconfig-paths/lib/tsconfig-loader.js:65:12)

In case it helps, the reported line that it fails at (foo.ts:5) imports a default class export:

import Bar from '../lib/Bar';

which is exported as:

export default class Bar { ... }

Let me know what additional info I can provide. Thanks!

Edit: v2.21.1 has the same issue

@fubar fubar changed the title v2.21.2 recursion error at import statement v2.21 recursion error at import statement Jun 10, 2020
@ljharb
Copy link
Member

ljharb commented Jun 10, 2020

What's your tsconfig look like?

@fubar
Copy link
Author

fubar commented Jun 10, 2020

@ljharb it's a lerna repo with multiple packages that extend a shared base config:

package1/tsconfig.json:

{
  "extends": "../tsconfig.base.json",
  "include": ["src/**/*"],
  "compilerOptions": {
    "composite": true,
    "rootDir": "src",
    "outDir": "dist"
  },
  "references": [
    {
      "path": "../package2"
    }
  ]
}

package2/tsconfig.json:

{
  "extends": "../tsconfig.base.json",
  "include": ["src/**/*"],
  "compilerOptions": {
    "composite": true,
    "rootDir": "src",
    "outDir": "dist"
  }
}

tsconfig.base.json:

{
  "compilerOptions": {
    "composite": true,
    "target": "es2019",
    "module": "commonjs",
    "sourceMap": true,
    "lib": [
      "dom",
      "es7",
      "esnext.asynciterable"
    ],
    "declaration": true,
    "declarationMap": true,
    "removeComments": false,
    "strict": true,
    "strictNullChecks": true,
    "strictFunctionTypes": true,
    "strictBindCallApply": true,
    "strictPropertyInitialization": true,
    "alwaysStrict": true,
    "noUnusedLocals": true,
    "noUnusedParameters": false,
    "noFallthroughCasesInSwitch": true,
    "moduleResolution": "node",
    "baseUrl": ".",
    "paths": {
      "@foo/*": ["./*/src"],
      "*": ["../node_modules/*", "../typelibs/*.d.ts"]
    },
    "allowSyntheticDefaultImports": true,
    "esModuleInterop": true,
    "sourceRoot": "src",
    "extendedDiagnostics": true
  }
}

@ljharb
Copy link
Member

ljharb commented Jun 10, 2020

tbh it kind of sounds like tsconfig-loader is the thing that has a cycle here. We'll leave this open (because it's a regression here) but could you file an issue on that package as well?

@kevinbosman
Copy link

  1. tsconfig-loader does not support a relative cwd passed to tsConfigLoader()
  2. eslint-plugin-import first uses parserOptions.tsconfigRootDir as the cwd prop if available
  3. parserOptions.tsconfigRootDir is normally configured relative to the location of the project root
  4. So if you have tsconfigRootDir set to "." (as an example) in your eslint config, then tsconfig-loader will fail with RangeError: Maximum call stack size exceeded

Note that this is not really a tsconfig-loader problem as it cannot know what your absolute project root is, and so it relies fully on the provided cwd prop being an absolute path.

The problem could be fixed in this plugin by resolving the context.parserOptions.tsconfigRootDir path relative to the ts file currently being linted, in ExportMap.js: https://github.com/benmosher/eslint-plugin-import/blob/ff50964df1234515bc6f7969b90d87ada1982008/src/ExportMap.js#L455-L458

Alternatively:

  • Do not use "." as your tsconfigRootDir. It usually works with a subfolder name like "src" or "ts" etc.
  • Remove tsconfigRootDir completely from your config. Rather set project values to include the relative path. ExportMap will then use cwd(). However, this will fail if there is no tsconfig at or above cwd (cwd is not relative to the ts file currently being linted)
  • convert your eslintrc to js and use __dirname in the tsconfigRootDir prop.

(see also typescript-eslint/typescript-eslint#251 for further context)

@ljharb
Copy link
Member

ljharb commented Jan 16, 2021

That sounds like a reasonable fix here to account for tsconfig-loader’s limitation. Want to make a PR?

@iluminar-yi
Copy link

I'd love to make a PR to fix it because I'm having the same issue with tsconfigRootDir: '..'.

However, as I looked further into typescript-eslint/typescript-eslint#251, it seems there is no way to use purely relative path for tsconfigRootDir (users are told to use __dirname). How about throwing an error if tsconfigRootDir is '.' or '..' (and so on) and direct the user to that thread for more context? This is better than letting it overflow the stack without any context (and blocks CI pipelines, see https://github.com/team-aie/app/runs/2052152978).

That said, it would be great if I can get some pointers on where to report/throw errors in ExportMap.js, as I'm not familiar with the codebase at all. Or if there is actually a fix, let me know too.

@ljharb
Copy link
Member

ljharb commented Apr 16, 2021

That error sounds like a great idea.

I don't have an opinion on where the error should be thrown, anywhere's probably good :-)

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Development

No branches or pull requests

4 participants