Skip to content

fix(cli): merge root and sub-package lint configs for vp lint#1115

Open
kazupon wants to merge 4 commits intovoidzero-dev:mainfrom
kazupon:fix/997
Open

fix(cli): merge root and sub-package lint configs for vp lint#1115
kazupon wants to merge 4 commits intovoidzero-dev:mainfrom
kazupon:fix/997

Conversation

@kazupon
Copy link
Collaborator

@kazupon kazupon commented Mar 23, 2026

Summary

Fixes vp lint ignoring sub-package ignorePatterns (and other lint config overrides) when running in a monorepo sub-package.

resolves #997

Root Cause

vp lint always resolved the vite config from the workspace root, regardless of the current working directory.

When a sub-package defined its own vite.config.ts with lint.ignorePatterns, it was never read, oxlint only received the root's config via -c.

Fix

When cwd differs from the workspace root and the sub-package has its own vite.config.ts, both configs are resolved and merged.

The root config serves as the base and the sub-package config overrides specific fields (plugins are unioned, rules/options are shallow-merged with sub-package priority, ignorePatterns are fully overridden by sub-package, overrides are concatenated).

The merged result is written to a fixed cache path (node_modules/.cache/vite-plus/merged-lint-config.json) and passed to oxlint via -c.

Bug flow — sub-package config ignored

sequenceDiagram
    participant User as User (in packages/some-package/)
    participant Rust as vp lint (Rust CLI)
    participant JS as resolveUniversalViteConfig
    participant Vite as Vite resolveConfig
    participant Oxlint as oxlint

    User->>Rust: vp lint
    Rust->>Rust: workspace_path = /root (always)
    Rust->>JS: resolveUniversalViteConfig("/root")
    JS->>Vite: resolveViteConfig("/root")
    Vite-->>JS: configFile: /root/vite.config.ts
    Note over JS: lint: { plugins: ["import"],<br/>rules: { "import/no-commonjs": "error" } }<br/>Warn: No ignorePatterns

    JS-->>Rust: { configFile: "/root/vite.config.ts", lint }
    Rust->>Oxlint: oxlint -c /root/vite.config.ts
    Note over Oxlint: Reads root config only<br/>Sub-package ignorePatterns never seen
    Oxlint-->>User: NG: import/no-commonjs error on fixture files
Loading

Fix flow — configs merged

sequenceDiagram
    participant User as User (in packages/some-package/)
    participant Rust as vp lint (Rust CLI)
    participant JS as resolveUniversalViteConfig
    participant Vite as Vite resolveConfig
    participant Oxlint as oxlint

    User->>Rust: vp lint
    Rust->>Rust: workspace_path = /root, cwd = /root/packages/some-package
    Rust->>JS: resolveUniversalViteConfig(JSON)
    Note over Rust: {"workspacePath": "/root",<br/>"cwd": "/root/packages/some-package"}

    JS->>Vite: resolveViteConfig("/root")
    Vite-->>JS: rootLint: { plugins, rules }
    JS->>Vite: resolveViteConfig("/root/packages/some-package")
    Vite-->>JS: cwdLint: { ignorePatterns, options }

    JS->>JS: mergeLintConfig(rootLint, cwdLint)
    Note over JS: merged: { plugins, rules,<br/>ignorePatterns, options }

    JS->>JS: Write merged config to<br/>node_modules/.cache/vite-plus/<br/>merged-lint-config.json
    JS-->>Rust: { configFile: "merged-lint-config.json", lint }

    Rust->>Oxlint: oxlint -c merged-lint-config.json
    Note over Oxlint: Reads merged config<br/>ignorePatterns excludes fixtures<br/>Root rules still apply
    Oxlint-->>User: OK: 0 errors (fixtures excluded)
Loading

Fix

When cwd differs from the workspace root and the sub-package has its own vite.config.ts, both configs are resolved and merged.

The root config serves as the base and the sub-package config overrides specific fields (plugins are unioned, rules/options are shallow-merged with sub-package priority, ignorePatterns are fully overridden by sub-package, overrides are concatenated).

The merged result is written to a fixed cache path (node_modules/.cache/vite-plus/merged-lint-config.json) and passed to oxlint via -c.

@netlify
Copy link

netlify bot commented Mar 23, 2026

Deploy Preview for viteplus-preview canceled.

Name Link
🔨 Latest commit 31aca40
🔍 Latest deploy log https://app.netlify.com/projects/viteplus-preview/deploys/69c1555fd0f07c0008306c8a

@kazupon kazupon marked this pull request as ready for review March 23, 2026 14:38
@kazupon
Copy link
Collaborator Author

kazupon commented Mar 23, 2026

@codex review

Copy link

@chatgpt-codex-connector chatgpt-codex-connector bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: e926afee0d

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

if (mergedLint) {
const mergedConfigPath = writeMergedLintConfig(cwd, mergedLint);
return JSON.stringify({
configFile: mergedConfigPath,

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P1 Badge Keep fmt pointed at a config that contains fmt settings

When cwd has its own vite.config and mergedLint is produced, this branch returns configFile: mergedConfigPath, but mergedConfigPath is a JSON file written from mergedLint only. The Rust resolver reuses configFile for both vp lint and vp fmt, so vp fmt/vp check in that sub-package will be run with a config file that lacks fmt fields, causing formatter options from root/cwd vite.config to be ignored (or rejected, depending on parser behavior).

Useful? React with 👍 / 👎.

@fengmk2 fengmk2 requested review from camc314 and leaysgur March 23, 2026 15:20
@fengmk2
Copy link
Member

fengmk2 commented Mar 23, 2026

I think the configuration handling logic for lint and fmt should be considered clearly on the oxlint and oxfmt side first.

@uncvrd uncvrd mentioned this pull request Mar 23, 2026
4 tasks
@leaysgur
Copy link
Contributor

I think the configuration handling logic for lint and fmt should be considered clearly on the oxlint and oxfmt side first.

Yes, and I understand that in order to do that, we need to decide how to handle the config files in Vite+ first. 🐣

In any case, I don't think we can make any code changes at this moment. Also, this approach won't be aligned with the LSP.

@cktang88
Copy link

Oxlint oxfmt handles it like so https://oxc.rs/docs/guide/usage/linter/nested-config.html

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Vp lint ignores nested package ignorePattern

4 participants