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

feat(examples-plugins): add knip to example plugin #570

Closed
wants to merge 193 commits into from

Conversation

BioPhoton
Copy link
Collaborator

@BioPhoton BioPhoton commented Mar 15, 2024

This PR is just here to showcase knip implementation and screenshots.

This PR includes:

  • examples-plugins/src
    • logic to wrap the knip CLI
    • unit and integration tests
    • docs
  • utils
    • helper to setup categories capital and singular

This PR does not include:

  • e2e tests because it is an example

See the portal here: https://staging.code-pushup.dev/portal/code-pushup/cli-utils/commit/985ac7155f1f8cb8ad1b482a984740ad3d2d5e75/dashboard

Changes for a followup PR:

  • issues table - duplicated exports should list last reference instead of first
  • issues table - unused dependencies should link to line where package sit's
  • issues table - unlisted dependencies, unused development dependencies could list only one referencing file (otherwise we see multiple times the same issue title with a difference source but installing it ones fixes the issues)
  • issues table - issue messages could include the full audit title e.g. "Unused export docsUrlSchema" instead of "Export docsUrlSchema"

Used configuration

import {
  KnipConfigPlugin,
  combineNxKnipPlugins,
  withEsbuildApps,
  withEsbuildPublishableLibs,
  withEslint,
  withLibraryMapper,
  withLocalNxPlugins,
  withNxTsPaths,
  withVitest,
} from '@beaussan/nx-knip';

export const withIgnoreMockInLibs = () =>
  withLibraryMapper({
    mapperFn: ({ rootFolder }) => {
      return {
        ignore: [rootFolder + '/mocks/**'],
        entry: [rootFolder + '/src/bin.ts', rootFolder + '/perf/**/index.ts'],
      };
    },
  });

export const withCuNxStandards = (): KnipConfigPlugin => () => {
  return {
    project: ['**/*.{ts,js,tsx,jsx}'],
    ignore: ['tmp/**', 'node_modules/**', 'examples/**'],
    entry: [
      'testing/test-utils/src/index.ts',
      'testing/test-utils/src/lib/fixtures/configs/*.{js,mjs,ts,cjs,mts,cts}',
      'testing/test-setup/src/index.ts',
      'testing/test-setup/src/lib/**/*.{js,mjs,ts,cjs,mts,cts}',
      // Same issue as the other vitest related, it should be picked up by knip from the vitest setup files
      'global-setup.ts',
      'global-setup.e2e.ts',
      // missing knip plugin for now, so this is in the root entry
      'packages/models/zod2md.config.ts',
      'code-pushup.config.ts',
      'esbuild.config.js',
      'tools/**/*.{js,mjs,ts,cjs,mts,cts}',
    ],
    ignoreDependencies: [
      'prettier',
      '@swc/helpers',
      '@swc/cli',
      '@nx/plugin',
      '@nx/workspace',
      '@example/custom-plugin',
    ],
  };
};

export default combineNxKnipPlugins(
  withNxTsPaths(),
  withLocalNxPlugins({ pluginNames: ['nx-plugin'] }),
  withEsbuildApps(),
  withEsbuildPublishableLibs(),
  withVitest(),
  withIgnoreMockInLibs(),
  withEslint(),
  withCuNxStandards(),
);

run nx run-collect --onlyPlugins knip to test it locally.

Example Audit Interpretation

Legend:

  • ✅ - valid result
  • ❌ - false positive
  • ❓ - open question
  • ⏳ - evaluation pending

Unused files (1)

  • ✅ packages/plugin-lighthouse/src/index.ts
    Can be fixed by using it in e.g. e2e tests

Unused dependencies (1)

  • ✅ cli-table3 package.json
    Can be fixed by uninstalling cli-table3
    Run npm remove cli-table3 to remove dependency

Unused devDependencies (8)

  • ✅ tsx package.json
    This package is not used anywhere in the code either directly on in "scripts" or configuration files.
    You can fix it by running npm remove tsx
    Same goes for the follwing dependencies
  • ✅ @trivago/prettier-plugin-sort-imports package.json
  • ⏳ eslint-plugin-jsx-a11y package.json
  • ❓ eslint-plugin-react package.json
    should have been picked up by the nx helper WDYT @beaussan
    the following packages are (most probably) a cascade of this issue
  • ❓ eslint-plugin-react-hooks package.json
  • ❓ jsonc package.json
  • ❌ commitlint-plugin-tense package.json
    false as it is used in commitlint.config.js
/** @type {import('@commitlint/types').UserConfig} */
const configuration = {
  extends: ['@commitlint/config-conventional'],
  plugins: ['commitlint-plugin-tense'],
// ...
}
  • ❌ conventional-changelog-angular package.json
    false as a peer dependency of commit. (cascade of commitlint-plugin-tense)
    Run npm ls conventional-changelog-angular to list check dependent packages.
