knip
knip copied to clipboard
Marked as unused if used only in Vue <template>
I have a typescript file that export a function used only in the <template> part of a .vue file like this:
<script setup lang="ts">
import {humanFormat} from "@/services/HumanFormat";
</script>
<template>
<div>{{ `Isosurface value (${humanFormat(value)})` }}</div>
</template>
Knip wrongly marks the HumanFormat.ts file as unused.
Maybe simply adding a list in the knip.json configuration with files that are used ("Trust me these files are used") could help reduce the noise on the output.
knip 5.11.0
Thanks! mario
The named import of humanFormat is enough for Knip to consider it referenced/used. So something else might be the culprit here, such as the way the vue file is imported, or the path aliases. So I'd need a proper reproduction to look into it and say something more useful about this.
Hello,
May be an issue with the tsconfig.json configuration created by https://github.com/vuejs/create-vue
The alias path are in tsconfig.app.json and not in the tsconfig.json
tsconfig.json:
{
"files": [],
"references": [
{
"path": "./tsconfig.node.json"
},
{
"path": "./tsconfig.app.json"
}
]
}
tsconfig.app.json
{
"extends": "@vue/tsconfig/tsconfig.dom.json",
"include": ["env.d.ts", "src/**/*", "src/**/*.vue", "src/**/*.json"],
"exclude": ["src/**/__tests__/*"],
"compilerOptions": {
"composite": true,
"baseUrl": ".",
"paths": {
"@/*": ["./src/*"]
}
}
Repro : https://stackblitz.com/edit/vitejs-vite-dpq56w?file=tsconfig.app.json
❯ npx knip
Analyzing workspace ....
Unused files (2)
src/vite-env.d.ts
src/components/HelloWorld.vue
Unresolved imports (1)
@/components/HelloWorld.vue src/App.vue:1:23
Regards
Mathieu
Thanks Mathieu! Repros are great 🙏
There's two different potential solutions to this.
- Add
knip.jsonwith the samepaths:
{
"paths": {
"@/*": ["./src/*"]
}
}
- Use
knip --tsConfig tsconfig.app.json
With that, I'm going to close issue.
Nothing changed unfortunately. Added the "path" entry to knip.json and executed knip with --tsConfig BTW, tsconfig.json already contains the "path" entry.
Without a minimal reproduction like @messenjer provided there isn't much to look for me.
@webpro Here is a minimal reproduction. The vue project has been generated with npm create vue@latest.
Rename the attached zip file
unused.txt
to unused.zip and unzip it. This creates the vue-project directory. Then do:
cd vue-project
npm install
knip
You will see that the file src/HumanFormat.ts has been marked as unused, but it is imported in HelloWorld.vue component where its exported routine is used only in the <template> section.
Thanks for your patience! mario
$ knip --version
5.24.1
on Windows
Typo?
<script setup lang="ts">
import { numanFormat } from '../HumanFormat.ts';
</script>
Opps, yes.
<script setup lang="ts">
import { humanFormat } from '../HumanFormat.ts';
</script>
So the reproduction failed. I should add more pieces from the original project...
Red face. Have found why this file ("@/services/HumanFormat") is accounted as unused by knip. Because it is only used by components that are loaded dynamically (with something like: defineAsyncComponent(import(components/ui/${ui}.vue) and thus considered unused.
If only knip had a way to manually mark files as used even if they cannot be found by knip!
Anyway, thanks for the patience and continue with this useful tool!
Ah yes, indeed dynamic import specifiers like import("components/ui/${ui}.vue") are not supported. They might be in the future, though.
There's a few options I can think of:
- Add such files as entry files using something like
entry: ["components/ui/*.vue"]- entry files are always "used" - Remove them files from the project files, e.g.
project: ["!components/ui/*.vue"]