-
-
Notifications
You must be signed in to change notification settings - Fork 2.8k
Using references makes eslint lint compiled files instead of original typescript files #1573
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
Comments
Could you please provide some more information. Could you please provide a repro? |
It's not a specific error message, it has errors from all kind of different rules, so I guess the exact error message I'm getting shouldn't matter. It just lints the js file instead of the ts file and all the errors return match exactly the js file. I logged the output of the function I mentioned above (https://github.com/typescript-eslint/typescript-eslint/blob/master/packages/typescript-estree/src/create-program/createIsolatedProgram.ts#L45) and it shows me the source code of the compiled js file with the file path of the ts file in the ast returned by typescript.
Any code, it's a big repository and any typescript file failed because the equivalent js file is linted.
{
"compilerOptions": {
"allowJs": true,
"allowSyntheticDefaultImports": true,
"baseUrl": ".",
"esModuleInterop": true,
"experimentalDecorators": true,
"forceConsistentCasingInFileNames": true,
"incremental": true,
"isolatedModules": true,
"jsx": "preserve",
"lib": [
"dom",
"dom.iterable",
"esnext"
],
"module": "commonjs",
"moduleResolution": "node",
"outDir": "./dist",
"resolveJsonModule": true,
"rootDir": "./src",
"skipLibCheck": true,
"sourceMap": true,
"strict": true,
"target": "ESNext"
},
"exclude": ["src/modules/*/dist"],
"include": [
"src/**/*"
],
"references": [
{
"path": "<REFERENCE_1>"
},
{
"path": "<REFERENCE_2>"
}
]
} and the referenced tsconfig.json files look like this: {
"extends": "../../../tsconfig.json",
"compilerOptions": {
"noEmit": false,
"rootDir": "../..",
"composite": true,
"incremental": true,
"outDir": "./dist"
},
"include": [
"**/*"
]
} I can provide a sample repository but it'll take time, please let me know if above information aren't enough and the repository is needed. |
What about your eslint config? |
This is my eslint config: const process = require('process');
const typescriptOverride = {
extends: [
'plugin:@typescript-eslint/recommended',
'plugin:import/errors',
'plugin:import/warnings',
'plugin:import/typescript',
],
files: ['*.ts', '*.tsx'],
rules: {
'@typescript-eslint/explicit-function-return-type': 'error',
'@typescript-eslint/explicit-member-accessibility': 'error',
'@typescript-eslint/indent': ['error', 2],
'@typescript-eslint/no-empty-function': 'off',
'@typescript-eslint/no-explicit-any': 'off',
'@typescript-eslint/no-non-null-assertion': 'off',
'@typescript-eslint/no-unused-vars': [
'warn',
{ignoreRestSiblings: true, varsIgnorePattern: '^_'},
],
'@typescript-eslint/no-use-before-define': 'off',
'import/no-unresolved': 'off',
},
};
module.exports = {
env: {
browser: true,
es6: true,
},
extends: [
'plugin:react/recommended',
'plugin:jsx-a11y/strict',
],
globals: {
Atomics: 'readonly',
SharedArrayBuffer: 'readonly',
},
overrides: [
typescriptOverride,
{
files: ['*.js', '*.jsx'],
parserOptions: {
ecmaVersion: 2018,
project: [],
sourceType: 'commonjs',
},
rules: {
'global-require': 'off',
'no-process-exit': 'off',
strict: 'off',
},
},
],
parser: '@typescript-eslint/parser',
parserOptions: {
ecmaFeatures: {
jsx: true,
},
ecmaVersion: 2018,
project: [
'./tsconfig.json',
'./<REFERENCE_1>/tsconfig.json',
'./<REFERENCE_2>/tsconfig.json',
],
sourceType: 'module',
},
plugins: [
'react',
'@typescript-eslint',
'import',
'sort-keys-fix',
'jsx-a11y',
],
rules: {
'accessor-pairs': 'error',
'array-bracket-newline': 'error',
'array-bracket-spacing': 'error',
'array-callback-return': 'error',
'arrow-body-style': 'error',
'arrow-parens': 'error',
'arrow-spacing': 'error',
'block-scoped-var': 'error',
'block-spacing': 'error',
'brace-style': ['error', 'stroustrup'],
'callback-return': 'error',
camelcase: 'error',
'capitalized-comments': 'off',
'class-methods-use-this': 'error',
'comma-dangle': [
'error',
'always-multiline',
],
'comma-spacing': 'error',
'comma-style': 'error',
complexity: ['error', 25],
'computed-property-spacing': 'error',
'consistent-return': 'error',
'consistent-this': 'error',
curly: 'error',
'default-case': 'error',
'dot-location': ['error', 'property'],
'dot-notation': 'error',
'eol-last': 'error',
eqeqeq: 'error',
'func-name-matching': 'error',
'func-names': 'error',
'generator-star-spacing': 'error',
'global-require': 'error',
'guard-for-in': 'error',
'handle-callback-err': 'error',
'id-blacklist': 'error',
'id-length': 'error',
'id-match': 'error',
'implicit-arrow-linebreak': 'error',
'import/order': [
'error',
{
alphabetize: {order: 'asc'},
groups: ['builtin', 'external', 'internal', 'parent', 'sibling', 'index'],
'newlines-between': 'always',
},
],
'jsx-a11y/label-has-associated-control': [
'error',
{
assert: 'either',
controlComponents: ['Input'],
},
],
'jsx-a11y/label-has-for': 'off',
'jsx-quotes': [
'error',
'prefer-single',
],
'key-spacing': 'error',
'keyword-spacing': 'error',
'line-comment-position': 'error',
'linebreak-style': [
'error',
'unix',
],
'lines-around-directive': 'error',
'lines-between-class-members': 'error',
'max-classes-per-file': 'error',
'max-depth': 'error',
'max-len': ['error', 120],
'max-nested-callbacks': 'error',
'max-params': 'error',
'max-statements': ['error', 25],
'max-statements-per-line': 'error',
'new-cap': 'error',
'new-parens': 'error',
'newline-after-var': 'error',
'newline-before-return': 'error',
'newline-per-chained-call': ['error', {ignoreChainWithDepth: 3}],
'no-alert': 'error',
'no-array-constructor': 'error',
'no-async-promise-executor': 'error',
'no-await-in-loop': 'error',
'no-bitwise': 'error',
'no-buffer-constructor': 'error',
'no-caller': 'error',
'no-catch-shadow': 'error',
'no-continue': 'error',
'no-div-regex': 'error',
'no-duplicate-imports': 'error',
'no-empty-function': 'off',
'no-eq-null': 'error',
'no-eval': 'error',
'no-extend-native': 'error',
'no-extra-bind': 'error',
'no-extra-label': 'error',
'no-floating-decimal': 'error',
'no-implicit-coercion': 'error',
'no-implicit-globals': 'error',
'no-implied-eval': 'error',
'no-inline-comments': 'off',
'no-invalid-this': 'error',
'no-iterator': 'error',
'no-label-var': 'error',
'no-labels': 'error',
'no-lone-blocks': 'error',
'no-lonely-if': 'error',
'no-loop-func': 'error',
'no-misleading-character-class': 'error',
'no-mixed-operators': 'error',
'no-mixed-requires': 'error',
'no-multi-assign': 'error',
'no-multi-spaces': 'error',
'no-multiple-empty-lines': 'error',
'no-native-reassign': 'error',
'no-negated-condition': 'error',
'no-negated-in-lhs': 'error',
'no-new': 'error',
'no-new-func': 'error',
'no-new-object': 'error',
'no-new-require': 'error',
'no-new-wrappers': 'error',
'no-octal-escape': 'error',
'no-param-reassign': 'error',
'no-path-concat': 'error',
'no-plusplus': 'error',
'no-process-exit': 'error',
'no-proto': 'error',
'no-prototype-builtins': 'error',
'no-restricted-globals': 'error',
'no-restricted-imports': 'error',
'no-restricted-modules': 'error',
'no-restricted-properties': 'error',
'no-restricted-syntax': 'error',
'no-return-assign': 'error',
'no-return-await': 'error',
'no-script-url': 'error',
'no-self-compare': 'error',
'no-sequences': 'error',
'no-shadow': 'error',
'no-shadow-restricted-names': 'error',
'no-tabs': 'error',
'no-template-curly-in-string': 'error',
'no-throw-literal': 'error',
'no-trailing-spaces': 'error',
'no-undef-init': 'error',
'no-undefined': 'off',
'no-unmodified-loop-condition': 'error',
'no-unneeded-ternary': 'error',
'no-unused-expressions': 'error',
'no-use-before-define': 'off',
'no-useless-call': 'error',
'no-useless-catch': 'error',
'no-useless-computed-key': 'error',
'no-useless-concat': 'error',
'no-useless-constructor': 'error',
'no-useless-rename': 'error',
'no-useless-return': 'error',
'no-var': 'error',
'no-void': 'error',
'no-warning-comments': process.env.CI ? 'off' : 'warn',
'no-whitespace-before-property': 'error',
'no-with': 'error',
'nonblock-statement-body-position': 'error',
'object-curly-newline': 'error',
'object-curly-spacing': 'error',
'object-shorthand': 'error',
'one-var-declaration-per-line': 'error',
'operator-assignment': 'error',
'operator-linebreak': 'error',
'padded-blocks': 'off',
'padding-line-between-statements': 'error',
'prefer-arrow-callback': 'error',
'prefer-const': 'error',
'prefer-destructuring': 'error',
'prefer-numeric-literals': 'error',
'prefer-object-spread': 'error',
'prefer-promise-reject-errors': 'error',
'prefer-reflect': 'error',
'prefer-rest-params': 'error',
'prefer-spread': 'error',
'prefer-template': 'error',
'quote-props': [
'error',
'as-needed',
],
quotes: [
'error',
'single',
{allowTemplateLiterals: true},
],
radix: 'error',
'react/display-name': 'off',
'react/jsx-curly-newline': ['error', {multiline: 'forbid'}],
'react/jsx-sort-props': [
'error',
{
callbacksLast: true,
ignoreCase: true,
reservedFirst: true,
shorthandLast: true,
},
],
'react/jsx-tag-spacing': [
'error',
{
afterOpening: 'never',
beforeClosing: 'never',
beforeSelfClosing: 'always',
closingSlash: 'never',
},
],
'react/jsx-wrap-multilines': [
'error',
{
arrow: 'parens-new-line',
assignment: 'parens-new-line',
condition: 'ignore',
declaration: 'parens-new-line',
logical: 'ignore',
prop: 'ignore',
return: 'parens-new-line',
},
],
'react/no-array-index-key': 'error',
'require-atomic-updates': 'error',
'require-await': 'error',
'require-unicode-regexp': 'error',
'rest-spread-spacing': 'error',
semi: 'error',
'semi-spacing': 'error',
'semi-style': [
'error',
'last',
],
'sort-keys-fix/sort-keys-fix': 'error',
'space-before-blocks': 'error',
'space-before-function-paren': 'off',
'space-in-parens': [
'error',
'never',
],
'space-infix-ops': 'error',
'space-unary-ops': 'error',
'spaced-comment': ['error', 'always', {markers: ['/']}],
strict: 'error',
'switch-colon-spacing': 'error',
'symbol-description': 'error',
'template-curly-spacing': 'error',
'template-tag-spacing': 'error',
'unicode-bom': [
'error',
'never',
],
'valid-jsdoc': 'error',
'vars-on-top': 'error',
'wrap-iife': 'error',
'wrap-regex': 'error',
'yield-star-spacing': 'error',
yoda: 'error',
},
settings: {
'import/resolver': 'babel-module',
react: {
version: 'detect',
},
},
}; |
I run eslint with |
Looking at your eslint config, you've got Note that we don't use project references at all. We do not resolve them ourselves (we don't even look at your tsconfig contents). The typescript APIs that we use should not resolve or use them them either (unless they've changed). The only code that should be parsed is what is matched by your You have |
I understand that it's happening in typescript and is not related to this project, so probably I should create an issue in typescript repository. |
I was able to solve the issue by narrowing |
Actually it's not resolved, the problem is that when a file is in another typescript project referenced in
You're right, at the time I was debugging it the settings were different, now that |
And I noticed it's not the js files, but it's |
Another note is that you're using the recommended configs for eslint-plugin-import, which has some rules we do not recommend. See the above linked FAQ for more info. Also note that our parser will parse all files covered by your tsconfigs (if you provide Eslint asks for whatever files are matched by the globs you pass to the CLI that aren't matched by your eslintignore file. The only smarts eslint does is to auto ignore node_modules. If you do something like |
Thanks for quick responses Brad. I'm running eslint on a single file currently and I do have build directories in I think I found the issue, we need to pass |
That option is used here: https://github.com/microsoft/TypeScript/blob/master/src/compiler/program.ts#L2311 |
I suspect that there's something else at work here. If you could provide a repro repo, I could help look into this. We do not want to resolve project references in our parser. We maintain one ts program for each tsconfig passed in |
Yes it's indeed lighter but it doesn't have the same ast (and even if it had the same ast it doesn't have the same location for each node in the ast) typescript-eslint needs to lint the real source file not the |
Sorry, this is what I'm trying to say though - if you are doing
This is why I'm so confused:
|
Based on the inspections I've done (with help of I guess I'm bothering you with this discussion without enough evidence, so please wait I find some time to provide a reproduction repository. It may be that I have an obvious mistake in my setup. |
@bradzacher Reproduction: git clone git@github.com:sassanh/typescript-eslint-1573-reproduction.git
cd typescript-eslint-1573-reproduction/
yarn install
node_modules/.bin/eslint reference/b.ts # It works as expected
node_modules/.bin/tsc --build
node_modules/.bin/eslint reference/b.ts # Now it doesn't work, it's linting `reference/dist/b.d.ts`
rm -rf reference/dist
node_modules/.bin/eslint reference/b.ts # It works again |
Until someone notices microsoft/TypeScript#36655 among 4K issues in that repository or we find time to provide a PR, if you can think of a workaround I'd appreciate if you share it here. |
Hmm. I've spent a bit of time looking into it and this is indeed a bug The problem is because of this block of code. When the project references are nested, then
Which then causes TS to set this mapping up in the internal source file cache. Then when we ask for We check the projects in the order that you provide them in your eslint config. We haven't run into it because when people use project references, they have a different folder structure. Your folder structure is this:
With
In my testing, I made this adjustment to your repro, and it worked fine when I did this. I can submit a "fix" for this locally. |
Thanks! I'm glad I can eventually lint my files, I really appreciate your quick responses and your help. |
What did you expect to happen?
Eslint to lint my code.
What actually happened?
Eslint lints compiled js files and reports the errors to the original typescript file. I noticed it when I saw eslint is giving errors at location that doesn't exist in the typescript file and I checked the compiled js files and noticed these errors are for the js file.
Versions
@typescript-eslint/typescript-estree
2.19.0
TypeScript
3.7.4
node
12.11.1
npm
6.11.3
I traced the issue to this line https://github.com/typescript-eslint/typescript-eslint/blob/master/packages/typescript-estree/src/create-program/createIsolatedProgram.ts#L45 here the source code returned by typescript is the compiled js file, it happens when I'm using references and when the files are compiled, if I remove
dist
directories, eslint will start working as expected but as soon as I compile again, eslint starts giving errors of compiled js files on ts files.The text was updated successfully, but these errors were encountered: