-
-
Notifications
You must be signed in to change notification settings - Fork 728
feat(lint): implement noVueDuplicateKeys
rule
#7542
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
Conversation
🦋 Changeset detectedLatest commit: 62fea3c The changes in this PR will be included in the next version bump. This PR includes changesets to release 13 packages
Not sure what this means? Click here to learn what changesets are. Click here if you're a maintainer who wants to add another changeset to this PR |
WalkthroughIntroduces a new lint rule noVueDuplicateKeys that detects duplicate keys across Vue component options (props, data, computed, methods, setup). Adds the rule implementation and diagnostics, a corresponding options type and module export, updates Vue setup declaration name extraction to use trimmed token text, and adds a comprehensive test suite with valid and invalid Vue SFC fixtures covering asyncData, data, methods, computed, setup, spreads and script-setup. Possibly related issues
Possibly related PRs
Suggested labels
Suggested reviewers
Pre-merge checks and finishing touches❌ Failed checks (1 warning)
✅ Passed checks (2 passed)
✨ Finishing touches
🧪 Generate unit tests
Tip 👮 Agentic pre-merge checks are now available in preview!Pro plan users can now enable pre-merge checks in their settings to enforce checklists before merging PRs.
Please see the documentation for more information. Example: reviews:
pre_merge_checks:
custom_checks:
- name: "Undocumented Breaking Changes"
mode: "warning"
instructions: |
Pass/fail criteria: All breaking changes to public APIs, CLI flags, environment variables, configuration keys, database schemas, or HTTP/GraphQL endpoints must be documented in the "Breaking Change" section of the PR description and in CHANGELOG.md. Exclude purely internal or private changes (e.g., code not exported from package entry points or explicitly marked as internal). Please share your feedback with us on this Discord post. Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. Comment |
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.
Actionable comments posted: 1
🧹 Nitpick comments (6)
.changeset/rude-horses-worry.md (1)
5-7
: Doc tweak: call out asyncData explicitly.Tests cover asyncData; mention it so the changeset mirrors behaviour.
-This rule prevents the use of duplicate keys across different Vue component options such as `props`, `data`, `computed`, `methods`, and `setup`. Even if keys don't conflict in the script tag, they may cause issues in the template since Vue allows direct access to these keys. +This rule prevents the use of duplicate keys across different Vue component options such as `props`, `data`, `computed`, `methods`, and `setup`. Even if keys don't conflict in the script tag, they may cause issues in the template since Vue allows direct access to these keys. +It also flags duplicates involving framework-specific options like `asyncData`.crates/biome_js_analyze/tests/specs/nursery/noVueDuplicateKeys/valid-data-function.vue (1)
12-14
: Clarify the second data() is intentionally “no-op”.Two data() entries can look suspicious. A tiny comment will help future readers.
data () { return }, + // Intentionally a second data() that returns nothing to ensure it contributes no keys.
crates/biome_rule_options/src/no_vue_duplicate_keys.rs (1)
1-6
: Add a brief doc comment for discoverability.A one-liner will help users understand that options are currently empty but reserved.
-#[derive(Default, Clone, Debug, Deserialize, Deserializable, Eq, PartialEq, Serialize)] +/// Options for the `noVueDuplicateKeys` rule. Currently empty; reserved for future toggles. +#[derive(Default, Clone, Debug, Deserialize, Deserializable, Eq, PartialEq, Serialize)]crates/biome_js_analyze/tests/specs/nursery/noVueDuplicateKeys/valid-script-setup-defineprops.vue (1)
1-13
: Script‑setup case looks good; tiny comment could avoid confusion.In real code ref/computed are imported; here it’s fine for AST purposes. A note helps newcomers.
<script setup> defineProps({ foo: String, bar: Number }) +// test-only: using ref/computed without imports is intentional here const baz = ref('hello') const qux = computed(() => 'world') function handleClick() { console.log('clicked') } </script>
crates/biome_js_analyze/tests/specs/nursery/noVueDuplicateKeys/invalid-duplicate-in-data-object.vue (1)
2-7
: Consider adding the function-return variant too.To cover both shapes used in the wild.
Proposed sibling fixture (new file suggestion):
<script> export default { data () { return { foo: null, foo: null } } } </script>Happy to draft it if you’d like.
crates/biome_js_analyze/tests/specs/nursery/noVueDuplicateKeys/valid-complex-spread.vue (1)
1-30
: Interesting edge case with both data() function and data object.The component defines both a
data
object (Line 16) and adata()
function (Line 24), which is unusual but syntactically valid. The function will take precedence at runtime, effectively overriding the object declaration.While not technically a rule violation, having both declarations might confuse developers:
- data: { - ...foo(), - dat: null - }, - methods: { - ...foo(), - test () {} - }, - data () { - return { - ...dat - } - } + data () { + return { + ...foo(), + dat: null, + ...dat + } + }, + methods: { + ...foo(), + test () {} + }
📜 Review details
Configuration used: Path: .coderabbit.yaml
Review profile: CHILL
Plan: Pro
⛔ Files ignored due to path filters (24)
crates/biome_cli/src/execute/migrate/eslint_any_rule_to_biome.rs
is excluded by!**/migrate/eslint_any_rule_to_biome.rs
and included by**
crates/biome_configuration/src/analyzer/linter/rules.rs
is excluded by!**/rules.rs
and included by**
crates/biome_diagnostics_categories/src/categories.rs
is excluded by!**/categories.rs
and included by**
crates/biome_js_analyze/src/lint/nursery.rs
is excluded by!**/nursery.rs
and included by**
crates/biome_js_analyze/tests/specs/nursery/noVueDuplicateKeys/invalid-asyncdata-data.vue.snap
is excluded by!**/*.snap
and included by**
crates/biome_js_analyze/tests/specs/nursery/noVueDuplicateKeys/invalid-asyncdata-methods.vue.snap
is excluded by!**/*.snap
and included by**
crates/biome_js_analyze/tests/specs/nursery/noVueDuplicateKeys/invalid-duplicate-across-sections.vue.snap
is excluded by!**/*.snap
and included by**
crates/biome_js_analyze/tests/specs/nursery/noVueDuplicateKeys/invalid-duplicate-computed-methods.vue.snap
is excluded by!**/*.snap
and included by**
crates/biome_js_analyze/tests/specs/nursery/noVueDuplicateKeys/invalid-duplicate-data-methods.vue.snap
is excluded by!**/*.snap
and included by**
crates/biome_js_analyze/tests/specs/nursery/noVueDuplicateKeys/invalid-duplicate-in-data-object.vue.snap
is excluded by!**/*.snap
and included by**
crates/biome_js_analyze/tests/specs/nursery/noVueDuplicateKeys/invalid-duplicate-props-data.vue.snap
is excluded by!**/*.snap
and included by**
crates/biome_js_analyze/tests/specs/nursery/noVueDuplicateKeys/invalid-with-setup.vue.snap
is excluded by!**/*.snap
and included by**
crates/biome_js_analyze/tests/specs/nursery/noVueDuplicateKeys/valid-asyncdata.vue.snap
is excluded by!**/*.snap
and included by**
crates/biome_js_analyze/tests/specs/nursery/noVueDuplicateKeys/valid-complex-spread.vue.snap
is excluded by!**/*.snap
and included by**
crates/biome_js_analyze/tests/specs/nursery/noVueDuplicateKeys/valid-data-function.vue.snap
is excluded by!**/*.snap
and included by**
crates/biome_js_analyze/tests/specs/nursery/noVueDuplicateKeys/valid-getter-setter.vue.snap
is excluded by!**/*.snap
and included by**
crates/biome_js_analyze/tests/specs/nursery/noVueDuplicateKeys/valid-script-setup-defineprops.vue.snap
is excluded by!**/*.snap
and included by**
crates/biome_js_analyze/tests/specs/nursery/noVueDuplicateKeys/valid-script-setup-destructure.vue.snap
is excluded by!**/*.snap
and included by**
crates/biome_js_analyze/tests/specs/nursery/noVueDuplicateKeys/valid-script-setup-simple.vue.snap
is excluded by!**/*.snap
and included by**
crates/biome_js_analyze/tests/specs/nursery/noVueDuplicateKeys/valid-unique-keys.vue.snap
is excluded by!**/*.snap
and included by**
crates/biome_js_analyze/tests/specs/nursery/noVueDuplicateKeys/valid-with-spread.vue.snap
is excluded by!**/*.snap
and included by**
crates/biome_unicode_table/src/tables.rs
is excluded by!**/biome_unicode_table/src/tables.rs
and included by**
packages/@biomejs/backend-jsonrpc/src/workspace.ts
is excluded by!**/backend-jsonrpc/src/workspace.ts
and included by**
packages/@biomejs/biome/configuration_schema.json
is excluded by!**/configuration_schema.json
and included by**
📒 Files selected for processing (21)
.changeset/rude-horses-worry.md
(1 hunks)crates/biome_js_analyze/src/lint/nursery/no_vue_duplicate_keys.rs
(1 hunks)crates/biome_js_analyze/tests/specs/nursery/noVueDuplicateKeys/invalid-asyncdata-data.vue
(1 hunks)crates/biome_js_analyze/tests/specs/nursery/noVueDuplicateKeys/invalid-asyncdata-methods.vue
(1 hunks)crates/biome_js_analyze/tests/specs/nursery/noVueDuplicateKeys/invalid-duplicate-across-sections.vue
(1 hunks)crates/biome_js_analyze/tests/specs/nursery/noVueDuplicateKeys/invalid-duplicate-computed-methods.vue
(1 hunks)crates/biome_js_analyze/tests/specs/nursery/noVueDuplicateKeys/invalid-duplicate-data-methods.vue
(1 hunks)crates/biome_js_analyze/tests/specs/nursery/noVueDuplicateKeys/invalid-duplicate-in-data-object.vue
(1 hunks)crates/biome_js_analyze/tests/specs/nursery/noVueDuplicateKeys/invalid-duplicate-props-data.vue
(1 hunks)crates/biome_js_analyze/tests/specs/nursery/noVueDuplicateKeys/invalid-with-setup.vue
(1 hunks)crates/biome_js_analyze/tests/specs/nursery/noVueDuplicateKeys/valid-asyncdata.vue
(1 hunks)crates/biome_js_analyze/tests/specs/nursery/noVueDuplicateKeys/valid-complex-spread.vue
(1 hunks)crates/biome_js_analyze/tests/specs/nursery/noVueDuplicateKeys/valid-data-function.vue
(1 hunks)crates/biome_js_analyze/tests/specs/nursery/noVueDuplicateKeys/valid-getter-setter.vue
(1 hunks)crates/biome_js_analyze/tests/specs/nursery/noVueDuplicateKeys/valid-script-setup-defineprops.vue
(1 hunks)crates/biome_js_analyze/tests/specs/nursery/noVueDuplicateKeys/valid-script-setup-destructure.vue
(1 hunks)crates/biome_js_analyze/tests/specs/nursery/noVueDuplicateKeys/valid-script-setup-simple.vue
(1 hunks)crates/biome_js_analyze/tests/specs/nursery/noVueDuplicateKeys/valid-unique-keys.vue
(1 hunks)crates/biome_js_analyze/tests/specs/nursery/noVueDuplicateKeys/valid-with-spread.vue
(1 hunks)crates/biome_rule_options/src/lib.rs
(1 hunks)crates/biome_rule_options/src/no_vue_duplicate_keys.rs
(1 hunks)
🧰 Additional context used
📓 Path-based instructions (5)
crates/biome_*_{syntax,parser,formatter,analyze,factory,semantic}/**
📄 CodeRabbit inference engine (CLAUDE.md)
Maintain the per-language crate structure: biome_{lang}_{syntax,parser,formatter,analyze,factory,semantic}
Files:
crates/biome_js_analyze/tests/specs/nursery/noVueDuplicateKeys/invalid-asyncdata-data.vue
crates/biome_js_analyze/tests/specs/nursery/noVueDuplicateKeys/valid-script-setup-defineprops.vue
crates/biome_js_analyze/tests/specs/nursery/noVueDuplicateKeys/invalid-duplicate-props-data.vue
crates/biome_js_analyze/tests/specs/nursery/noVueDuplicateKeys/valid-unique-keys.vue
crates/biome_js_analyze/src/lint/nursery/no_vue_duplicate_keys.rs
crates/biome_js_analyze/tests/specs/nursery/noVueDuplicateKeys/invalid-with-setup.vue
crates/biome_js_analyze/tests/specs/nursery/noVueDuplicateKeys/valid-script-setup-simple.vue
crates/biome_js_analyze/tests/specs/nursery/noVueDuplicateKeys/invalid-duplicate-across-sections.vue
crates/biome_js_analyze/tests/specs/nursery/noVueDuplicateKeys/valid-complex-spread.vue
crates/biome_js_analyze/tests/specs/nursery/noVueDuplicateKeys/invalid-duplicate-data-methods.vue
crates/biome_js_analyze/tests/specs/nursery/noVueDuplicateKeys/invalid-duplicate-in-data-object.vue
crates/biome_js_analyze/tests/specs/nursery/noVueDuplicateKeys/valid-asyncdata.vue
crates/biome_js_analyze/tests/specs/nursery/noVueDuplicateKeys/valid-getter-setter.vue
crates/biome_js_analyze/tests/specs/nursery/noVueDuplicateKeys/invalid-duplicate-computed-methods.vue
crates/biome_js_analyze/tests/specs/nursery/noVueDuplicateKeys/valid-with-spread.vue
crates/biome_js_analyze/tests/specs/nursery/noVueDuplicateKeys/invalid-asyncdata-methods.vue
crates/biome_js_analyze/tests/specs/nursery/noVueDuplicateKeys/valid-data-function.vue
crates/biome_js_analyze/tests/specs/nursery/noVueDuplicateKeys/valid-script-setup-destructure.vue
crates/biome_*/**
📄 CodeRabbit inference engine (CLAUDE.md)
Place core crates under /crates/biome_*/
Files:
crates/biome_js_analyze/tests/specs/nursery/noVueDuplicateKeys/invalid-asyncdata-data.vue
crates/biome_rule_options/src/no_vue_duplicate_keys.rs
crates/biome_js_analyze/tests/specs/nursery/noVueDuplicateKeys/valid-script-setup-defineprops.vue
crates/biome_rule_options/src/lib.rs
crates/biome_js_analyze/tests/specs/nursery/noVueDuplicateKeys/invalid-duplicate-props-data.vue
crates/biome_js_analyze/tests/specs/nursery/noVueDuplicateKeys/valid-unique-keys.vue
crates/biome_js_analyze/src/lint/nursery/no_vue_duplicate_keys.rs
crates/biome_js_analyze/tests/specs/nursery/noVueDuplicateKeys/invalid-with-setup.vue
crates/biome_js_analyze/tests/specs/nursery/noVueDuplicateKeys/valid-script-setup-simple.vue
crates/biome_js_analyze/tests/specs/nursery/noVueDuplicateKeys/invalid-duplicate-across-sections.vue
crates/biome_js_analyze/tests/specs/nursery/noVueDuplicateKeys/valid-complex-spread.vue
crates/biome_js_analyze/tests/specs/nursery/noVueDuplicateKeys/invalid-duplicate-data-methods.vue
crates/biome_js_analyze/tests/specs/nursery/noVueDuplicateKeys/invalid-duplicate-in-data-object.vue
crates/biome_js_analyze/tests/specs/nursery/noVueDuplicateKeys/valid-asyncdata.vue
crates/biome_js_analyze/tests/specs/nursery/noVueDuplicateKeys/valid-getter-setter.vue
crates/biome_js_analyze/tests/specs/nursery/noVueDuplicateKeys/invalid-duplicate-computed-methods.vue
crates/biome_js_analyze/tests/specs/nursery/noVueDuplicateKeys/valid-with-spread.vue
crates/biome_js_analyze/tests/specs/nursery/noVueDuplicateKeys/invalid-asyncdata-methods.vue
crates/biome_js_analyze/tests/specs/nursery/noVueDuplicateKeys/valid-data-function.vue
crates/biome_js_analyze/tests/specs/nursery/noVueDuplicateKeys/valid-script-setup-destructure.vue
**/tests/**
📄 CodeRabbit inference engine (CLAUDE.md)
Place test files under a tests/ directory in each crate
Files:
crates/biome_js_analyze/tests/specs/nursery/noVueDuplicateKeys/invalid-asyncdata-data.vue
crates/biome_js_analyze/tests/specs/nursery/noVueDuplicateKeys/valid-script-setup-defineprops.vue
crates/biome_js_analyze/tests/specs/nursery/noVueDuplicateKeys/invalid-duplicate-props-data.vue
crates/biome_js_analyze/tests/specs/nursery/noVueDuplicateKeys/valid-unique-keys.vue
crates/biome_js_analyze/tests/specs/nursery/noVueDuplicateKeys/invalid-with-setup.vue
crates/biome_js_analyze/tests/specs/nursery/noVueDuplicateKeys/valid-script-setup-simple.vue
crates/biome_js_analyze/tests/specs/nursery/noVueDuplicateKeys/invalid-duplicate-across-sections.vue
crates/biome_js_analyze/tests/specs/nursery/noVueDuplicateKeys/valid-complex-spread.vue
crates/biome_js_analyze/tests/specs/nursery/noVueDuplicateKeys/invalid-duplicate-data-methods.vue
crates/biome_js_analyze/tests/specs/nursery/noVueDuplicateKeys/invalid-duplicate-in-data-object.vue
crates/biome_js_analyze/tests/specs/nursery/noVueDuplicateKeys/valid-asyncdata.vue
crates/biome_js_analyze/tests/specs/nursery/noVueDuplicateKeys/valid-getter-setter.vue
crates/biome_js_analyze/tests/specs/nursery/noVueDuplicateKeys/invalid-duplicate-computed-methods.vue
crates/biome_js_analyze/tests/specs/nursery/noVueDuplicateKeys/valid-with-spread.vue
crates/biome_js_analyze/tests/specs/nursery/noVueDuplicateKeys/invalid-asyncdata-methods.vue
crates/biome_js_analyze/tests/specs/nursery/noVueDuplicateKeys/valid-data-function.vue
crates/biome_js_analyze/tests/specs/nursery/noVueDuplicateKeys/valid-script-setup-destructure.vue
.changeset/*.md
📄 CodeRabbit inference engine (CONTRIBUTING.md)
.changeset/*.md
: In changeset files, only use #### or ##### headers; avoid other header levels
Changeset descriptions should use past tense for what you did (e.g., "Added...")
Describe current Biome behavior in present tense within changesets (e.g., "Biome now supports...")
For bug fixes in changesets, start with a link to the issue (e.g., "Fixed #1234: ...")
When referencing rules or assists in changesets, include links to their documentation pages
Include a minimal code block in the changeset when applicable to demonstrate the change
End every sentence in the changeset description with a period
Files:
.changeset/rude-horses-worry.md
**/*.rs
📄 CodeRabbit inference engine (CONTRIBUTING.md)
Format all Rust source files before committing (just f)
Files:
crates/biome_rule_options/src/no_vue_duplicate_keys.rs
crates/biome_rule_options/src/lib.rs
crates/biome_js_analyze/src/lint/nursery/no_vue_duplicate_keys.rs
🧠 Learnings (2)
📚 Learning: 2025-09-10T08:05:22.867Z
Learnt from: CR
PR: biomejs/biome#0
File: crates/biome_analyze/CONTRIBUTING.md:0-0
Timestamp: 2025-09-10T08:05:22.867Z
Learning: Applies to crates/biome_analyze/crates/biome_rule_options/lib/**/*.rs : Options types must implement serialization/deserialization and schema support using derives: `Serialize`, `Deserialize`, `Deserializable`, and `#[cfg_attr(feature = "schema", derive(schemars::JsonSchema))]`
Applied to files:
crates/biome_rule_options/src/no_vue_duplicate_keys.rs
📚 Learning: 2025-09-10T08:05:22.867Z
Learnt from: CR
PR: biomejs/biome#0
File: crates/biome_analyze/CONTRIBUTING.md:0-0
Timestamp: 2025-09-10T08:05:22.867Z
Learning: Applies to crates/biome_analyze/crates/biome_rule_options/lib/**/*.rs : Define per-rule options types in `biome_rule_options` crate (one file per rule, e.g., `lib/use_my_rule.rs`)
Applied to files:
crates/biome_rule_options/src/no_vue_duplicate_keys.rs
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (25)
- GitHub Check: Test Node.js API
- GitHub Check: Bench (biome_module_graph)
- GitHub Check: Bench (biome_html_parser)
- GitHub Check: Bench (biome_package)
- GitHub Check: Bench (biome_html_formatter)
- GitHub Check: Bench (biome_json_analyze)
- GitHub Check: Bench (biome_graphql_parser)
- GitHub Check: Bench (biome_configuration)
- GitHub Check: Bench (biome_graphql_formatter)
- GitHub Check: Bench (biome_css_formatter)
- GitHub Check: Bench (biome_css_analyze)
- GitHub Check: Bench (biome_js_analyze)
- GitHub Check: Bench (biome_json_formatter)
- GitHub Check: Bench (biome_json_parser)
- GitHub Check: Bench (biome_js_formatter)
- GitHub Check: Bench (biome_js_parser)
- GitHub Check: Bench (biome_css_parser)
- GitHub Check: Check JS Files
- GitHub Check: autofix
- GitHub Check: Documentation
- GitHub Check: Check Dependencies
- GitHub Check: Test (depot-ubuntu-24.04-arm-16)
- GitHub Check: Test (depot-windows-2022-16)
- GitHub Check: Lint project (depot-ubuntu-24.04-arm-16)
- GitHub Check: Lint project (depot-windows-2022)
🔇 Additional comments (22)
crates/biome_js_analyze/tests/specs/nursery/noVueDuplicateKeys/valid-getter-setter.vue (1)
3-8
: LGTM: covers accessor-pair nuance.Good guard that get/set under one computed key isn’t treated as duplicates.
crates/biome_js_analyze/tests/specs/nursery/noVueDuplicateKeys/invalid-duplicate-computed-methods.vue (1)
3-12
: LGTM: classic cross-section collision.Solid negative fixture; ensures computed vs methods clash is caught.
crates/biome_js_analyze/tests/specs/nursery/noVueDuplicateKeys/valid-script-setup-simple.vue (1)
1-10
: Add one invalid script-setup collision for completeness.Consider a case where
defineProps<{ foo: string }>()
collides withconst foo = ref(1)
to prove script-setup duplicates are flagged too.Would you like me to draft that fixture?
crates/biome_js_analyze/tests/specs/nursery/noVueDuplicateKeys/invalid-asyncdata-data.vue (1)
3-12
: LGTM: Nuxt-style asyncData vs data conflict.Nice coverage of framework-specific option names.
crates/biome_js_analyze/tests/specs/nursery/noVueDuplicateKeys/invalid-with-setup.vue (1)
3-21
: LGTM: options + setup collision matrix.This neatly exercises props/computed/data/methods/setup all sharing a key.
crates/biome_js_analyze/tests/specs/nursery/noVueDuplicateKeys/invalid-duplicate-props-data.vue (1)
3-10
: LGTM: props vs data duplicate.Straightforward and necessary baseline failure.
crates/biome_rule_options/src/lib.rs (1)
239-239
: Approve: no_vue_duplicate_keys options present and wired.crates/biome_rule_options/src/no_vue_duplicate_keys.rs defines
pub struct NoVueDuplicateKeysOptions {}
and crates/biome_js_analyze/src/lint/nursery/no_vue_duplicate_keys.rs imports and uses it (type Options = NoVueDuplicateKeysOptions
).crates/biome_js_analyze/tests/specs/nursery/noVueDuplicateKeys/valid-data-function.vue (1)
2-19
: LGTM: good “no duplicates across sections” valid fixture.Covers props/computed/data/methods without overlapping keys.
crates/biome_rule_options/src/no_vue_duplicate_keys.rs (2)
1-6
: Options type looks correct and follows derive/schema conventions.Derives, serde attrs, and schema gate are in place. Nice one.
1-6
: Resolved — options module exported and referenced by rulecrates/biome_rule_options/src/lib.rs has
pub mod no_vue_duplicate_keys;
(line 239) and the rule imports/usesNoVueDuplicateKeysOptions
in crates/biome_js_analyze/src/lint/nursery/no_vue_duplicate_keys.rs (use at line 10;type Options = NoVueDuplicateKeysOptions
at line 125).crates/biome_js_analyze/tests/specs/nursery/noVueDuplicateKeys/valid-asyncdata.vue (1)
2-18
: LGTM: distinct keys across asyncData/data/methods.Nice positive control for Nuxt asyncData handling.
crates/biome_js_analyze/tests/specs/nursery/noVueDuplicateKeys/invalid-asyncdata-methods.vue (1)
2-13
: LGTM: clear asyncData ↔ methods collision.This should produce a single, focused diagnostic on “handleClick”.
crates/biome_js_analyze/tests/specs/nursery/noVueDuplicateKeys/valid-unique-keys.vue (1)
2-16
: LGTM: canonical “happy path” fixture.Straightforward baseline with no overlaps.
crates/biome_js_analyze/tests/specs/nursery/noVueDuplicateKeys/invalid-duplicate-in-data-object.vue (1)
2-7
: LGTM: duplicate keys within a data object.Good negative sample for intra‑object duplicates.
crates/biome_js_analyze/tests/specs/nursery/noVueDuplicateKeys/invalid-duplicate-across-sections.vue (1)
2-15
: Group diagnostics: one primary + related notes (avoid spam)Snapshot found at crates/biome_js_analyze/tests/specs/nursery/noVueDuplicateKeys/invalid-duplicate-across-sections.vue.snap — verify the rule emits a single primary diagnostic with related notes for props/computed/data/methods instead of multiple top-level diagnostics.
crates/biome_js_analyze/tests/specs/nursery/noVueDuplicateKeys/valid-with-spread.vue (1)
1-17
: Test case looks appropriate for spread syntax validation.Even if a key name does not conflict in the <script> tag itself, it still may lead to a conflict in the since Vue allows directly accessing these keys from there. This fixture correctly demonstrates a scenario where spread operators are used in props and computed sections without introducing duplicate keys.
crates/biome_js_analyze/tests/specs/nursery/noVueDuplicateKeys/invalid-duplicate-data-methods.vue (1)
1-14
: Perfect test case for cross-option duplicate detection.This rule prevents duplicate props/data/methods/etc. key names defined on a component. This fixture correctly demonstrates the problematic scenario where the same identifier (
message
) appears in both data and methods options, which would cause template access conflicts.crates/biome_js_analyze/tests/specs/nursery/noVueDuplicateKeys/valid-script-setup-destructure.vue (1)
1-6
: Good coverage for script setup syntax.The test case appropriately demonstrates that destructured props in script setup don't conflict with locally declared variables, which is correct behaviour since they exist in different scopes.
crates/biome_js_analyze/src/lint/nursery/no_vue_duplicate_keys.rs (4)
14-119
: Comprehensive rule documentation with clear examples.The documentation effectively explains the purpose and provides relevant examples for both invalid and valid cases. The rule metadata properly references the equivalent ESLint rule.
121-160
: Rule implementation logic is sound.The core logic correctly:
- Uses VueComponent framework to parse Vue files
- Collects all declarations across component sections
- Groups by key name to identify duplicates
- Returns state objects for each duplicate key
162-190
: Diagnostic output provides helpful context.The diagnostic implementation effectively shows the first occurrence as the primary diagnostic and subsequent occurrences as related information, with a helpful note explaining the template access conflict issue.
192-195
: Simple and appropriate state structure.The RuleState struct efficiently stores the duplicate key information needed for diagnostic generation.
export default { | ||
asyncData() { | ||
return { | ||
foo: 'bar' | ||
} | ||
}, | ||
data() { | ||
return { | ||
baz: 'qux' | ||
} | ||
}, | ||
methods: { | ||
handleClick() { | ||
console.log('click'); | ||
} | ||
} | ||
} |
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.
🛠️ Refactor suggestion
🧩 Analysis chain
Double‑check asyncData is included in the rule’s sections.
Just to be safe that the rule accounts for Nuxt’s asyncData surface.
🏁 Script executed:
#!/bin/bash
# Grep the rule for all recognised sections
rg -nP 'asyncData|props|data|computed|methods|setup' crates/biome_js_analyze/src/lint/nursery/no_vue_duplicate_keys.rs
Length of output: 642
Add asyncData to recognised Vue option sections
Search shows no 'asyncData' in crates/biome_js_analyze/src/lint/nursery/no_vue_duplicate_keys.rs — add 'asyncData' to the rule's option matcher and update/cover it in tests (crates/biome_js_analyze/tests/specs/nursery/noVueDuplicateKeys/valid-asyncdata.vue).
🤖 Prompt for AI Agents
In
crates/biome_js_analyze/tests/specs/nursery/noVueDuplicateKeys/valid-asyncdata.vue
lines 2-18, the test uses the Vue option asyncData but the linter rule
crates/biome_js_analyze/src/lint/nursery/no_vue_duplicate_keys.rs does not
recognize asyncData; update that rule's option matcher to include "asyncData" as
a recognized option name, add/adjust any pattern matching or tests that
enumerate Vue option sections, and ensure the test file is covered (or add a
corresponding test case) so asyncData is treated the same as data/methods for
duplicate key checks.
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.
There's invalid-asyncdata-data
test which proves the otherwise.
CodSpeed Performance ReportMerging #7542 will not alter performanceComparing Summary
|
// Collect all declarations across all Vue component sections | ||
for declaration in component.declarations(VueDeclarationCollectionFilter::all()) { | ||
if let Some(name) = declaration.declaration_name() { | ||
let key = name.text().to_string(); |
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.
You should use trimmed_text
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.
TokenText doesn't have trimmed_text
.
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.
There's token_text_trimmed()
on SyntaxToken
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.
Added missing token_text_trimmed()
calls to the vue_component
.
crates/biome_js_analyze/src/lint/nursery/no_vue_duplicate_keys.rs
Outdated
Show resolved
Hide resolved
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.
Actionable comments posted: 0
🧹 Nitpick comments (6)
crates/biome_js_analyze/tests/specs/nursery/noVueDuplicateKeys/invalid-duplicate-props-data.vue.snap.new (1)
43-45
: Broaden the help note to mention all covered options.The note lists “props, data, methods, computed” but the rule intends to also cover
setup
(and tests includeasyncData
). Please update the note text in the rule and re-record snapshots.crates/biome_js_analyze/tests/specs/nursery/noVueDuplicateKeys/invalid-asyncdata-methods.vue.snap.new (1)
45-46
: IncludeasyncData
in the guidance note.The rule flags
asyncData
vsmethods
, but the message omitsasyncData
. Update the note in the rule and re-record.crates/biome_js_analyze/src/lint/nursery/no_vue_duplicate_keys.rs (4)
15-21
: Docs: name all covered options for clarity.Mention
asyncData
explicitly alongsideprops
,data
,computed
,methods
,setup
to match tests and intent.
147-158
: Stabilise diagnostic ordering across runs.
FxHashMap
iteration order isn’t guaranteed; snapshot order could flap if multiple keys duplicate. Sort by first occurrence before emitting signals.Apply:
- // Find duplicates - key_declarations - .into_iter() - .filter_map(|(key, declarations)| { - if declarations.len() > 1 { - Some(RuleState { key, declarations }) - } else { - None - } - }) - .collect::<Box<[_]>>() + // Find duplicates + let mut duplicates: Vec<_> = key_declarations + .into_iter() + .filter_map(|(key, declarations)| { + if declarations.len() > 1 { + Some(RuleState { key, declarations }) + } else { + None + } + }) + .collect(); + // Keep diagnostics stable across runs + duplicates.sort_by_key(|state| { + state + .declarations + .first() + .and_then(|d| d.declaration_name_range().map(|r| r.start())) + }); + duplicates.into_boxed_slice()
183-185
: Tighten the note: includesetup
/asyncData
and avoid a fixed list.Broaden the message so snapshots don’t need churn as support expands.
Apply:
- diagnostic = diagnostic.note(markup! { - "Keys defined in different Vue component options (props, data, methods, computed) can conflict when accessed in the template. Rename the key to avoid conflicts." - }); + diagnostic = diagnostic.note(markup! { + "Keys defined in different Vue component options (e.g., props, data, computed, methods, setup, asyncData) can conflict when accessed in the template. Rename the key to avoid conflicts." + });
191-194
: MakeRuleState
private.No external use; tighten visibility.
Apply:
-pub struct RuleState { +struct RuleState {
📜 Review details
Configuration used: Path: .coderabbit.yaml
Review profile: CHILL
Plan: Pro
📒 Files selected for processing (9)
crates/biome_js_analyze/src/lint/nursery/no_vue_duplicate_keys.rs
(1 hunks)crates/biome_js_analyze/tests/specs/nursery/noVueDuplicateKeys/invalid-asyncdata-data.vue.snap.new
(1 hunks)crates/biome_js_analyze/tests/specs/nursery/noVueDuplicateKeys/invalid-asyncdata-methods.vue.snap.new
(1 hunks)crates/biome_js_analyze/tests/specs/nursery/noVueDuplicateKeys/invalid-duplicate-across-sections.vue.snap.new
(1 hunks)crates/biome_js_analyze/tests/specs/nursery/noVueDuplicateKeys/invalid-duplicate-computed-methods.vue.snap.new
(1 hunks)crates/biome_js_analyze/tests/specs/nursery/noVueDuplicateKeys/invalid-duplicate-data-methods.vue.snap.new
(1 hunks)crates/biome_js_analyze/tests/specs/nursery/noVueDuplicateKeys/invalid-duplicate-in-data-object.vue.snap.new
(1 hunks)crates/biome_js_analyze/tests/specs/nursery/noVueDuplicateKeys/invalid-duplicate-props-data.vue.snap.new
(1 hunks)crates/biome_js_analyze/tests/specs/nursery/noVueDuplicateKeys/invalid-with-setup.vue.snap.new
(1 hunks)
✅ Files skipped from review due to trivial changes (3)
- crates/biome_js_analyze/tests/specs/nursery/noVueDuplicateKeys/invalid-duplicate-in-data-object.vue.snap.new
- crates/biome_js_analyze/tests/specs/nursery/noVueDuplicateKeys/invalid-asyncdata-data.vue.snap.new
- crates/biome_js_analyze/tests/specs/nursery/noVueDuplicateKeys/invalid-duplicate-data-methods.vue.snap.new
🧰 Additional context used
📓 Path-based instructions (4)
crates/biome_*_{syntax,parser,formatter,analyze,factory,semantic}/**
📄 CodeRabbit inference engine (CLAUDE.md)
Maintain the per-language crate structure: biome_{lang}_{syntax,parser,formatter,analyze,factory,semantic}
Files:
crates/biome_js_analyze/tests/specs/nursery/noVueDuplicateKeys/invalid-asyncdata-methods.vue.snap.new
crates/biome_js_analyze/src/lint/nursery/no_vue_duplicate_keys.rs
crates/biome_js_analyze/tests/specs/nursery/noVueDuplicateKeys/invalid-duplicate-computed-methods.vue.snap.new
crates/biome_js_analyze/tests/specs/nursery/noVueDuplicateKeys/invalid-duplicate-props-data.vue.snap.new
crates/biome_js_analyze/tests/specs/nursery/noVueDuplicateKeys/invalid-duplicate-across-sections.vue.snap.new
crates/biome_js_analyze/tests/specs/nursery/noVueDuplicateKeys/invalid-with-setup.vue.snap.new
crates/biome_*/**
📄 CodeRabbit inference engine (CLAUDE.md)
Place core crates under /crates/biome_*/
Files:
crates/biome_js_analyze/tests/specs/nursery/noVueDuplicateKeys/invalid-asyncdata-methods.vue.snap.new
crates/biome_js_analyze/src/lint/nursery/no_vue_duplicate_keys.rs
crates/biome_js_analyze/tests/specs/nursery/noVueDuplicateKeys/invalid-duplicate-computed-methods.vue.snap.new
crates/biome_js_analyze/tests/specs/nursery/noVueDuplicateKeys/invalid-duplicate-props-data.vue.snap.new
crates/biome_js_analyze/tests/specs/nursery/noVueDuplicateKeys/invalid-duplicate-across-sections.vue.snap.new
crates/biome_js_analyze/tests/specs/nursery/noVueDuplicateKeys/invalid-with-setup.vue.snap.new
**/tests/**
📄 CodeRabbit inference engine (CLAUDE.md)
Place test files under a tests/ directory in each crate
Files:
crates/biome_js_analyze/tests/specs/nursery/noVueDuplicateKeys/invalid-asyncdata-methods.vue.snap.new
crates/biome_js_analyze/tests/specs/nursery/noVueDuplicateKeys/invalid-duplicate-computed-methods.vue.snap.new
crates/biome_js_analyze/tests/specs/nursery/noVueDuplicateKeys/invalid-duplicate-props-data.vue.snap.new
crates/biome_js_analyze/tests/specs/nursery/noVueDuplicateKeys/invalid-duplicate-across-sections.vue.snap.new
crates/biome_js_analyze/tests/specs/nursery/noVueDuplicateKeys/invalid-with-setup.vue.snap.new
**/*.rs
📄 CodeRabbit inference engine (CONTRIBUTING.md)
Format all Rust source files before committing (just f)
Files:
crates/biome_js_analyze/src/lint/nursery/no_vue_duplicate_keys.rs
🧠 Learnings (1)
📚 Learning: 2025-09-10T08:05:22.867Z
Learnt from: CR
PR: biomejs/biome#0
File: crates/biome_analyze/CONTRIBUTING.md:0-0
Timestamp: 2025-09-10T08:05:22.867Z
Learning: Applies to crates/biome_analyze/crates/**/tests/specs/**/*.jsonc : Snapshot test `.jsonc` files must contain an array of code snippets (strings); these run in script mode (no ESM syntax)
Applied to files:
crates/biome_js_analyze/tests/specs/nursery/noVueDuplicateKeys/invalid-duplicate-props-data.vue.snap.new
🧬 Code graph analysis (1)
crates/biome_js_analyze/src/lint/nursery/no_vue_duplicate_keys.rs (1)
crates/biome_analyze/src/rule.rs (4)
recommended
(554-557)domains
(584-587)sources
(569-572)same
(241-246)
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (25)
- GitHub Check: Documentation
- GitHub Check: Test (depot-ubuntu-24.04-arm-16)
- GitHub Check: Test (depot-windows-2022-16)
- GitHub Check: Check Dependencies
- GitHub Check: Lint project (depot-ubuntu-24.04-arm-16)
- GitHub Check: Lint project (depot-windows-2022)
- GitHub Check: Bench (biome_html_parser)
- GitHub Check: Bench (biome_module_graph)
- GitHub Check: Check JS Files
- GitHub Check: Bench (biome_package)
- GitHub Check: Bench (biome_html_formatter)
- GitHub Check: Bench (biome_configuration)
- GitHub Check: Bench (biome_graphql_formatter)
- GitHub Check: Bench (biome_json_analyze)
- GitHub Check: Bench (biome_json_formatter)
- GitHub Check: Bench (biome_js_analyze)
- GitHub Check: Bench (biome_css_formatter)
- GitHub Check: Bench (biome_json_parser)
- GitHub Check: Bench (biome_js_formatter)
- GitHub Check: Bench (biome_graphql_parser)
- GitHub Check: Bench (biome_css_parser)
- GitHub Check: Bench (biome_css_analyze)
- GitHub Check: Bench (biome_js_parser)
- GitHub Check: autofix
- GitHub Check: Test Node.js API
🔇 Additional comments (4)
crates/biome_js_analyze/tests/specs/nursery/noVueDuplicateKeys/invalid-duplicate-across-sections.vue.snap.new (1)
27-66
: Snapshot looks solid.Primary/secondary locations and messaging read well.
crates/biome_js_analyze/tests/specs/nursery/noVueDuplicateKeys/invalid-duplicate-computed-methods.vue.snap.new (1)
25-47
: Good coverage for computed vs methods.Accurate ranges and a clear message.
crates/biome_js_analyze/src/lint/nursery/no_vue_duplicate_keys.rs (1)
114-118
: Nursery rule in “recommended” set—confirm policy.Nursery rules are typically opt‑in. If that’s the project policy, set
recommended: false
until graduation.Would you like me to flip it? Proposed diff:
- recommended: true, + recommended: false,crates/biome_js_analyze/tests/specs/nursery/noVueDuplicateKeys/invalid-with-setup.vue.snap.new (1)
62-74
:setup
duplicate isn’t surfaced in related locations.The component returns foo from setup, but the diagnostic snapshot marks duplicates for props/data/methods/computed and does not attach an “also defined here” entry to the setup return.
Evidence: crates/biome_js_analyze/tests/specs/nursery/noVueDuplicateKeys/invalid-with-setup.vue — setup() at line 15 (returns foo); .snap/.snap.new show setup occurrences at lines 20/21 with NO_ALSO_DEFINED_WITHIN_7_LINES while the “i Key foo is also defined here.” lines are at ~61/62.
Action: either include setup-return keys in the duplicate-key collection or update the tests/snapshots to match the intended behaviour.
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.
Actionable comments posted: 0
🧹 Nitpick comments (1)
crates/biome_js_analyze/src/frameworks/vue/vue_component.rs (1)
752-768
: Align imports: also use trimmed token text for setup import namesFor consistency across all VueDeclarationName impls and to avoid edge-case trivia, use
token_text_trimmed()
here too.Apply this diff:
Some( local_name .ok()? .as_js_identifier_binding()? .name_token() .ok()? - .token_text(), + .token_text_trimmed(), )
📜 Review details
Configuration used: Path: .coderabbit.yaml
Review profile: CHILL
Plan: Pro
⛔ Files ignored due to path filters (8)
crates/biome_js_analyze/tests/specs/nursery/noVueDuplicateKeys/invalid-asyncdata-data.vue.snap
is excluded by!**/*.snap
and included by**
crates/biome_js_analyze/tests/specs/nursery/noVueDuplicateKeys/invalid-asyncdata-methods.vue.snap
is excluded by!**/*.snap
and included by**
crates/biome_js_analyze/tests/specs/nursery/noVueDuplicateKeys/invalid-duplicate-across-sections.vue.snap
is excluded by!**/*.snap
and included by**
crates/biome_js_analyze/tests/specs/nursery/noVueDuplicateKeys/invalid-duplicate-computed-methods.vue.snap
is excluded by!**/*.snap
and included by**
crates/biome_js_analyze/tests/specs/nursery/noVueDuplicateKeys/invalid-duplicate-data-methods.vue.snap
is excluded by!**/*.snap
and included by**
crates/biome_js_analyze/tests/specs/nursery/noVueDuplicateKeys/invalid-duplicate-in-data-object.vue.snap
is excluded by!**/*.snap
and included by**
crates/biome_js_analyze/tests/specs/nursery/noVueDuplicateKeys/invalid-duplicate-props-data.vue.snap
is excluded by!**/*.snap
and included by**
crates/biome_js_analyze/tests/specs/nursery/noVueDuplicateKeys/invalid-with-setup.vue.snap
is excluded by!**/*.snap
and included by**
📒 Files selected for processing (1)
crates/biome_js_analyze/src/frameworks/vue/vue_component.rs
(1 hunks)
🧰 Additional context used
📓 Path-based instructions (3)
crates/biome_*_{syntax,parser,formatter,analyze,factory,semantic}/**
📄 CodeRabbit inference engine (CLAUDE.md)
Maintain the per-language crate structure: biome_{lang}_{syntax,parser,formatter,analyze,factory,semantic}
Files:
crates/biome_js_analyze/src/frameworks/vue/vue_component.rs
crates/biome_*/**
📄 CodeRabbit inference engine (CLAUDE.md)
Place core crates under /crates/biome_*/
Files:
crates/biome_js_analyze/src/frameworks/vue/vue_component.rs
**/*.rs
📄 CodeRabbit inference engine (CONTRIBUTING.md)
Format all Rust source files before committing (just f)
Files:
crates/biome_js_analyze/src/frameworks/vue/vue_component.rs
🔇 Additional comments (1)
crates/biome_js_analyze/src/frameworks/vue/vue_component.rs (1)
711-724
: Good normalisation: use trimmed token text for setup namesSwitching to
token_text_trimmed()
aligns withtext_trimmed_range()
and avoids stray trivia causing false “duplicate key” matches. Looks solid.
065c2c2
to
62fea3c
Compare
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.
Actionable comments posted: 0
🧹 Nitpick comments (1)
crates/biome_rule_options/src/no_vue_duplicate_keys.rs (1)
5-6
: Add a brief doc comment for generated docs/schemas.Helps users understand why the options exist even if empty today.
Apply this diff:
#[serde(rename_all = "camelCase", deny_unknown_fields, default)] +/// Options for the `noVueDuplicateKeys` rule. +/// Currently empty; reserved for future configuration. pub struct NoVueDuplicateKeysOptions {}
📜 Review details
Configuration used: Path: .coderabbit.yaml
Review profile: CHILL
Plan: Pro
⛔ Files ignored due to path filters (23)
crates/biome_cli/src/execute/migrate/eslint_any_rule_to_biome.rs
is excluded by!**/migrate/eslint_any_rule_to_biome.rs
and included by**
crates/biome_configuration/src/analyzer/linter/rules.rs
is excluded by!**/rules.rs
and included by**
crates/biome_diagnostics_categories/src/categories.rs
is excluded by!**/categories.rs
and included by**
crates/biome_js_analyze/src/lint/nursery.rs
is excluded by!**/nursery.rs
and included by**
crates/biome_js_analyze/tests/specs/nursery/noVueDuplicateKeys/invalid-asyncdata-data.vue.snap
is excluded by!**/*.snap
and included by**
crates/biome_js_analyze/tests/specs/nursery/noVueDuplicateKeys/invalid-asyncdata-methods.vue.snap
is excluded by!**/*.snap
and included by**
crates/biome_js_analyze/tests/specs/nursery/noVueDuplicateKeys/invalid-duplicate-across-sections.vue.snap
is excluded by!**/*.snap
and included by**
crates/biome_js_analyze/tests/specs/nursery/noVueDuplicateKeys/invalid-duplicate-computed-methods.vue.snap
is excluded by!**/*.snap
and included by**
crates/biome_js_analyze/tests/specs/nursery/noVueDuplicateKeys/invalid-duplicate-data-methods.vue.snap
is excluded by!**/*.snap
and included by**
crates/biome_js_analyze/tests/specs/nursery/noVueDuplicateKeys/invalid-duplicate-in-data-object.vue.snap
is excluded by!**/*.snap
and included by**
crates/biome_js_analyze/tests/specs/nursery/noVueDuplicateKeys/invalid-duplicate-props-data.vue.snap
is excluded by!**/*.snap
and included by**
crates/biome_js_analyze/tests/specs/nursery/noVueDuplicateKeys/invalid-with-setup.vue.snap
is excluded by!**/*.snap
and included by**
crates/biome_js_analyze/tests/specs/nursery/noVueDuplicateKeys/valid-asyncdata.vue.snap
is excluded by!**/*.snap
and included by**
crates/biome_js_analyze/tests/specs/nursery/noVueDuplicateKeys/valid-complex-spread.vue.snap
is excluded by!**/*.snap
and included by**
crates/biome_js_analyze/tests/specs/nursery/noVueDuplicateKeys/valid-data-function.vue.snap
is excluded by!**/*.snap
and included by**
crates/biome_js_analyze/tests/specs/nursery/noVueDuplicateKeys/valid-getter-setter.vue.snap
is excluded by!**/*.snap
and included by**
crates/biome_js_analyze/tests/specs/nursery/noVueDuplicateKeys/valid-script-setup-defineprops.vue.snap
is excluded by!**/*.snap
and included by**
crates/biome_js_analyze/tests/specs/nursery/noVueDuplicateKeys/valid-script-setup-destructure.vue.snap
is excluded by!**/*.snap
and included by**
crates/biome_js_analyze/tests/specs/nursery/noVueDuplicateKeys/valid-script-setup-simple.vue.snap
is excluded by!**/*.snap
and included by**
crates/biome_js_analyze/tests/specs/nursery/noVueDuplicateKeys/valid-unique-keys.vue.snap
is excluded by!**/*.snap
and included by**
crates/biome_js_analyze/tests/specs/nursery/noVueDuplicateKeys/valid-with-spread.vue.snap
is excluded by!**/*.snap
and included by**
packages/@biomejs/backend-jsonrpc/src/workspace.ts
is excluded by!**/backend-jsonrpc/src/workspace.ts
and included by**
packages/@biomejs/biome/configuration_schema.json
is excluded by!**/configuration_schema.json
and included by**
📒 Files selected for processing (22)
.changeset/rude-horses-worry.md
(1 hunks)crates/biome_js_analyze/src/frameworks/vue/vue_component.rs
(1 hunks)crates/biome_js_analyze/src/lint/nursery/no_vue_duplicate_keys.rs
(1 hunks)crates/biome_js_analyze/tests/specs/nursery/noVueDuplicateKeys/invalid-asyncdata-data.vue
(1 hunks)crates/biome_js_analyze/tests/specs/nursery/noVueDuplicateKeys/invalid-asyncdata-methods.vue
(1 hunks)crates/biome_js_analyze/tests/specs/nursery/noVueDuplicateKeys/invalid-duplicate-across-sections.vue
(1 hunks)crates/biome_js_analyze/tests/specs/nursery/noVueDuplicateKeys/invalid-duplicate-computed-methods.vue
(1 hunks)crates/biome_js_analyze/tests/specs/nursery/noVueDuplicateKeys/invalid-duplicate-data-methods.vue
(1 hunks)crates/biome_js_analyze/tests/specs/nursery/noVueDuplicateKeys/invalid-duplicate-in-data-object.vue
(1 hunks)crates/biome_js_analyze/tests/specs/nursery/noVueDuplicateKeys/invalid-duplicate-props-data.vue
(1 hunks)crates/biome_js_analyze/tests/specs/nursery/noVueDuplicateKeys/invalid-with-setup.vue
(1 hunks)crates/biome_js_analyze/tests/specs/nursery/noVueDuplicateKeys/valid-asyncdata.vue
(1 hunks)crates/biome_js_analyze/tests/specs/nursery/noVueDuplicateKeys/valid-complex-spread.vue
(1 hunks)crates/biome_js_analyze/tests/specs/nursery/noVueDuplicateKeys/valid-data-function.vue
(1 hunks)crates/biome_js_analyze/tests/specs/nursery/noVueDuplicateKeys/valid-getter-setter.vue
(1 hunks)crates/biome_js_analyze/tests/specs/nursery/noVueDuplicateKeys/valid-script-setup-defineprops.vue
(1 hunks)crates/biome_js_analyze/tests/specs/nursery/noVueDuplicateKeys/valid-script-setup-destructure.vue
(1 hunks)crates/biome_js_analyze/tests/specs/nursery/noVueDuplicateKeys/valid-script-setup-simple.vue
(1 hunks)crates/biome_js_analyze/tests/specs/nursery/noVueDuplicateKeys/valid-unique-keys.vue
(1 hunks)crates/biome_js_analyze/tests/specs/nursery/noVueDuplicateKeys/valid-with-spread.vue
(1 hunks)crates/biome_rule_options/src/lib.rs
(1 hunks)crates/biome_rule_options/src/no_vue_duplicate_keys.rs
(1 hunks)
🚧 Files skipped from review as they are similar to previous changes (19)
- crates/biome_rule_options/src/lib.rs
- crates/biome_js_analyze/tests/specs/nursery/noVueDuplicateKeys/valid-data-function.vue
- crates/biome_js_analyze/tests/specs/nursery/noVueDuplicateKeys/valid-script-setup-simple.vue
- crates/biome_js_analyze/tests/specs/nursery/noVueDuplicateKeys/valid-asyncdata.vue
- crates/biome_js_analyze/tests/specs/nursery/noVueDuplicateKeys/invalid-duplicate-computed-methods.vue
- crates/biome_js_analyze/tests/specs/nursery/noVueDuplicateKeys/invalid-duplicate-in-data-object.vue
- crates/biome_js_analyze/tests/specs/nursery/noVueDuplicateKeys/valid-with-spread.vue
- crates/biome_js_analyze/tests/specs/nursery/noVueDuplicateKeys/valid-script-setup-destructure.vue
- crates/biome_js_analyze/tests/specs/nursery/noVueDuplicateKeys/valid-complex-spread.vue
- .changeset/rude-horses-worry.md
- crates/biome_js_analyze/tests/specs/nursery/noVueDuplicateKeys/valid-getter-setter.vue
- crates/biome_js_analyze/src/lint/nursery/no_vue_duplicate_keys.rs
- crates/biome_js_analyze/src/frameworks/vue/vue_component.rs
- crates/biome_js_analyze/tests/specs/nursery/noVueDuplicateKeys/valid-unique-keys.vue
- crates/biome_js_analyze/tests/specs/nursery/noVueDuplicateKeys/valid-script-setup-defineprops.vue
- crates/biome_js_analyze/tests/specs/nursery/noVueDuplicateKeys/invalid-with-setup.vue
- crates/biome_js_analyze/tests/specs/nursery/noVueDuplicateKeys/invalid-duplicate-data-methods.vue
- crates/biome_js_analyze/tests/specs/nursery/noVueDuplicateKeys/invalid-asyncdata-data.vue
- crates/biome_js_analyze/tests/specs/nursery/noVueDuplicateKeys/invalid-asyncdata-methods.vue
🧰 Additional context used
📓 Path-based instructions (4)
crates/biome_*_{syntax,parser,formatter,analyze,factory,semantic}/**
📄 CodeRabbit inference engine (CLAUDE.md)
Maintain the per-language crate structure: biome_{lang}_{syntax,parser,formatter,analyze,factory,semantic}
Files:
crates/biome_js_analyze/tests/specs/nursery/noVueDuplicateKeys/invalid-duplicate-across-sections.vue
crates/biome_js_analyze/tests/specs/nursery/noVueDuplicateKeys/invalid-duplicate-props-data.vue
crates/biome_*/**
📄 CodeRabbit inference engine (CLAUDE.md)
Place core crates under /crates/biome_*/
Files:
crates/biome_js_analyze/tests/specs/nursery/noVueDuplicateKeys/invalid-duplicate-across-sections.vue
crates/biome_js_analyze/tests/specs/nursery/noVueDuplicateKeys/invalid-duplicate-props-data.vue
crates/biome_rule_options/src/no_vue_duplicate_keys.rs
**/tests/**
📄 CodeRabbit inference engine (CLAUDE.md)
Place test files under a tests/ directory in each crate
Files:
crates/biome_js_analyze/tests/specs/nursery/noVueDuplicateKeys/invalid-duplicate-across-sections.vue
crates/biome_js_analyze/tests/specs/nursery/noVueDuplicateKeys/invalid-duplicate-props-data.vue
**/*.rs
📄 CodeRabbit inference engine (CONTRIBUTING.md)
Format all Rust source files before committing (just f)
Files:
crates/biome_rule_options/src/no_vue_duplicate_keys.rs
🧠 Learnings (2)
📚 Learning: 2025-09-10T08:05:22.867Z
Learnt from: CR
PR: biomejs/biome#0
File: crates/biome_analyze/CONTRIBUTING.md:0-0
Timestamp: 2025-09-10T08:05:22.867Z
Learning: Applies to crates/biome_analyze/crates/biome_rule_options/lib/**/*.rs : Options types must implement serialization/deserialization and schema support using derives: `Serialize`, `Deserialize`, `Deserializable`, and `#[cfg_attr(feature = "schema", derive(schemars::JsonSchema))]`
Applied to files:
crates/biome_rule_options/src/no_vue_duplicate_keys.rs
📚 Learning: 2025-09-10T08:05:22.867Z
Learnt from: CR
PR: biomejs/biome#0
File: crates/biome_analyze/CONTRIBUTING.md:0-0
Timestamp: 2025-09-10T08:05:22.867Z
Learning: Applies to crates/biome_analyze/crates/biome_rule_options/lib/**/*.rs : Define per-rule options types in `biome_rule_options` crate (one file per rule, e.g., `lib/use_my_rule.rs`)
Applied to files:
crates/biome_rule_options/src/no_vue_duplicate_keys.rs
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (25)
- GitHub Check: Test (depot-ubuntu-24.04-arm-16)
- GitHub Check: Test (depot-windows-2022-16)
- GitHub Check: Lint project (depot-windows-2022)
- GitHub Check: Lint project (depot-ubuntu-24.04-arm-16)
- GitHub Check: Documentation
- GitHub Check: Check Dependencies
- GitHub Check: Bench (biome_html_formatter)
- GitHub Check: Check JS Files
- GitHub Check: Bench (biome_graphql_formatter)
- GitHub Check: Bench (biome_package)
- GitHub Check: Bench (biome_configuration)
- GitHub Check: Bench (biome_module_graph)
- GitHub Check: Bench (biome_json_analyze)
- GitHub Check: Bench (biome_html_parser)
- GitHub Check: Bench (biome_graphql_parser)
- GitHub Check: Bench (biome_json_formatter)
- GitHub Check: Bench (biome_js_formatter)
- GitHub Check: Bench (biome_json_parser)
- GitHub Check: Bench (biome_css_formatter)
- GitHub Check: Bench (biome_js_analyze)
- GitHub Check: Bench (biome_css_parser)
- GitHub Check: Bench (biome_css_analyze)
- GitHub Check: Bench (biome_js_parser)
- GitHub Check: Test Node.js API
- GitHub Check: autofix
🔇 Additional comments (4)
crates/biome_js_analyze/tests/specs/nursery/noVueDuplicateKeys/invalid-duplicate-props-data.vue (1)
1-12
: Good negative fixture: clear props/data collision.Covers object-style props vs data with the same key; perfect for exercising the rule.
crates/biome_js_analyze/tests/specs/nursery/noVueDuplicateKeys/invalid-duplicate-across-sections.vue (1)
2-15
: Nice cross-section coverage.Array-style props plus duplicates in computed, data, and methods gives broad, realistic coverage.
crates/biome_rule_options/src/no_vue_duplicate_keys.rs (2)
1-6
: Derives and serde config match contributor guide.Empty options struct with Deserialize/Deserializable/Serialize and schema cfg is spot on.
1-6
: Export & wiring verified — no changes required. The module is exported in crates/biome_rule_options/src/lib.rs and the rule imports/uses NoVueDuplicateKeysOptions in crates/biome_js_analyze/src/lint/nursery/no_vue_duplicate_keys.rs.
Summary
Added the rule
noVueDuplicateKeys
, which prevents duplicate keys in Vue component definitions.This rule prevents the use of duplicate keys across different Vue component options such as
props
,data
,computed
,methods
, andsetup
. Even if keys don't conflict in the script tag, they may cause issues in the template since Vue allows direct access to these keys.Invalid examples
Valid examples
Test Plan
Tests are included
Docs
Docs are included