├─┬ @commitlint/[email protected]
│ └─┬ @commitlint/[email protected]
│   └─┬ @commitlint/[email protected]
│     └── [email protected]
└─┬ [email protected]
  └─┬ @commitlint/[email protected]
    └─┬ @commitlint/[email protected]
      └── [email protected]

Unlisted dependencies (38)

  • ✅ jsonc-eslint-parser .eslintrc.json
    This is a peer dependency of @nx/eslint-plugin, but and not directly installed.
    If you uninstall @nx/eslint-plugin you don't have jsonc-eslint-parser anymore available.
    Run npm ls jsonc-eslint-parser to list the root package:
@code-pushup/[email protected] /Users/michael_hladky/WebstormProjects/quality-metrics-cli
└─┬ @nx/[email protected]
  └── [email protected]

To fix it run npm i jsonc-eslint-parser --save-dev
same is valid for all following issues of jsonc-eslint-parser

  • ✅ jsonc-eslint-parser e2e/cli-e2e/.eslintrc.json
  • ✅ jsonc-eslint-parser packages/cli/.eslintrc.json
  • ✅ jsonc-eslint-parser packages/core/.eslintrc.json
  • ✅ jsonc-eslint-parser packages/models/.eslintrc.json
  • ✅ jsonc-eslint-parser packages/nx-plugin/.eslintrc.json
  • ✅ jsonc-eslint-parser packages/plugin-coverage/.eslintrc.json
  • ✅ jsonc-eslint-parser packages/plugin-eslint/.eslintrc.json
  • ✅ jsonc-eslint-parser packages/plugin-js-packages/.eslintrc.json
  • ✅ jsonc-eslint-parser packages/plugin-lighthouse/.eslintrc.json
  • ✅ jsonc-eslint-parser packages/utils/.eslintrc.json
  • ✅ jsonc-eslint-parser testing/test-setup/.eslintrc.json
  • ✅ jsonc-eslint-parser testing/test-utils/.eslintrc.json
  • ✅ minimatch tools/eslint-to-code-pushup.mjs
    This is used in tools/eslint-to-code-pushup.mjs, but and not listed in package.json. The code works because other packages like @nx/devkit have minimatch as peer dependency. If you would remove all related packages like @nx/devkit, tools/eslint-to-code-pushup.mjswould stop working.
    Run npm ls minimatch to list the root package:
├─┬ @nx/[email protected]
│ └─┬ [email protected]
│   └─┬ [email protected]
│     ├─┬ [email protected]
│     │ └── [email protected]
│     └── [email protected]

To fix it run npm i minimatch --save-dev
same is valid for issues of tslib

  • ✅ tslib tsconfig.base.json
  • ✅ @example/custom-plugin testing/test-utils/src/lib/fixtures/configs/code-pushup.needs-tsconfig.config.ts
    This is used as dummy reference in a test like this.
  // the point is to test runtime import which relies on alias defined in tsconfig.json "paths"
// non-type import from '@example/custom-plugin' wouldn't work without --tsconfig
import customPlugin from '@example/custom-plugin';

const config = {
  plugins: [customPlugin],
};

export default config;

It can be fixed by adding the package name to the knip.config.ts

 export default { 
// ...
  ignoreDependencies: [
      // 👇 fixed by add package name to ignoreDependencies here
      '@example/custom-plugin'
    ],
}
  • ✅ @commitlint/types commitlint.config.js
    Is used in like this: const { RuleConfigSeverity } = require('@commitlint/types');.
    To fix it run npm i @commitlint/types --save-dev

  • ❓ basic e2e/cli-e2e/vite.config.e2e.ts
    This shows no dependents when running npm ls basic
    This could be fixed by installing basic manually over npm i basic -D but seems odd as there are no deps listed.
    Same goes for all other issues related to basic

  • basic packages/cli/vite.config.integration.ts

  • basic packages/cli/vite.config.unit.ts

  • basic packages/core/vite.config.integration.ts

  • basic packages/core/vite.config.unit.ts

  • basic packages/models/vite.config.integration.ts

  • basic packages/models/vite.config.unit.ts

  • basic packages/nx-plugin/vite.config.integration.ts

  • basic packages/nx-plugin/vite.config.unit.ts

  • basic packages/plugin-coverage/vite.config.integration.ts

  • basic packages/plugin-coverage/vite.config.unit.ts

  • basic packages/plugin-eslint/vite.config.integration.ts

  • basic packages/plugin-eslint/vite.config.unit.ts

  • basic packages/plugin-js-packages/vite.config.integration.ts

  • basic packages/plugin-js-packages/vite.config.unit.ts

  • basic packages/plugin-lighthouse/vite.config.integration.ts

  • basic packages/plugin-lighthouse/vite.config.unit.ts

  • basic packages/utils/vite.config.integration.ts

  • basic packages/utils/vite.config.unit.ts

  • basic testing/test-utils/vite.config.unit.ts

