eslint-plugin-vue icon indicating copy to clipboard operation
eslint-plugin-vue copied to clipboard

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

Open tony19 opened this issue 5 years ago • 3 comments

Tell us about your environment

  • ESLint version: 5.14.1
  • eslint-plugin-vue version: 5.2.2
  • Node version: 10.11.0

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 avatar Feb 26 '19 12:02 tony19

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 avatar Feb 26 '19 12:02 tony19

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.

tony19 avatar Feb 26 '19 12:02 tony19

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.

mysticatea avatar Feb 27 '19 17:02 mysticatea