Skip to content

lint,fmt: Known vite.config.ts releated issues #930

Closed
0 of 1 issue completed
Closed

Description

@leaysgur

Currently, vp lint, vp fmt, and the VSCode extension all transparently utilize Oxlint and Oxfmt respectively.

In Oxapps side, the ability to extract .lint and .fmt fields from vite.config.ts has been added, but they are not fully complete at present.

1: All Vite config patterns are not supported

Note

This is fixed in oxlint@1.67.0 and oxfmt@0.52.0 = vite-plus@0.1.23

Details

https://vite.dev/config/

Currently supported static config only:

export default { ... };
export default defineConfig({ ... });

Conditional and async config are NOT supported.

defineConfig(({ ... }) => ({ ... }));
defineConfig(async ({ ... }) => ({ ... }));

Since they do not know how to handle arguments.

For the first place, Oxlint and Oxfmt do not support functional config even with their oxlint.config.ts. Also, be aware that the file name, they only support the .ts extension.

2: Some valid Vite config fails to load even with static config

Note

This is fixed in oxlint@1.67.0 and oxfmt@0.52.0 = vite-plus@0.1.23

Details

Most reported cases fall into this category.

Oxlint and Oxfmt uses normal ESM dynamic import() to load vite.config.ts.

This means it is roughly equivalent to --configLoader native for Vite, so if configuration files rely on the default --configLoader bundle (also runner), which requires some transform, it will fail to load.

e.g.

  • Use __dirname in type: module project
  • Try to import X from "./foo.js", but actually there is only foo.ts on the disk
  • Try to import "foo.json without with { type: "json" }
  • etc...

Refs: vitejs/vite#21546

3: VSCode extension does not pick vite.config.ts

Details

If you have multiple workspaces open, please make sure that the correct version of Oxlint/Oxfmt is being used to your dedicated workspace.

Currently, single extension and LSP process is shared across multiple workspace folders.

If an unintended project's LSP is selected, it may not have the capability to read vite.config.ts.

Refs: oxc-project/oxc-vscode#145

4: vite.config.ts is not used if oxapps config file also exists

Note

This is fixed in oxlint@1.60.0 and oxfmt@0.45.0

Details

With current implementation, vite.config.ts is used as fallback.

The priority order is: the respective config files (such as .oxfmtrc.json) and then vite.config.ts.

I don't think it's recommended to combine these together in a Vite+ environment, but that’s how things stand at the moment.

5: Oxlint|Oxfmt fails even in non-Vite+ project

Note

This is fixed in oxlint@1.60.0 and oxfmt@0.45.0

Details

It's not directly related to Vite+, but it's a noteworthy point.

Oxlint and Oxfmt might run into problems if they find vite.config.ts (which triggers 2nd issue) while searching for config files by finding-up the parent directories. Just by attempting to load the relevant .lint|fmt field causes error.

This may happen to Oxfmt CLI+LSP, and Oxlint LSP usecases.

6: Nested config is not used by the vp lint|fmt, but it is used by the LSP

Details

Currently, vp lint|fmt always executes with --config flag with the vite.config.ts located at the project root.

This is because, as a recommendation for Vite+, we want to keep all lint|fmt settings contained within the root. (And use overrides for each package style)

However, it is not possible to enforce the same specification for an LSP (since it is unknown which directory the workspace will be opened from).

Therefore, if nested vite.config.ts files are placed and they contain .lint|fmt fields, different options will be used.

We are considering adding a built-in Oxlint rule to detect and prevent this.

Refs: #1456

(Ideally, --config is not needed for vp lint|fmt. It will auto-discover root config at any cwd. But perf-wise, since -c effectively disables nested config discovery. Or just adding --disable-nested-config is fine too. But still, LSP does not have equivalent option yet.)