Unused exports (23)

  • ✅ renderUploadAutorunHint function packages/cli/src/lib/collect/collect-command.ts:42:17
    can be fixed by removing the export form duplicateRefsInCategoryMetricsErrorMsg
// 👇 fixed by removing this export
export function renderUploadAutorunHint(...) { /*...*/ }
  • ✅ duplicateRefsInCategoryMetricsErrorMsg function packages/models/src/lib/category-config.ts:54:17
  • ✅ unrefinedCoreConfigSchema unknown packages/models/src/lib/core-config.ts:11:14
  • ✅ refineCoreConfig function packages/models/src/lib/core-config.ts:32:17
  • ✅ messageStyles unknown packages/utils/src/lib/progress.ts:13:14
  • ✅ singletonUiInstance unknown packages/utils/src/lib/logging.ts:23:12
  • ✅ logListItem function packages/utils/src/lib/logging.ts:39:17
  • ✅ onlyPluginsOption unknown packages/cli/src/lib/implementation/only-plugins.options.ts:4:14
  • ✅ h function packages/utils/src/lib/reports/md/headline.ts:13:17
    can be fixed by exporting h in index.ts
// 👇 fixed by adding this export
export * from './src/lib/reports/md'
  • ✅ h4 function packages/utils/src/lib/reports/md/headline.ts:29:17
  • ✅ h5 function packages/utils/src/lib/reports/md/headline.ts:33:17
  • ✅ h6 function packages/utils/src/lib/reports/md/headline.ts:37:17
    can be fixed by exporting groupMetaSchema in index.ts
// 👇 fixed by adding this export
export {groupMetaSchema} from '.packages/models/src/lib/audit.ts'

Similar fix can be applied for the following issues.

  • ✅ throwIsNotPresentError function packages/utils/src/lib/reports/utils.ts:273:17
  • ✅ groupMetaSchema unknown packages/models/src/lib/group.ts:20:14
  • ✅ NoExportError class packages/utils/src/lib/file-system.ts:78:14
  • ✅ weightSchema unknown packages/models/src/lib/implementation/schemas.ts:140:14
  • ✅ descriptionSchema unknown packages/models/src/lib/implementation/schemas.ts:40:14
  • ✅ docsUrlSchema unknown packages/models/src/lib/implementation/schemas.ts:49:14
  • ✅ pluginDataSchema unknown packages/models/src/lib/plugin-config.ts:30:14
  • ✅ coverageTypeSchema unknown packages/plugin-coverage/src/lib/config.ts:3:14
  • ✅ coverageResultSchema unknown packages/plugin-coverage/src/lib/config.ts:6:14
  • ⏳ WORKDIR unknown packages/plugin-eslint/src/lib/runner/index.ts:14:14
  • ⏳ shieldsBadge function packages/utils/src/lib/reports/utils.ts:71:17

Unused exported types (12)

  • ✅ FontStyle type packages/utils/src/lib/reports/md/font-style.ts:8:13
    can be fixed by exporting h in index.ts
// 👇 fixed by adding this export
export * from './src/lib/reports/md'

Same is applicable for the following issues

  • ✅ Hierarchy type packages/utils/src/lib/reports/md/headline.ts:2:13
  • ✅ Order type packages/utils/src/lib/reports/md/list.ts:1:13
  • ✅ GroupMeta type packages/models/src/lib/group.ts:26:13
    can be fixed by exporting GroupMeta in index.ts
// 👇 fixed by adding this export
export {GroupMeta} from '.packages/models/src/lib/group.ts'
  • ✅ CliUiBase type packages/utils/src/lib/logging.ts:8:13
    can be fixed by removing the export form CliUiBase
// 👇 fixed by removing this export
export type CliUiBase = /*...*/;
  • ✅ OnlyPluginsCliOptions type packages/cli/src/lib/implementation/only-plugins.model.ts:4:13
    this type is not used.
    It can be fixed by using it to ensure the option names.
export function yargsOnlyPluginsOptionsDefinition(): Record<
   // 👇 fixed by replacing 'onlyPlugins' with `keyof OnlyPluginsCliOptions`
  'onlyPlugins',
  Options
