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
@typescript-eslint/typescript-estree is missing a peer dependency on the "typescript" package #828
Comments
There's also a similar problem in I created PR #829 to fix this. |
The missing typescript peer dependency is done on purpose. Essentially If we have a peer dependency on typescript, npm/yarn will spit out warnings into the console whenever users do any operation on the package.json. This creates a bad experience and annoys users, and colours people's perceptions of the language. Ultimately the peer dep doesn't do anything except provide documentation that the packages use typescript, which is similarly accomplished by the package names, and also the fact that they'll throw at lint-time. But if someone intentionally installs any of our packages, they'll have typescript installed locally anyway. IIRC yarn supports the notion of optional peer dependencies, but NPM doesn't. The plan is to add the deps back in using that notation when both tools support it. |
I need to do a little more investigation to see how likely my project is to get burned by this in practice. Maybe it's a purely theoretical concern. I'm being paranoid because in a large company, people can spend a /lot/ of time dealing with headaches caused by packages with incorrectly specified package.json dependencies.
Ermmm no. The peer dependency alters the package manager's analysis, and in some situations this is the only way to get a correct installation. Consider this hypothetical case:
(This example is perhaps a bit artificial, since it's just the first thing I could think of. But it represents a general NPM side-by-side versioning problem that arises very frequently for large scale projects.) In the above example, when The right answer is that we need to load two instances of There are two modern implementations of this feature:
The "weirdness" is that it correctly supports side-by-side versioning relationships, which requires those dependencies to be actually declared in package.json. From this perspective, classic NPM was more "weird" by flattening the node_modules folder and allowing packages to import undeclared dependencies, with no idea what version they will get.
If |
Sorry I meant in terms of the peer deps we had listed before, which was just (It was probably just part of your example, but) If they use Also note that we do runtime checking of the typescript version, and log a big, annoying warning if an unsupported version of TS is being used. typescript-eslint/packages/typescript-estree/src/parser.ts Lines 275 to 290 in 42b3013
These together will likely take care of many of the problems that could happen with different versions. Sorry, weirdness was the wrong word. I should have just said errors.
I wasn't actually sure how it worked, as I haven't ever used it before. I think they have certain philosophies like not modifying the user's dependencies. The idea is that it's a black-box tool. Linting is handled within the tool (it integrates into their custom webpack build process), hence they have internal dependencies on our packages. |
In a monorepo with hundreds of projects, we don't add You are right, though, the project-level dependency on It's understandable why |
It looks like it's set to be released in npm v7! So give it a few weeks after that for people to start to upgrade their versions, and we can put it in. |
Its in npm 6.11.0 |
Breaking the eco-system because beginners might not get a great experience when installing packages is not great. The assumption is incorrect, and there is no messaging now when you don't install I know that this is likely to be fixed (per above), but the reasoning will hopefully not be applied again, in the future. |
But unless I'm mistaken - a peer dependency wouldn't have helped your prod build. If your project works in development, that means you have typescript installed in development. Because have it installed as a dev dependency, you wouldn't have gotten a warning logged at install time by npm/yarn. An optional dep will definitely help, because (IIRC) they are installed by default as part of a production install. But it's only been a month since implementation by I'm curious - which one of our packages are you relying upon in a production environment? Everything we've got is pretty much dev-only tooling. |
Hehe. You're absolutely right. Except I don't agree that typescript is an optional dep. It's required by the main export, so it should be a dep. But alas, like you said, of they're installed by default, that would have fixed it for us 😁🥰. I use the parser to parse code into an EStree! It's to automatically generate commentary on student solutions for exercises on https://exercism.io. we don't use the typescript parse because using and relying on ESTree means we can actually manually run tools, including custom lint rules. You can find the repository at https://github.com/exercism/javascript-analyzer |
The problem with making it a proper dep is that will cause npm/yarn to install a local copy of the package within our install if the version ranges don't match the locally installed version, and having two copies of typescript in your tree can be problematic (imagine having So we kinda have to make it a peer/optional dep :/ |
Yessss. I understand. Optional peer dep for me would work.
It's a hard problem and the deps system don't provide a right option it
seems. Currently it just silently blows up which took two of us an hour
to figure out which is costly. But I know you understand :)
…On 2019-09-25 19:25, Brad Zacher wrote:
The problem with making it a proper dep is that will cause npm/yarn to
install a local copy of the package within our install if the version
ranges don't match the locally installed version, and having two
copies of typescript in your tree can be problematic (imagine having
readonly string[] work in your ide, but throw errors at lint time!).
So we kinda have to make it a peer/optional dep :/
--
You are receiving this because you commented.
Reply to this email directly, view it on GitHub [1], or mute the
thread [2].
Links:
------
[1]
#828?email_source=notifications&email_token=AAO7SWFS5TUUGRTSKBSKTOTQLONHFA5CNFSM4IKROKTKYY3PNVWWK3TUL52HS4DFVREXG43VMVBW63LNMVXHJKTDN5WW2ZLOORPWSZGOD7SWA4I#issuecomment-535126129
[2]
https://github.com/notifications/unsubscribe-auth/AAO7SWHJSZ5KHU437WXMETLQLONHFANCNFSM4IKROKTA
|
The package.json for the
@typescript-eslint/typescript-estree
current canary release looks like this:The
typescript
dependency appears in thedevDependencies
section, but it is not listed as apeerDependency
. This is incorrect because this package definitely does import objects from thetypescript
package. For example, this line:typescript-eslint/packages/typescript-estree/src/tsconfig-parser.ts
Line 189 in 3c902a1
When using NPM and classic Yarn, this "phantom dependency" can get inadvertently satisfied by other packages that appear in the flattened node_modules tree (albeit without any guarantee of what version will get loaded). But with more rigorous package managers such as PNPM or Yarn Plug 'n Play, the module may fail to load because their installation strategy prevents undeclared dependencies from being accidentally imported (while still being 100% compatible with the NodeJS module resolution contract).
Proposed solution: Add something like this to typescript-estree/package.json:
The text was updated successfully, but these errors were encountered: