-
-
Notifications
You must be signed in to change notification settings - Fork 2.7k
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
Symlinks cause parserOptions.project errors #2987
Comments
We build on top of TypeScript and eslint, and we delegate all file reading to those packages. I haven't looked into it, but I don't know it there's much we can do without reading from disk and attempting to pre-empt what TS is doing to normalise the file paths. Attempting to encode knowledge about how TS/ESLint handle symlinks is also a recipe for disaster when TS releases a new version or ESLint releases a major. Additionally disk reads aren't cheap so IDK if it's a great idea to just build into the regular flow. Symlinks are also a pretty rare usecase in the community (hence this is the first time someone has reported this), so I'm not sure how much effort is worth putting into this. I'd be looking for a champion to work on this, as I don't have the time to look into this niche of an issue (similar to vue support - vuejs/eslint-plugin-vue#1296) |
Unfortunately I don't really know any of the technologies very well, otherwise I may have dug into it a bit further. I'm currently more inclined to try and structure my project a bit differently instead to work around the issue. I did notice though that TS seems to have some symlink functionality built in, as |
i'm going to look into this |
i have few news about this issue, and this seem to be caused by our normalization of paths <- that was a fix introduced to fix issues with editors i can confirm that i can reproduce this issue on linux |
any workarounds possible? |
I discovered this because we have a monorepo (@nrwl/nx) containing a legacy app among other things. We decided to make our libraries "buildable" and import transpiled code instead. This got us around the issue even though we still use symlinks, since we have set up eslint to ignore the transpiled code. |
I was experiencing this as well, and finally came across a solution. Basically, we need to compare The gist is: /*** ./config/utils/Files.js ***/
const fs = require('fs');
const path = require('path');
const childProcess = require('child_process');
/*
* Fix paths to use the path of the current process' directory if it's within a symlinked path.
* Otherwise, IDEs may have trouble with automatic resolutions for ESLint, file paths, etc.
*
* Short summary:
* - process.cwd() == `npm prefix` - Doesn't preserve symlinks
* - process.env.PWD == `pwd` - Preserves symlinks
* - fs.realpathSync(process.env.PWD) == `realpath $(pwd)` - Doesn't preserve symlinks
*/
// Root directory of repository - absolute path without preserving symlinks
// You could use your own logic here, this was my choice so the root dir was always the same regardless
// of where a script/process was run
const realPath = path.resolve(
childProcess
.execSync('npm prefix')
.toString()
.replace(/\n/g, '')
);
// Root dir preserving symlinks + current process' path (e.g. if in a nested directory from the root)
const currentProcessPath = process.env.PWD;
// Only the nested directory, used for diffing any (non-)symlink-preserving path (nested or not) with
// the repo root in order to convert PWD to the root dir
const currentProcessNestedPath = fs.realpathSync(currentProcessPath).replace(realPath, '');
// Root dir preserving symlinks without the nested directory
const rootDirMaintainingSymlinks = currentProcessPath.replace(currentProcessNestedPath, '');
// Final constant for use in other files
export const rootDir = rootDirMaintainingSymlinks;
// Now to resolve the tsconfig.json
export const tsconfigPath = path.resolve(rootDir, 'tsconfig.json');
/*** ./.eslintrc.js ***/
const {
rootDir,
tsconfigPath,
} = require('./config/utils/Files');
module.exports = {
parser: '@typescript-eslint/parser',
parserOptions: {
// Set the root directory of the repo - now preserving symlinks
tsconfigRootDir: rootDir,
// Path of tsconfig.json - now preserving symlinks
project: tsconfigPath,
// ...
},
// ...
}; Tested on Linux Mint Uma 20.2. |
Following this discussion, I think this will fix the issue, Change typescript-eslint/packages/typescript-estree/src/create-program/createProjectProgram.ts Line 26 in da48527
to
|
Isn't this fix (@gutenye) not yet the part of current release? |
Any news on this issue? |
Not only Eslint, Many of the built-ins (eg: Git changes feature will not work as expected on symlinked dirs - try checking it out) and custom plugins of vscode fails to work along with symlinked dirs, so I suggest you to find a way to work without sym-linking, I wasted plethora of time looking for a fix, as mentioned in this thread, if I write fix for one plugin (like Eslint) the same issue will arise in other plugins as well.. since this is never ending loop and all the plugins were relatively referenced this causes error while resolving symbolic links, changing our dev flow is the only fix right now, since we can't write patch like this for every plugin which has this issue. |
Oh, so issue stems from VS Code? Not ESLint itself? @ThayalanGR Edit: |
No, it is not stems from vscode, both having this symlink issue in common. |
issue had to do with opening the project from a symlink Related: typescript-eslint/typescript-eslint#2987
* await creating the default list * for completeness: also assert organization * lint for await * ooops - put the eslint config for ts in the right place * eslint should ignore .mailing directories * add tsconfig's to parserOptions.project in @typescript-eslint/parser block * await async functions * don't ignore __test__ from tsconfig in core * linter says that this expect must be awaited * tsconfig covers all the .ts files in the root directory: jest.config.ts testSetup.integration.ts testUtilIntegration.ts jest.integration.config.ts testSetup.ts * tsconfig should include e2e/**/* * src/cli/generator_templates/**/* is not a directory in packages/cli * await some async functions * we're using plain js in e2e/mailing_tests so don't need a tsconfig * fix typo * await analytics calls * eslintignore these 2 files: packages/cli/src/generator_templates packages/cli/src/emails because they are ignored in tsconfig.json * update files attribute in package.json * don't actually want to ignore those * this is my workaround for typescript-eslint/typescript-eslint#2987 * noop? * simplify tsconfigs? * fix all the lints * oops * try void * async await * smaller change * fix server build * Revert "fix server build" This reverts commit e24e0ed. * await -> void in init * remove trailing comma in json * cypress does not actually need to reset the web db, so remove * server: try cd into .mailing and then npx next build with the current directory * pull posthog api key into its own file so it does not bloat the next build by pulling in posthog-node * import from the righ tplaÿce
I’m also having this problem using ESLint from a symlink location resulting in the error typescript-eslint/packages/typescript-estree/src/parseSettings/getProjectConfigFiles.ts Line 36 in 810fc8c
typescript-eslint/packages/typescript-estree/src/parseSettings/getProjectConfigFiles.ts Lines 55 to 58 in 810fc8c
from PR #6084. typescript-eslint/packages/typescript-estree/src/parseSettings/createParseSettings.ts Lines 68 to 73 in 810fc8c
with |
@alex-kinokon feel free to send a PR, that'd be lovely! I'm not 100% sure that the I'll extend that invitation to everybody seeing this. We the maintainers haven't had time to send a PR ourselves but I see at least 2-3 suggestions of how to fix the issue in the thread. Wonderful opportunity for someone to send a code contribution in. 😄 |
@alex-kinokon Can you please provide your insight as PR ❤️ |
(noob here) I see that calling |
Some code already calls to |
Thanks. Tried applying the propsed fixed but tests went bananas. Hoping that someone who knows this project will pick this up 🤞🙏 |
Drive-by, but is this "fixed" by just using the project service? After all, surely this code works with tsserver in VS Code, so theoretically should behave no differently with the project service enabled. |
That's a workaround, yeah. |
Any final solution on this? To avoid using a work around. |
If there was an update, it'd be posted here. There is not. It's still |
With any issue opened in this project — it either has visible progress in the form of an attached PR, or it has no progress. We are a community-run project. The volunteer maintainers spend most of their time triaging issues and reviewing PRs. This means that most issues will not progress unless a member of the community steps up and champions it. If this issue is important to you — consider being that champion. |
@JoshuaKGoldberg, @bradzacher, Sorry. My previous message was not intended to be pushy. I will wait patiently for this. |
Repro
https://github.com/nikparo/ts-eslint-symlinks
Expected Result
The targeted directories and files should be linted, whether or not there are symlinks elsewhere pointing at them.
Actual Result
If there is a symlink somewhere pointing at a directory, then linting it will throw
Parsing error: "parserOptions.project" has been set for @typescript-eslint/parser.
errors. At least if the symlink alphabetically comes before the directory.By deleting the symlink
apps/legacy-app/libs
(which points atlibs
) the errors go away. Whether the symlink is ignored or not usingignorePatterns
does not seem to matter.Additional Info
I believe I have tracked this down to the use of
updatedProgram.getRootFileNames()
increateWatchProgram.js
. That method call seems to only get the first instance of a symlinked file. I.e.apps/legacy-app/libs/symlinked-lib/src/index.ts
will be in the returnedfileList
, butlibs/symlinked-lib/src/index.ts
will not.Versions
@typescript-eslint/typescript-estree
4.14.1
TypeScript
4.1.3
node
v12.20.0
The text was updated successfully, but these errors were encountered: