-
-
Notifications
You must be signed in to change notification settings - Fork 4.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
chore: Introduce Knip #18005
chore: Introduce Knip #18005
Conversation
Hi @webpro!, thanks for the Pull Request The pull request title isn't properly formatted. We ask that you update the pull request title to match this format, as we use it to generate changelogs and automate releases.
To Fix: You can fix this problem by clicking 'Edit' next to the pull request title at the top of this page. Read more about contributing to ESLint here |
✅ Deploy Preview for docs-eslint ready!
To edit notification comments on pull requests, go to your Netlify site configuration. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thanks for putting this together. Overall, what this PR is missing is an explanation of what Knip is and what benefit it is to the project as a whole. If you can add that information into the original description, it would greatly facilitate conversation around this PR.
@@ -0,0 +1,46 @@ | |||
{ |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It would be helpful if you could explain what all of this does.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Most of the configuration comes down to providing entry files in order for Knip to do its thing.
This repository is much like a monorepo, but without explicitly defined workspaces
as package managers like npm and pnpm recognize them. Knip normally hooks into package.json#workspaces
, but those folders with a package.json
manifest can also be manually added to the Knip configuration file. So the keys of the workspaces
object are the paths to those folders.
@@ -157,6 +160,7 @@ | |||
"semver": "^7.5.3", | |||
"shelljs": "^0.8.2", | |||
"sinon": "^11.0.0", | |||
"typescript": "^5.3.3", |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Why do we need TypeScript?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Knip uses typescript
and @types/node
as peer dependencies to parse JavaScript and TypeScript files, build ASTs to find imports and exports, and as a foundation for module resolution. They're not regular dependencies of Knip as not to cause incompatibility issues with projects that do use TypeScript. Both devDependencies
are already in node_modules
, so they're not further impacting the size of the project.
Sorry, there was indeed no proper introduction. There's a new section added to the description. Feel free to ask me anything you'd like to discuss or want to know more about. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Cool stuff! Left a few clarifying questions in lieu of a full review.
To move this pull request forward, it would help to discuss questions number 2 and 3 I've listed at the end of the description. And then, eventually, the list of configuration options and things in the codebase we can delete. |
1 and 2: These dependencies are needed when eslint is used with Lines 64 to 66 in 8c1b8dd
eslint/packages/eslint-config-eslint/eslintrc.js Lines 12 to 17 in 8c1b8dd
We'll probably remove this config file and the dependencies soon (#18011).
|
Let's await that then to circumvent unnecessary complexity/issues.
Added a yorkie plugin to Knip (and upgraded to that version here). |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
LGTM. Interested to get this integrated and see what else we find along the way.
Would like @mdjermanovic and @JoshuaKGoldberg to approve before merging.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Progress! 🚀
I left a status summary comment on package.json
. I think it'd make sense to perform the deletions as part of this PR so that the repo's in a clean slate. WDYT?
Requesting changes to also indicate the PR as blocked on #18011 per the comments.
tests/tools/config-rule.js
Outdated
@@ -10,7 +10,7 @@ | |||
//------------------------------------------------------------------------------ | |||
|
|||
const assert = require("chai").assert, | |||
ConfigRule = require("../../tools/config-rule"), | |||
{ generateConfigsFromSchema } = require("../../tools/config-rule"), |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The ConfigRule.createCoreRuleConfigs
below also needs to be updated:
{ generateConfigsFromSchema } = require("../../tools/config-rule"), | |
{ createCoreRuleConfigs, generateConfigsFromSchema } = require("../../tools/config-rule"), |
It looks like the CI is breaking, can you take a look? |
I've fixed the issues to make tests pass. This is the only way I see that satisfies both proxyquire and knip. |
lib/shared/runtime-info.js
Outdated
@@ -162,6 +162,7 @@ function version() { | |||
//------------------------------------------------------------------------------ | |||
|
|||
module.exports = { | |||
__esModule: true, |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This seems like a bad idea...what's the purpose of this?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
- First I refactored to this syntax, but
proxquire
does not play well with it (so tests were failing):
{ environment, version } = require("./shared/runtime-info"),
So I had no choice but to revert that change to use the "default import":
RuntimeInfo = require("./shared/runtime-info"),
That causes ambiguity in terms of intention, so I've added the property. I've explained more about this here:
The name of the property could be anything, I think __esModule
is common (in bundled code) and describes intent well, but if we think it might cause issues we can rename it.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Gotcha, makes sense. Can you add a comment above explaining that this property makes Knip treat the default export correctly? I could see people getting confused and perhaps unintentionally removing it in the future.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Good idea, done.
@mdjermanovic still looking for your feedback here. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
LGTM. Would still like @mdjermanovic and @JoshuaKGoldberg to approve before merging.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This looks great to me!
I would love to get the list of unused reports down to 0 and add npm run lint:imports
to CI. But if other folks are happy to have that be a followup, then I am too. This is a directly positive change! And, I've pestered @webpro quite a lot already for a very kind change. 😄
I asked in Discord about an issue template for repo tooling followups and can file followup issues for the existing comment threads.
🔥 🙌
], | ||
"ignoreDependencies": [ | ||
"c8", | ||
// Ignore until Knip has a wdio plugin: |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
// Ignore until Knip has a wdio plugin: | |
// Ignore until Knip has a wdio plugin: | |
// https://github.com/webpro/knip/issues/483#issuecomment-1925751516 |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Overall looks good. Can we:
- Add a CI job for this to run on all commits?
- Delete/remove unused files/exports/dependencies as reported in the output?
Just saying: since there are no more issues or blocking matters, I believe my work is done here. Please follow up with PRs for maintenance as you please. |
@webpro There are some suggestions on this issue that need to be addressed before it can be merged. Have you missed them or would you prefer not to put more work into this PR? |
@fasttime The comments keep coming, where does it end? I prefer not to put more work in this PR. |
Fine, thanks a lot for your time working on this! I really appreciate it. At this point, we'll need someone else to finish the PR. |
Perhaps my badly worded point was that I think this PR is fine as it stands. The lights are green. The rest is more a matter of fine-tuning and other things not directly related to the intentions of this PR: introduce Knip. There will always be some maintenance in configuration, just like any other tool. I wonder what must be done in order to start using Knip properly? |
I can take over, if that's helpful. As webpro says - it looks like it's mostly fine-tuning at this point. |
Co-authored-by: Milos Djermanovic <milos.djermanovic@gmail.com>
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
LGTM, thanks!
Prerequisites checklist
What is the purpose of this pull request? (put an "X" next to an item)
[ ] Documentation update
[ ] Bug fix (template)
[ ] New rule (template)
[ ] Changes an existing rule (template)
[ ] Add autofix to a rule
[ ] Add a CLI option
[ ] Add something to the core
[x] Other, please explain: add Knip, a project linter to keep codebase tidy
After having a "go" to explore the usefulness of Knip for the ESLint repository, and a meeting with @JoshuaKGoldberg the other day in which we've set up a first configuration, here's the follow up to that meeting in the form of a pull request.
EDIT: Knip is a project linter. Roughly speaking, where ESLint lints files in isolation, Knip lints codebases as a whole. This line could be drawn at the
export
keyword:Knip creates a map of exports and imports to find unused exports. Additionally, it also finds unused dependencies, by mapping external imports against
dependencies
inpackage.json
files. After all, it's only human to forget to delete unused files, exports and dependencies when they're no longer used. Knip is increasingly able to automate that process. Knip becomes smarter over time, resulting in less configuration. Using Knip in CI, just like ESLint, is beneficial to projects small and large to prevent regressions. Also see https://knip.dev/explanations/why-use-knip for some more in-depth explanations about what Knip has to offer. Knip has a lot more features than fit in this description, feel free to check them out on the website.This PR is ready for review, but there's a few things I'd like you to decide upon:
What changes did you make? (Give an overview)
This last bullet point might be seen as controversial. The thing is that Knip takes a rather conservative stance when it comes to named versus named exports in CommonJS modules. This is because the meaning of
module.exports =
is ambiguous (is it a default export or does it contain named exports?). The changes in this PR reflect that (I believe it's a small price to pay and validates Knip behavior).Is there anything you'd like reviewers to focus on?
When running
npm run lint:knip
from the root, we'll see:Before actually cleaning up unused elements, I'd like to discuss a few results:
eslint-plugin-eslint-comments
is installed and used inpackages/eslint-config-eslint
so I think can be removed from the rootpackage.json
"n/no-process-exit"
rule enough to considereslint-plugin-n
a required plugin? Shouldn'tn
oreslint-plugin-n
explicitly be added to the array ofplugins
?lint-staged
or thegitHooks
inpackage.json
actually used?lint-staged
is reported since there's no reference to it (e.g. in one of thepackage.json#scripts