eslint-plugin-unicorn: `template-indent` rule conflicts with the prettier

Hello, I have encountered a problem with unicorn/template-indent rule. It’s not indenting the string properly which causes conflict with eslint-plugin-prettier. Fixing one results on other complaining. I know there’s an option to specify the amount of spaces to use for indentation but it feels wrong to hard-code number of spaces in multiple configs. I wonder if there’s a way for this rule to either make this rule respect prettier/editorconfig style guide or make it figure out the indent needed based on the other indents inside of the template literal?

Here’s an example file:

const AppPanel = {};

const Template = (args, options) => ({
    components: { AppPanel },
    setup() {
        return { args };
    },
    // On the next line I get 'ESLint: Templates should be properly indented. (unicorn/template-indent)'
    // ... even though I think it is indented properly 
    template: /* html */ `
        <div style="width:400px">
            <AppPanel>
                <div style="padding:2.4rem">{{args.default}}</div>
            </AppPanel >
        </div>
    `,
});

If I autofix this issue I get this (irrelevant code omitted):

    template: /* html */ `
      <div style="width:400px">
          <AppPanel>
              <div style="padding:2.4rem">{{args.default}}</div>
          </AppPanel>
      </div>
    `,

The problem is the first indent is using 2 spaces while the nested nodes are using 4 spaces (like the rest of the file) so Prettier starts complaining because it wants to indent them according to the styleguide (defined in editorconfig).

I think in this case it should use 4 spaces for indentation automatically.

About this issue

  • Original URL
  • State: closed
  • Created 2 years ago
  • Comments: 16 (10 by maintainers)

Most upvoted comments

Edit: The following seems to be a spec issue, the ESLint ecosystem use different range.


And it is very wired about node.quasis’s position:

unicorn.jsx

node.quasis: <ref *1> [
  Node {
    type: 'TemplateElement',
    start: 38,
    end: 102,
    loc: SourceLocation {
      start: [Position],
      end: [Position],
      filename: undefined,
      identifierName: undefined
    },
    range: [ 38, 102 ],
    value: {
      raw: '<div abc>\n      <div>Nested</div>\n      Hello World\n    </div>',
      cooked: '<div abc>\n      <div>Nested</div>\n      Hello World\n    </div>'
    },
    tail: true,
    parent: Node {
      type: 'TemplateLiteral',
      start: 38,
      end: 102,
      loc: [SourceLocation],
      range: [Array],
      expressions: [],
      quasis: [Circular *1],
      parent: [Node]
    }
  }
]
joined: "<div abc>\n      <div>Nested</div>\n      Hello World\n    </div>"

unicorn.mdx

node.quasis: <ref *1> [
  {
    type: 'TemplateElement',
    start: 39,
    end: 101,
    loc: { start: [Object], end: [Object] },
    range: [ 39, 101 ],
    value: {
      raw: '<div abc>\n      <div>Nested</div>\n      Hello World\n    </div>',
      cooked: '<div abc>\n      <div>Nested</div>\n      Hello World\n    </div>'
    },
    tail: true,
    parent: {
      type: 'TemplateLiteral',
      start: 38,
      end: 102,
      loc: [Object],
      range: [Array],
      expressions: [],
      quasis: [Circular *1],
      parent: [Object]
    }
  }
]
joined: "div abc>\n      <div>Nested</div>\n      Hello World\n    </div"

In astexplorer, it is

{
  "type": "TemplateLiteral",
  "start": 38,
  "end": 102,
  "expressions": [],
  "quasis": [
    {
      "type": "TemplateElement",
      "start": 39,
      "end": 101,
      "value": {
        "raw": "<div abc>\n      <div>Nested</div>\n      Hello World\n    </div>",
        "cooked": "<div abc>\n      <div>Nested</div>\n      Hello World\n    </div>"
      },
      "tail": true
    }
  ]
}

Which is same in remark-mdx parser using acorn under the hood.

Perhaps it is related to the parsed AST loc itself. I’ll check tomorrow.

That’s fair. The more I think about it the more it seems like unnecessary complication. 😅 I’ll stick to the option for now then. Thank you!