> {
  return {
    onlyPlugins: onlyPluginsOption,
  };
}
  • ✅ HistoryOnlyOptions type packages/core/src/lib/history.ts:8:13
    is unused can be fixed by exporting it. (lands in feat(cli): add history command #273)
  • ✅ LighthouseCliOptions type packages/plugin-lighthouse/src/lib/utils.ts:16:13
    is unused can be fixed by exporting it. (lands in feat(plugin-lighthouse): add lighthouse runner #549)
  • ✅ Yarnv2AuditAdvisory type packages/plugin-js-packages/src/lib/runner/audit/types.ts:87:13
    can be fixed by exporting Yarnv2AuditAdvisory in index.ts
// 👇 fixed by adding this export
export {Yarnv2AuditAdvisory} from './src/lib/runner/audit/types.ts'

Same applies for the following exported types

  • ✅ NpmVersionOverview type packages/plugin-js-packages/src/lib/runner/outdated/types.ts:19:13
  • ✅ Yarnv1VersionOverview type packages/plugin-js-packages/src/lib/runner/outdated/types.ts:33:13
  • ✅ Yarnv2VersionOverview type packages/plugin-js-packages/src/lib/runner/outdated/types.ts:54:13

Duplicate exports (2)

  • ✅ addToProjectGenerator, default packages/nx-plugin/src/generators/configuration/generator.ts
    the audit can be fixed by only exporting the same instance 1 time. Note: also applies for the following autit.
// packages/nx-plugin/src/generators/configuration/generator.ts
// 👇 e.g. fixed by removing this export and keep the default export
export function initGenerator(tree: Tree, schema: InitGeneratorSchema) {
   // ...
}
// 👇 e.g. fixed by removing this export and keep the explicite export
export default initGenerator;
  • ✅ initGenerator, default packages/nx-plugin/src/generators/init/generator.ts

Snippet to test fixes:

npm remove cli-table3 conventional-changelog-angular eslint-plugin-jsx-a11y tsx && npm i -D jsonc-eslint-parser lighthouse-logger debug chrome-launcher minimatch

Screenshots of the implementation in different views

Plugin Terminal Output Plugin MD Output
Screenshot 2024-03-14 at 09 02 59 Screenshot 2024-03-15 at 12 23 04 Screenshot 2024-03-14 at 11 29 39
Portal Portal
Screenshot 2024-03-16 at 00 47 23 Screenshot 2024-03-16 at 00 49 20

Related:
webpro-nl/knip#551

@matejchalk
Copy link
Collaborator

The Unused development dependencies audit is full of false positives, I'm afraid 😞 It doesn't seem to detect usage other than import/require in code. Other than the false positives already mentioned, the following are also not valid:

✅ tsx package.json
This package is not used anywhere in the code either directly on in "scripts" or configuration files.
You can fix it by running npm remove tsx
Same goes for the follwing dependencies
✅ @trivago/prettier-plugin-sort-imports package.json

@BioPhoton
Copy link
Collaborator Author

✅ @trivago/prettier-plugin-sort-imports package.json

  • @trivago/prettier-plugin-sort-imports is used, Prettier picks it up automatically, importOrder and importOrderSortSpecifiers options configured in .prettierrc
  • could also be made explicit by adding plugins: ['@trivago/prettier-plugin-sort-imports']

True! found out prettier was excluded in the config

True. figured out perf folder is configured wrong

@beaussan
Copy link
Contributor

beaussan commented Apr 7, 2024

❓ eslint-plugin-react package.json
should have been picked up by the nx helper WDYT @beaussan
the following packages are (most probably) a cascade of this issue
❓ eslint-plugin-react-hooks package.json

This was the case since we excluded the example projects, I changed that in the base config and this is now properly reported

❌ commitlint-plugin-tense package.json
false as it is used in commitlint.config.js

This is something missing on the knip side, it will only look at the extends but not the plugins array. I will make a follow up on their side to update it. In the meantime, added to the ignore array

❓ basic e2e/cli-e2e/vite.config.e2e.ts
This shows no dependents when running npm ls basic
This could be fixed by installing basic manually over npm i basic -D but seems odd as there are no deps listed.
Same goes for all other issues related to basic

This is a false positive, it shouldn't require a npm lib since it's a built in of vitest. I will make a pr to add it to the built in reporters on the knip side so this shouldn't occur anymore. In the meantime, I added it to the ignore dependencies array

tsx is used by the perf Nx target in packages/utils/project.json

This should have been picked up by knip, since it will look at the project json configs to detect the scripts and thrid party requirements, I will follow up with an issue on their side

@beaussan
Copy link
Contributor

beaussan commented Apr 7, 2024

Related PRs :
webpro-nl/knip#587
webpro-nl/knip#588

@BioPhoton BioPhoton marked this pull request as ready for review April 14, 2024 15:43
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
🧩 models 📖 Project documentation improvements or additions to the project documentation 🔬 testing writing tests 🛠️ tooling 🧩 utils
Projects
None yet
Development

Successfully merging this pull request may close these issues.

4 participants