Repository: vuejs/eslint-plugin-vue

Issue #833: vue/script-indent: ignoring nested arrays/objects causes incorrect formatting for object
Created: 2019-02-26T12:38:20Z
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?

Generate default project with vue-cli.
Add ESLint rule above to package.json.
In src/App.vue, add variable of object containing nested arrays/objects and literals.
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>

Duplicate issue #834: vue/script-indent: ignoring nested arrays/objects causes incorrect formatting for object (TypeScript)
Created: 2019-02-27T07:27:19Z
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:

// .eslintrc.js
module.exports = {
  root: true,
  env: {
    node: true
  },
  'extends': [
    'plugin:vue/essential',
    '@vue/standard',
    '@vue/typescript'
  ],
  rules: {
    'no-console': process.env.NODE_ENV === 'production' ? 'error' : 'off',
    'no-debugger': process.env.NODE_ENV === 'production' ? 'error' : 'off',
    'vue/script-indent': [
      'error',
      2,
      {
        'baseIndent': 1,
        'ignores': [
          '[value.type="ObjectExpression"]:not(:matches(ExportDefaultDeclaration, [left.property.name="exports"]) > * > [value.type="ObjectExpression"])',
          '[value.type="ArrayExpression"]'
        ]
      }
    ]
  },
  'overrides': [
    {
      'files': ['*.vue'],
      'rules': {
        'indent': 'off'
      }
    }
  ],
  parserOptions: {
    parser: '@typescript-eslint/parser'
  }
}
What did you do?

Generate TypeScript project with vue-cli (pick ESLint as linter, separate config files).
Add ESLint rule above to .eslintrc.js.
In src/components/HelloWorld.vue, add method that contains variable of object containing nested arrays/objects and literals.
Run yarn lint.

See reproduction repo
src/components/HelloWorld.vue:

<script lang="ts">
import { Component, Prop, Vue } from 'vue-property-decorator'

@Component
export default class HelloWorld extends Vue {
@Prop() private msg!: string;

foo() {
const x = {
a: [],
b: 1,
c: {},
d: 2
}
return x;
}
}
</script>
What did you expect to happen?
<script lang="ts">
  import { Component, Prop, Vue } from 'vue-property-decorator'

@Component
  export default class HelloWorld extends Vue {
@Prop() private msg!: string;

    foo () {
      const x = {
a: [],
        b: 1,
c: {},
        d: 2
      }
      return x
    }
  }
</script>
What actually happened?

<script lang="ts">
  import { Component, Prop, Vue } from 'vue-property-decorator'

@Component
  export default class HelloWorld extends Vue {
@Prop() private msg!: string;

foo () {                  ❌
const x = {               ❌
a: [],
b: 1,                     ❌
c: {},
d: 2                      ❌
}                         ❌
return x                  ❌
}                         ❌
  }
</script>

Closing comment (2019-02-28T02:01:35Z): Ok. Given your comment in #833, it makes sense that this is probably a duplicate of #833.
I just wanted to point out that this issue is slightly different, and perhaps the subtle differences are significant. I noticed a few lines that are unexpectedly not indented (❌1, ❌2, ❌3, and ❌4). Why is that?
  import { Component, Prop, Vue } from 'vue-property-decorator'     //     Indented with base indent

@Component                                                          //❌1: Why is this not indented? Expected base indent
  export default class HelloWorld extends Vue {                     //     Indented with base indent
@Prop() private msg!: string;                                       //❌2: Why is this not indented? Expected base+1 indent

foo () {                  //     Not indented because it's aligned with first property (`msg`) of current block ('HelloWorld')
const x = {               //❌3: Why is this not indented? Expected base indent
a: [],                    //     Not indented because it's ignored
b: 1,                     //     Not indented because it's aligned with first property (`a`) of current block (`x`)
c: {},                    //     Not indented because it's ignored
d: 2                      //     Not indented because it's aligned with first property (`a`) of current block (`x`)
}                         //     Not indented because it's aligned with declaration of current block (`x`)
return x                  //❌4: Why is this not indented? Expected base indent
}                         //     Not indented because it's aligned with declaration of current block (`foo`)
  }                       //     Indented with base indent