unjs / magicast

🧀 Programmatically modify JavaScript and TypeScript source codes with a simplified, elegant and familiar syntax powered by recast and babel.
MIT License
2.31k stars 39 forks source link

Tab style is not kept #34

Open innocenzi opened 1 year ago

innocenzi commented 1 year ago

Environment

magicast@0.2 typescript@5.0.3 node@19.8.1

Reproduction

import { parseModule, generateCode } from 'magicast'
import { addVitePlugin } from 'magicast/helpers'

const mod = parseModule(`
import { defineConfig } from 'vite'

export default defineConfig({
    plugins: []
})
`)

addVitePlugin(mod, {
    from: '@vitejs/plugin-vue',
    constructor: 'vue',
    options: {
        owo: true,
    },
})

const { code } = generateCode(mod)

console.log({ code })

Describe the bug

In the reproduction above, the indentation of plugins is a single tab. However, the generated code uses four tabs.

Additional context

Result:

{
  code: "import vue from '@vitejs/plugin-vue';\n" +
    "import { defineConfig } from 'vite'\n" +
    '\n' +
    'export default defineConfig({\n' +
    '\t\t\t\tplugins: [vue({\n' +
    '\t\t\t\t owo: true\n' +
    '\t\t\t\t})]\n' +
    '})'
}

Expected:

{
  code: "import vue from '@vitejs/plugin-vue';\n" +
    "import { defineConfig } from 'vite'\n" +
    '\n' +
    'export default defineConfig({\n' +
    '\tplugins: [vue({\n' +
    '\t\towo: true\n' +
    '\t})]\n' +
    '})'
}
antfu commented 1 year ago

This feels a bit like recast's bug to me. As I checked, we seems to be detecting them correctly and passing { useTabs: true, tabWidth: 1 }. And normally I think when useTabs is set, tabWidth should be ignored, but in real, it actually affects how many tabs are generated (passing 2 makes it generate fewer tabs somehow).

Could use some help if anyone wants to go deeper on it.

tushar-deepsource commented 1 year ago

@antfu I assume tabWidth is a bit like the ts query parameter in github. If the indentation is 2 tabs in your code, and you set ?ts=2 in any GitHub URL, the 2 tabs will look like 4 spaces. Similarly if you do ?ts=4, 4 tabs will look like 4 spaces.

Hence I guess tabWidth: 1 tells the generator that to preserve the look of 4 spaces, insert 4 tabs there.