+
Skip to content

feat(biome_js_analyze): noVueDataObjectDeclaration #6574

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

Open
wants to merge 8 commits into
base: main
Choose a base branch
from

Conversation

amousa11
Copy link

@amousa11 amousa11 commented Jun 27, 2025

Summary

Port vue/no-deprecated-data-object-declaration and /vue/no-shared-component-data from eslint-plugin-vue -#6300

closes #6300

Test Plan

Copy link

changeset-bot bot commented Jun 27, 2025

⚠️ No Changeset found

Latest commit: fcce177

Merging this PR will not cause a version bump for any packages. If these changes should not result in a new version, you're good to go. If these changes should result in a version bump, you need to add a changeset.

This PR includes no changesets

When changesets are added to this PR, you'll see the packages that this PR includes changesets for and the associated semver types

Click here to learn what changesets are, and how to add one.

Click here if you're a maintainer who wants to add a changeset to this PR

@github-actions github-actions bot added A-Project Area: project A-Linter Area: linter L-JavaScript Language: JavaScript and super languages A-Diagnostic Area: diagnostocis labels Jun 27, 2025
Copy link
Contributor

@dyc3 dyc3 left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The filtering needs to be a little more careful to prevent false positives. Could be nice to bring over test cases from the source rule.

Comment on lines 62 to 78
fn run(ctx: &RuleContext<Self>) -> Self::Signals {
let member = ctx.query();

if let Ok(member_name) = member.name() {
if let Some(name) = member_name.name() {
if name.trim() == "data" {
if let Ok(value) = member.value() {
match value {
AnyJsExpression::JsIdentifierExpression(_)
| AnyJsExpression::JsArrowFunctionExpression(_)
| AnyJsExpression::JsFunctionExpression(_) => return None,
_ => return Some(()),
}
}
}
}
}
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Needs to be filtered so that it only runs in .vue files.

Comment on lines 65 to 78
if let Ok(member_name) = member.name() {
if let Some(name) = member_name.name() {
if name.trim() == "data" {
if let Ok(value) = member.value() {
match value {
AnyJsExpression::JsIdentifierExpression(_)
| AnyJsExpression::JsArrowFunctionExpression(_)
| AnyJsExpression::JsFunctionExpression(_) => return None,
_ => return Some(()),
}
}
}
}
}
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This needs to make sure that the data member is at the specific level that we are expecting. This would be a false positive:

{
    methods: {
        foo() {
            const bar = {
                data: {}
            }
        }
    }
}

Copy link
Author

@amousa11 amousa11 Jul 1, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

d1c004b - I'm hoping this covers all the cases we need. Let me know if i'm still missing any here. I added this example + the test cases from both eslint rules in the snapshot tests

@dyc3 dyc3 added the D-Vue Domains: Vue label Jun 27, 2025
@amousa11 amousa11 changed the title Port vue/no-deprecated-data-object-declaration/vue/no-shared-component-data from eslint-plugin-vue feat(biome_js_analyze): noVueDataObjectDeclaration Jun 27, 2025
@amousa11 amousa11 requested a review from dyc3 July 1, 2025 05:32
@amousa11 amousa11 marked this pull request as ready for review July 1, 2025 05:35
Comment on lines +102 to +109
pub NoVueDataObjectDeclaration {
version: "next",
name: "noVueDataObjectDeclaration",
language: "vue",
recommended: true,
fix_kind: FixKind::Safe,
domains: &[RuleDomain::Vue],
}
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Whoops, I missed this on my first pass -- This is missing the rule source that points to the original rule.

Comment on lines 122 to 124
// createApp(...), defineComponent(...)
AnyJsExpression::JsIdentifierExpression(_) => {
let options_argument = call.arguments().ok()?.args().elements().next()?.into_node();
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I feel like the strings need to be checked here to make sure we don't hit false positives. As in, we need to make sure this is a call to createApp or defineComponent (PS -- you'll want to compare the TokenText, not a String).

That being said, I'm not sure if its worth invoking the semantic model here to make sure this is imported from vue. Since this rule is confined to the vue domain, I would think anyone calling these functions would be importing them from vue. So the simple string comparison will suffice.

Comment on lines 181 to 185
if let Ok(object_member_name) = property_object_member.name() {
if let Some(key_name) = object_member_name.name() {
if key_name.text().trim() == "data" {
if let Ok(value) = property_object_member.value() {
match value {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

nit: You might want to try chaining .and_then() instead to reduce this indentation

Comment on lines +125 to +135
i Safe fix: Convert the data object to a function returning the data object

9 9 │ // app.component with object `data`
10 10 │ app.component('some-comp', {
11 │ - ··data:·{
11 │ + ··data:·function(){return{
12 12 │ foo: 'bar'
13 │ - ··}
13 │ + ··}}
14 14 │ });
15 15 │
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Generally, we try to make our fixes line up with what the formatter would output so the user doesn't have to run biome twice.

@dyc3
Copy link
Contributor

dyc3 commented Jul 7, 2025

@amousa11 Would you mind if I took over this PR? We have some more generic vue tooling coming in another PR that this would benefit from.

@amousa11
Copy link
Author

amousa11 commented Jul 8, 2025

@dyc3 No problem, I just pushed up my WIP based on your feedback. Can you link me to that PR for my own learning?

@dyc3
Copy link
Contributor

dyc3 commented Jul 9, 2025

@amousa11 The PR in question is #6757

I'll rebase this PR once that has landed and continue it from there.

@dyc3 dyc3 self-assigned this Jul 9, 2025
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
A-Diagnostic Area: diagnostocis A-Linter Area: linter A-Project Area: project D-Vue Domains: Vue L-JavaScript Language: JavaScript and super languages
Projects
None yet
Development

Successfully merging this pull request may close these issues.

📎 Port vue/no-deprecated-data-object-declaration/vue/no-shared-component-data from eslint-plugin-vue
2 participants
点击 这是indexloc提供的php浏览器服务,不要输入任何密码和下载