vuejs / eslint-plugin-vue

Official ESLint plugin for Vue.js
https://eslint.vuejs.org/
MIT License
4.47k stars 665 forks source link

vue/script-indent: ignoring nested arrays/objects causes incorrect formatting for object #833

Open tony19 opened 5 years ago

tony19 commented 5 years ago

Tell us about your environment

Please show your full configuration:

{
  "root": true,
  "env": {
    "node": true
  },
  "extends": [
    "plugin:vue/essential",
    "eslint:recommended"
  ],
  "rules": {
    "vue/script-indent": [
      "error",
      2,
      {
        "ignores": [
          "[value.type='ObjectExpression']:not(:matches(ExportDefaultDeclaration, [left.property.name='exports']) > * > [value.type='ObjectExpression'])",
          "[value.type='ArrayExpression']"
        ]
      }
    ]
  },
  "parserOptions": {
    "parser": "babel-eslint"
  }
}

What did you do?

  1. Generate default project with vue-cli.
  2. Add ESLint rule above to package.json.
  3. In src/App.vue, add variable of object containing nested arrays/objects and literals.
  4. Run yarn lint.

See reproduction repo

src/App.vue:

<script>
import HelloWorld from './components/HelloWorld.vue'

const x = {
a: [],
b: 1,
c: {},
d: 2
}
console.log(x)

export default {
  name: 'app',
  components: {
    HelloWorld
  },
  methods: {
foo() {
const x = {
a: [],
b: 1,
c: {},
d: 2
}
console.log(x)
}
  }
}
</script>

What did you expect to happen?

<script>
import HelloWorld from './components/HelloWorld.vue'

const x = {
a: [],
  b: 1,
c: {},
  d: 2
}
console.log(x)

export default {
  name: 'app',
  components: {
    HelloWorld
  },
  methods: {
    foo() {
      const x = {
a: [],
        b: 1,
c: {},
        d: 2
      }
      console.log(x)
    }
  }
}
</script>

What actually happened?

<script>
import HelloWorld from './components/HelloWorld.vue'

const x = {
a: [],
b: 1, ❌
c: {},
d: 2  ❌
}
console.log(x)

export default {
  name: 'app',
  components: {
    HelloWorld
  },
  methods: {
    foo() {
      const x = {
a: [],
b: 1, ❌
c: {},
d: 2  ❌
      }
      console.log(x)
    }
  }
}
</script>
tony19 commented 5 years ago

Workaround: Move the literal field to be first in the object, which somehow allows the linter to format the object correctly (in addition to ignoring nested arrays/objects):

const x = {
b: 1,  👈
a: [],
c: {},
d: 2
}
tony19 commented 5 years ago

A similar issue exists in https://github.com/eslint/eslint/issues/11445 with two differences:

  1. Inserting a literal as the first value has no effect.
  2. All fields that follow a nested array/object are ignored.
mysticatea commented 5 years ago

Thank you for the report.

Our indent rule aligns other properties to the same column of the first property. In your case, the first property is ignored by your configuration, so other properties are aligned to the first property, then those are ignored as well.