mirror of
https://github.com/kucherenko/jscpd.git
synced 2026-09-19 08:11:03 +08:00
2baf2890d4
basta reported most of a real Vue, Svelte or Astro project as dead: on
thirty GitHub-trending projects in those three ecosystems it flagged 1572
unused files, and some import in the tree contradicted 78% of them. The
misses were almost never in the analysis itself; they were imports only the
project's own build knows how to resolve. This reads them the way the build
does.
- Single-file components are read whole. The script of a .vue, .svelte or
.astro file is masked in place so positions stay real, and the markup is
scanned for the names it reads: <Foo />, kebab-case spellings, {{ }}
interpolations, Svelte actions, attribute expressions, and a literal
import() written in markup.
- Aliases come from vite.config.* resolve.alias and svelte.config.* kit.alias
as well as tsconfig paths, and SvelteKit's $lib is known without the
generated .svelte-kit/tsconfig.json no repository commits. The project's
own declaration now wins over the ~/ @/ project-root fallback.
- A computed import whose static head names a directory,
import(`./pages/${name}.vue`), and import.meta.glob('./locales/*.js') are
expanded into one namespace edge per file there, the way a bundler hands
back whole module objects. Such an import no longer marks its module as
dynamic access, so the module's own findings keep their confidence.
- In a monorepo a package name resolves through that package's package.json,
exports subpath by subpath with source conditions preferred over ./dist,
anywhere in the workspace pnpm-workspace.yaml, lerna.json, turbo.json or a
workspaces field marks out.
- A path literal in a build config resolves against the project root, and
Nitro's api/, routes/ and middleware/ are file-system routes.
On the same thirty projects reported unused files fell from 1572 to 468.
fixtures/dead-code-demo gains components/, bundler/ and monorepo/. On master
the bundler demo reports five files as certainly dead, four of them wrongly;
the monorepo demo reports badge.ts, which the app imports by package name.
Both now report only what is dead. The quote-aware byte scanning the markup
and config readers share lives in one place, lang::Quotes and
lang::outside_strings, so rust/crates keeps master's 25 clones.
49 lines
1.3 KiB
TOML
49 lines
1.3 KiB
TOML
[package]
|
|
name = "basta"
|
|
version = "0.1.1"
|
|
edition.workspace = true
|
|
publish = false
|
|
rust-version.workspace = true
|
|
description = "Dead code detection — unused files, exports, symbols and imports across JavaScript, TypeScript, Vue, Svelte, Astro and Python"
|
|
homepage.workspace = true
|
|
license.workspace = true
|
|
repository.workspace = true
|
|
documentation = "https://jscpd.dev"
|
|
keywords = ["dead-code", "unused-code", "static-analysis", "unused-exports", "basta"]
|
|
categories = ["command-line-utilities", "development-tools"]
|
|
|
|
[lib]
|
|
name = "basta"
|
|
path = "src/lib.rs"
|
|
|
|
[[bin]]
|
|
name = "basta"
|
|
path = "src/main.rs"
|
|
|
|
[dependencies]
|
|
globset = "0.4"
|
|
ignore = "0.4"
|
|
cpd-core = { version = "0.1.14", path = "../cpd-core" }
|
|
cpd-finder = { version = "0.1.16", path = "../cpd-finder" }
|
|
cpd-reporter = { version = "0.1.15", path = "../cpd-reporter" }
|
|
cpd-tokenizer = { version = "0.1.16", path = "../cpd-tokenizer" }
|
|
oxc_allocator = "0.147"
|
|
oxc_ast = "0.147"
|
|
oxc_ast_visit = "0.147"
|
|
oxc_parser = "0.147"
|
|
oxc_semantic = "0.147"
|
|
oxc_span = "0.147"
|
|
oxc_syntax = "0.147"
|
|
ruff_python_ast = "0.0.13"
|
|
ruff_python_parser = "0.0.13"
|
|
rustc-hash = "2"
|
|
chrono = "0.4"
|
|
rayon = "1"
|
|
serde = { version = "1", features = ["derive"] }
|
|
serde_json = "1"
|
|
clap = { version = "4", features = ["derive"] }
|
|
env_logger = "0.11"
|
|
|
|
[dev-dependencies]
|
|
serde_json = "1"
|