Activity

  1. added theissue type on Mar 16, 2026
  2. changed the issue type fromtoon Mar 16, 2026
  3. marked VP Check error #860 as a duplicate of this issue on Mar 16, 2026
  4. RafaRochaS91 commented on Mar 25, 2026

    @RafaRochaS91

    +1 here, I've just used the vp create interactive command to create a monorepo and the format IDE shortcut doesn't pickup the configuration of fmt as below:

    export default defineConfig({
      fmt: {
        singleQuote: true,
      },
      staged: {
        "*": "vp check --fix",
      },
      lint: { options: { typeAware: true, typeCheck: true } },
    });

    I'm using cursor so the specific extension pack isn't available however i do have the extensions within installed (vitest and oxc).
    I tried in VSCode and had the same issue where the format shortcut and the cmd + shift + p isn't picking up the config in vite.config.ts.

    Let me know if there's any more information to provide.

  5. FleetAdmiralJakob commented on Apr 4, 2026

    @FleetAdmiralJakob
    Contributor

    +1 from me as well. I need to access mode today, so I switched to the function/conditional config. This broke vp fmt though.

  6. FleetAdmiralJakob commented on Apr 4, 2026

    @FleetAdmiralJakob
    Contributor

    The 4th "issue" you wrote down is actually what helps me to move around the first problem. By just removing the lint and fmt field from the vite.config.ts and moving the configs to their respective JSON files, I was able to work around the problem (not the smoothest way, but hey, at least something)

  7. 4513ECHO commented on Apr 9, 2026

    @4513ECHO

    For someone trying to use conditional config, I've found following example will be useful:

    You can access mode by adding a simple plugin.

    // XXX: Access mode from config
    // See https://github.com/voidzero-dev/vite-plus/issues/930
    function modeWorkaround(): Plugin {
      return {
        name: "mode-workaround",
        config(_config, { mode }) {
          return {
            build: {
              sourcemap: mode === "prod" ? false : "inline",
              minify: mode === "prod",
            },
          };
        },
      };
    }
    
    export default defineConfig({
      plugins: [modeWorkaround()],
      // ...
      fmt: {}, // oxfmt is working!
    });
  8. marked vp fail 0.1.18 #1423 as a duplicate of this issue on Apr 20, 2026
  9. fengmk2 commented on Apr 24, 2026

    @fengmk2
    Member

    For someone trying to use conditional config, I've found following example will be useful:

    You can access mode by adding a simple plugin.

    // XXX: Access mode from config
    // See #930
    function modeWorkaround(): Plugin {
    return {
    name: "mode-workaround",
    config(_config, { mode }) {
    return {
    build: {
    sourcemap: mode === "prod" ? false : "inline",
    minify: mode === "prod",
    },
    };
    },
    };
    }

    export default defineConfig({
    plugins: [modeWorkaround()],
    // ...
    fmt: {}, // oxfmt is working!
    });

    @4513ECHO https://viteplus.dev/guide/troubleshooting#slow-config-loading-caused-by-heavy-plugins can use lazyPlugins now.

  10. 4513ECHO commented on Apr 24, 2026

    @4513ECHO

    I think lazyPlugins doesn't fit this situation. In my example the plugin accesses mode but does no heavy calculations.

  11. changed the title [-]vp lint/fmt + IDE: Known vite.config.ts releated issues[/-] [+]lint,fmt: Known vite.config.ts releated issues[/+] on May 12, 2026
  12. added a commit that references this issue on May 29, 2026
    1f48b2c
  13. priithansen commented on Jun 19, 2026

    @priithansen

    For me moving fmt and lint objects to corresponding oxfmt.config.ts and oxlint.config.ts files pointing the Oxc extension to those and importing the config files in vite.config.ts seems like pragmatical solution. Avoiding problems where the extension can't handle the full vite config object while keeping the rules deduplicated.

    // codebase/frontend/oxlint.config.ts
    
    import { defineConfig } from 'oxlint'
    
    export default defineConfig({
      ...
    })
    // codebase/frontend/oxfmt.config.ts
    
    import { defineConfig } from 'oxfmt'
    
    export default defineConfig({
      ...
    })
    // codebase/frontend/vite.config.ts
    
    import { defineConfig } from 'vite-plus'
    
    // Separate files so VsCode Oxc extension would not error out on full vite.config.ts.
    import fmt from './oxfmt.config'
    import lint from './oxlint.config'
    
    // https://vite.dev/config/
    export default defineConfig({
      fmt,
      lint,
      ...
    })
    // .vscode/settings.json
    
    {
      "oxc.path.oxfmt": "codebase/frontend/node_modules/.bin/oxfmt",
      "oxc.path.oxlint": "codebase/frontend/node_modules/.bin/oxlint",
      "oxc.fmt.configPath": "codebase/frontend/oxfmt.config.ts",
      "oxc.configPath": "codebase/frontend/oxlint.config.ts",
      "oxc.path.tsgolint": "codebase/frontend/node_modules/.bin/tsgolint",
      ...
    }
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

Labels

No labels
No labels

Fields

Priority

None yet

Start date

None yet

Target date

None yet

Effort

None yet

Projects

No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions