From 1a03ca7e49b8891ee6168492889fc8e0c6ef2d7e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=EC=9D=B4=EC=A2=85=EA=B2=BD?= Date: Thu, 23 Apr 2026 00:08:23 +0900 Subject: [PATCH 1/4] feat(check): add TypeCheckOnly variant and from_flags helper --- packages/cli/binding/src/check/analysis.rs | 88 ++++++++++++++++++---- 1 file changed, 72 insertions(+), 16 deletions(-) diff --git a/packages/cli/binding/src/check/analysis.rs b/packages/cli/binding/src/check/analysis.rs index 2dbaa00577..6068b1a866 100644 --- a/packages/cli/binding/src/check/analysis.rs +++ b/packages/cli/binding/src/check/analysis.rs @@ -39,23 +39,26 @@ pub(super) struct LintFailure { pub(super) enum LintMessageKind { LintOnly, LintAndTypeCheck, + TypeCheckOnly, } impl LintMessageKind { - pub(super) fn from_lint_config(lint_config: Option<&serde_json::Value>) -> Self { - let type_check_enabled = lint_config - .and_then(|config| config.get("options")) - .and_then(|options| options.get("typeCheck")) - .and_then(serde_json::Value::as_bool) - .unwrap_or(false); - - if type_check_enabled { Self::LintAndTypeCheck } else { Self::LintOnly } + pub(super) fn from_flags(lint_enabled: bool, type_check_enabled: bool) -> Self { + match (lint_enabled, type_check_enabled) { + (true, true) => Self::LintAndTypeCheck, + (true, false) => Self::LintOnly, + (false, true) => Self::TypeCheckOnly, + (false, false) => unreachable!( + "from_flags called with (false, false); caller must guard on run_lint_phase" + ), + } } pub(super) fn success_label(self) -> &'static str { match self { Self::LintOnly => "Found no warnings or lint errors", Self::LintAndTypeCheck => "Found no warnings, lint errors, or type errors", + Self::TypeCheckOnly => "Found no type errors", } } @@ -63,6 +66,7 @@ impl LintMessageKind { match self { Self::LintOnly => "Lint warnings found", Self::LintAndTypeCheck => "Lint or type warnings found", + Self::TypeCheckOnly => "Type warnings found", } } @@ -70,10 +74,26 @@ impl LintMessageKind { match self { Self::LintOnly => "Lint issues found", Self::LintAndTypeCheck => "Lint or type issues found", + Self::TypeCheckOnly => "Type errors found", } } } +/// `typeCheck` requires `typeAware` as a prerequisite — oxlint's type-aware +/// analysis must be on for TypeScript diagnostics to surface. +pub(super) fn lint_config_type_check_enabled(lint_config: Option<&serde_json::Value>) -> bool { + let options = lint_config.and_then(|config| config.get("options")); + let type_aware = options + .and_then(|options| options.get("typeAware")) + .and_then(serde_json::Value::as_bool) + .unwrap_or(false); + let type_check = options + .and_then(|options| options.get("typeCheck")) + .and_then(serde_json::Value::as_bool) + .unwrap_or(false); + type_aware && type_check +} + fn parse_check_summary(line: &str) -> Option { let rest = line.strip_prefix("Finished in ")?; let (duration, rest) = rest.split_once(" on ")?; @@ -227,29 +247,65 @@ pub(super) fn analyze_lint_output(output: &str) -> Option Date: Thu, 23 Apr 2026 00:08:23 +0900 Subject: [PATCH 2/4] feat(check): redefine --no-lint to forward --type-check-only when typeCheck enabled --- crates/vite_global_cli/src/help.rs | 5 +- packages/cli/binding/src/check/mod.rs | 77 +++++++++++++------ packages/cli/binding/src/cli/types.rs | 2 +- .../command-check-help/snap.txt | 6 +- .../cli/snap-tests/check-all-skipped/snap.txt | 2 +- .../snap.txt | 1 + 6 files changed, 62 insertions(+), 31 deletions(-) diff --git a/crates/vite_global_cli/src/help.rs b/crates/vite_global_cli/src/help.rs index 7fadebc0db..9e07adf628 100644 --- a/crates/vite_global_cli/src/help.rs +++ b/crates/vite_global_cli/src/help.rs @@ -760,7 +760,10 @@ fn delegated_help_doc(command: &str) -> Option { vec![ row("--fix", "Auto-fix format and lint issues"), row("--no-fmt", "Skip format check"), - row("--no-lint", "Skip lint check"), + row( + "--no-lint", + "Skip lint rules; type-check still runs when `lint.options.typeCheck` is true", + ), row( "--no-error-on-unmatched-pattern", "Do not exit with error when pattern is unmatched", diff --git a/packages/cli/binding/src/check/mod.rs b/packages/cli/binding/src/check/mod.rs index 722a52578c..d7b1e1fe44 100644 --- a/packages/cli/binding/src/check/mod.rs +++ b/packages/cli/binding/src/check/mod.rs @@ -10,7 +10,8 @@ use vite_task::ExitStatus; use self::analysis::{ LintMessageKind, analyze_fmt_check_output, analyze_lint_output, format_count, format_elapsed, - print_error_block, print_pass_line, print_stdout_block, print_summary_line, + lint_config_type_check_enabled, print_error_block, print_pass_line, print_stdout_block, + print_summary_line, }; use crate::cli::{ CapturedCommandOutput, SubcommandResolver, SynthesizableSubcommand, resolve_and_capture_output, @@ -28,14 +29,6 @@ pub(crate) async fn execute_check( cwd: &AbsolutePathBuf, cwd_arc: &Arc, ) -> Result { - if no_fmt && no_lint { - output::error("No checks enabled"); - print_summary_line( - "`vp check` did not run because both `--no-fmt` and `--no-lint` were set", - ); - return Ok(ExitStatus(1)); - } - let mut status = ExitStatus::SUCCESS; let has_paths = !paths.is_empty(); // In --fix mode with file paths (the lint-staged use case), implicitly suppress @@ -46,6 +39,18 @@ pub(crate) async fn execute_check( let mut deferred_lint_pass: Option<(String, String)> = None; let resolved_vite_config = resolver.resolve_universal_vite_config().await?; + let type_check_enabled = lint_config_type_check_enabled(resolved_vite_config.lint.as_ref()); + let lint_enabled = !no_lint; + let run_lint_phase = lint_enabled || type_check_enabled; + + if no_fmt && !run_lint_phase { + output::error("No checks enabled"); + print_summary_line( + "Enable `lint.options.typeCheck` in vite.config.ts to use `vp check --no-fmt --no-lint` for type-check only, or drop a flag to re-enable fmt/lint.", + ); + return Ok(ExitStatus(1)); + } + if !no_fmt { let mut args = if fix { vec![] } else { vec!["--check".to_string()] }; if suppress_unmatched { @@ -109,7 +114,7 @@ pub(crate) async fn execute_check( } } - if fix && no_lint && status == ExitStatus::SUCCESS { + if fix && !run_lint_phase && status == ExitStatus::SUCCESS { print_pass_line( "Formatting completed for checked files", Some(&format!("({})", format_elapsed(fmt_start.elapsed()))), @@ -127,11 +132,12 @@ pub(crate) async fn execute_check( } } - if !no_lint { - let lint_message_kind = - LintMessageKind::from_lint_config(resolved_vite_config.lint.as_ref()); + if run_lint_phase { + let lint_message_kind = LintMessageKind::from_flags(lint_enabled, type_check_enabled); let mut args = Vec::new(); - if fix { + // oxlint cannot auto-fix type diagnostics, so `--fix` is dropped on the + // type-check-only path. + if fix && lint_enabled { args.push("--fix".to_string()); } // `vp check` parses oxlint's human-readable summary output to print @@ -140,6 +146,9 @@ pub(crate) async fn execute_check( // parser think linting never started. Force the default reporter here so the // captured output is stable across local and CI environments. args.push("--format=default".to_string()); + if !lint_enabled && type_check_enabled { + args.push("--type-check-only".to_string()); + } if suppress_unmatched { args.push("--no-error-on-unmatched-pattern".to_string()); } @@ -207,13 +216,18 @@ pub(crate) async fn execute_check( } } if status != ExitStatus::SUCCESS { + // Surface fmt `--fix` completion before bailing so users can see + // the working tree was mutated before the lint/type-check error. + if fix && !no_fmt { + flush_deferred_pass_lines(&mut fmt_fix_started, &mut deferred_lint_pass); + } return Ok(status); } } // Re-run fmt after lint --fix, since lint fixes can break formatting - // (e.g. the curly rule adding braces to if-statements) - if fix && !no_fmt && !no_lint { + // (e.g. the curly rule adding braces to if-statements). + if fix && !no_fmt && lint_enabled { let mut args = Vec::new(); if suppress_unmatched { args.push("--no-error-on-unmatched-pattern".to_string()); @@ -241,20 +255,33 @@ pub(crate) async fn execute_check( ); return Ok(status); } - if let Some(started) = fmt_fix_started { - print_pass_line( - "Formatting completed for checked files", - Some(&format!("({})", format_elapsed(started.elapsed()))), - ); - } - if let Some((message, detail)) = deferred_lint_pass.take() { - print_pass_line(&message, Some(&detail)); - } + flush_deferred_pass_lines(&mut fmt_fix_started, &mut deferred_lint_pass); + } + + // Type-check-only mode skips the re-fmt block above, so flush deferred + // pass lines here. + if fix && !no_fmt && run_lint_phase && !lint_enabled { + flush_deferred_pass_lines(&mut fmt_fix_started, &mut deferred_lint_pass); } Ok(status) } +fn flush_deferred_pass_lines( + fmt_fix_started: &mut Option, + deferred_lint_pass: &mut Option<(String, String)>, +) { + if let Some(started) = fmt_fix_started.take() { + print_pass_line( + "Formatting completed for checked files", + Some(&format!("({})", format_elapsed(started.elapsed()))), + ); + } + if let Some((message, detail)) = deferred_lint_pass.take() { + print_pass_line(&message, Some(&detail)); + } +} + /// Combine stdout and stderr from a captured command output. fn combine_output(captured: CapturedCommandOutput) -> (ExitStatus, String) { let combined = if captured.stderr.is_empty() { diff --git a/packages/cli/binding/src/cli/types.rs b/packages/cli/binding/src/cli/types.rs index 0d2a7455ba..f17ca40509 100644 --- a/packages/cli/binding/src/cli/types.rs +++ b/packages/cli/binding/src/cli/types.rs @@ -90,7 +90,7 @@ pub enum SynthesizableSubcommand { /// Skip format check #[arg(long = "no-fmt")] no_fmt: bool, - /// Skip lint check + /// Skip lint rules; type-check still runs when `lint.options.typeCheck` is true #[arg(long = "no-lint")] no_lint: bool, /// Do not exit with error when pattern is unmatched diff --git a/packages/cli/snap-tests-global/command-check-help/snap.txt b/packages/cli/snap-tests-global/command-check-help/snap.txt index 830728f645..b1c04836cf 100644 --- a/packages/cli/snap-tests-global/command-check-help/snap.txt +++ b/packages/cli/snap-tests-global/command-check-help/snap.txt @@ -8,7 +8,7 @@ Run format, lint, and type checks. Options: --fix Auto-fix format and lint issues --no-fmt Skip format check - --no-lint Skip lint check + --no-lint Skip lint rules; type-check still runs when `lint.options.typeCheck` is true --no-error-on-unmatched-pattern Do not exit with error when pattern is unmatched -h, --help Print help @@ -30,7 +30,7 @@ Run format, lint, and type checks. Options: --fix Auto-fix format and lint issues --no-fmt Skip format check - --no-lint Skip lint check + --no-lint Skip lint rules; type-check still runs when `lint.options.typeCheck` is true --no-error-on-unmatched-pattern Do not exit with error when pattern is unmatched -h, --help Print help @@ -52,7 +52,7 @@ Run format, lint, and type checks. Options: --fix Auto-fix format and lint issues --no-fmt Skip format check - --no-lint Skip lint check + --no-lint Skip lint rules; type-check still runs when `lint.options.typeCheck` is true --no-error-on-unmatched-pattern Do not exit with error when pattern is unmatched -h, --help Print help diff --git a/packages/cli/snap-tests/check-all-skipped/snap.txt b/packages/cli/snap-tests/check-all-skipped/snap.txt index 99cea52dfb..c462f68156 100644 --- a/packages/cli/snap-tests/check-all-skipped/snap.txt +++ b/packages/cli/snap-tests/check-all-skipped/snap.txt @@ -1,4 +1,4 @@ [1]> vp check --no-fmt --no-lint error: No checks enabled -`vp check` did not run because both `--no-fmt` and `--no-lint` were set +Enable `lint.options.typeCheck` in vite.config.ts to use `vp check --no-fmt --no-lint` for type-check only, or drop a flag to re-enable fmt/lint. diff --git a/packages/cli/snap-tests/check-fix-lint-error-not-swallowed/snap.txt b/packages/cli/snap-tests/check-fix-lint-error-not-swallowed/snap.txt index a9604d89a4..dcdce37b14 100644 --- a/packages/cli/snap-tests/check-fix-lint-error-not-swallowed/snap.txt +++ b/packages/cli/snap-tests/check-fix-lint-error-not-swallowed/snap.txt @@ -10,3 +10,4 @@ error: Lint issues found help: Avoid eval(). For JSON parsing use JSON.parse(); for dynamic property access use bracket notation (obj[key]); for other cases refactor to avoid evaluating strings as code. Found 1 error and 0 warnings in 1 file (ms, threads) +pass: Formatting completed for checked files (ms) From 01394d7b321d06bf9f5618592c164e5eff18be28 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=EC=9D=B4=EC=A2=85=EA=B2=BD?= Date: Thu, 23 Apr 2026 00:08:23 +0900 Subject: [PATCH 3/4] test(check): add snap fixtures covering --no-lint type-check-only matrix --- .../check-fix-no-fmt-no-lint-typecheck/package.json | 5 +++++ .../check-fix-no-fmt-no-lint-typecheck/snap.txt | 2 ++ .../check-fix-no-fmt-no-lint-typecheck/src/index.ts | 2 ++ .../check-fix-no-fmt-no-lint-typecheck/steps.json | 6 ++++++ .../check-fix-no-fmt-no-lint-typecheck/vite.config.ts | 8 ++++++++ .../check-fix-no-lint-typecheck-fail/package.json | 5 +++++ .../check-fix-no-lint-typecheck-fail/snap.txt | 11 +++++++++++ .../check-fix-no-lint-typecheck-fail/src/index.ts | 2 ++ .../check-fix-no-lint-typecheck-fail/steps.json | 6 ++++++ .../check-fix-no-lint-typecheck-fail/vite.config.ts | 8 ++++++++ .../check-fix-no-lint-typecheck/package.json | 5 +++++ .../snap-tests/check-fix-no-lint-typecheck/snap.txt | 3 +++ .../check-fix-no-lint-typecheck/src/index.ts | 2 ++ .../snap-tests/check-fix-no-lint-typecheck/steps.json | 6 ++++++ .../check-fix-no-lint-typecheck/vite.config.ts | 8 ++++++++ .../check-no-fmt-no-lint-typecheck/package.json | 5 +++++ .../check-no-fmt-no-lint-typecheck/snap.txt | 2 ++ .../check-no-fmt-no-lint-typecheck/src/index.ts | 2 ++ .../check-no-fmt-no-lint-typecheck/steps.json | 6 ++++++ .../check-no-fmt-no-lint-typecheck/vite.config.ts | 8 ++++++++ .../check-no-lint-typecheck-fail/package.json | 5 +++++ .../snap-tests/check-no-lint-typecheck-fail/snap.txt | 11 +++++++++++ .../check-no-lint-typecheck-fail/src/index.ts | 2 ++ .../check-no-lint-typecheck-fail/steps.json | 6 ++++++ .../check-no-lint-typecheck-fail/vite.config.ts | 11 +++++++++++ .../snap-tests/check-no-lint-typecheck/package.json | 5 +++++ .../cli/snap-tests/check-no-lint-typecheck/snap.txt | 3 +++ .../snap-tests/check-no-lint-typecheck/src/index.ts | 8 ++++++++ .../cli/snap-tests/check-no-lint-typecheck/steps.json | 6 ++++++ .../snap-tests/check-no-lint-typecheck/vite.config.ts | 11 +++++++++++ 30 files changed, 170 insertions(+) create mode 100644 packages/cli/snap-tests/check-fix-no-fmt-no-lint-typecheck/package.json create mode 100644 packages/cli/snap-tests/check-fix-no-fmt-no-lint-typecheck/snap.txt create mode 100644 packages/cli/snap-tests/check-fix-no-fmt-no-lint-typecheck/src/index.ts create mode 100644 packages/cli/snap-tests/check-fix-no-fmt-no-lint-typecheck/steps.json create mode 100644 packages/cli/snap-tests/check-fix-no-fmt-no-lint-typecheck/vite.config.ts create mode 100644 packages/cli/snap-tests/check-fix-no-lint-typecheck-fail/package.json create mode 100644 packages/cli/snap-tests/check-fix-no-lint-typecheck-fail/snap.txt create mode 100644 packages/cli/snap-tests/check-fix-no-lint-typecheck-fail/src/index.ts create mode 100644 packages/cli/snap-tests/check-fix-no-lint-typecheck-fail/steps.json create mode 100644 packages/cli/snap-tests/check-fix-no-lint-typecheck-fail/vite.config.ts create mode 100644 packages/cli/snap-tests/check-fix-no-lint-typecheck/package.json create mode 100644 packages/cli/snap-tests/check-fix-no-lint-typecheck/snap.txt create mode 100644 packages/cli/snap-tests/check-fix-no-lint-typecheck/src/index.ts create mode 100644 packages/cli/snap-tests/check-fix-no-lint-typecheck/steps.json create mode 100644 packages/cli/snap-tests/check-fix-no-lint-typecheck/vite.config.ts create mode 100644 packages/cli/snap-tests/check-no-fmt-no-lint-typecheck/package.json create mode 100644 packages/cli/snap-tests/check-no-fmt-no-lint-typecheck/snap.txt create mode 100644 packages/cli/snap-tests/check-no-fmt-no-lint-typecheck/src/index.ts create mode 100644 packages/cli/snap-tests/check-no-fmt-no-lint-typecheck/steps.json create mode 100644 packages/cli/snap-tests/check-no-fmt-no-lint-typecheck/vite.config.ts create mode 100644 packages/cli/snap-tests/check-no-lint-typecheck-fail/package.json create mode 100644 packages/cli/snap-tests/check-no-lint-typecheck-fail/snap.txt create mode 100644 packages/cli/snap-tests/check-no-lint-typecheck-fail/src/index.ts create mode 100644 packages/cli/snap-tests/check-no-lint-typecheck-fail/steps.json create mode 100644 packages/cli/snap-tests/check-no-lint-typecheck-fail/vite.config.ts create mode 100644 packages/cli/snap-tests/check-no-lint-typecheck/package.json create mode 100644 packages/cli/snap-tests/check-no-lint-typecheck/snap.txt create mode 100644 packages/cli/snap-tests/check-no-lint-typecheck/src/index.ts create mode 100644 packages/cli/snap-tests/check-no-lint-typecheck/steps.json create mode 100644 packages/cli/snap-tests/check-no-lint-typecheck/vite.config.ts diff --git a/packages/cli/snap-tests/check-fix-no-fmt-no-lint-typecheck/package.json b/packages/cli/snap-tests/check-fix-no-fmt-no-lint-typecheck/package.json new file mode 100644 index 0000000000..7fceb1dc42 --- /dev/null +++ b/packages/cli/snap-tests/check-fix-no-fmt-no-lint-typecheck/package.json @@ -0,0 +1,5 @@ +{ + "name": "check-fix-no-fmt-no-lint-typecheck", + "version": "0.0.0", + "private": true +} diff --git a/packages/cli/snap-tests/check-fix-no-fmt-no-lint-typecheck/snap.txt b/packages/cli/snap-tests/check-fix-no-fmt-no-lint-typecheck/snap.txt new file mode 100644 index 0000000000..5c5c63d3fa --- /dev/null +++ b/packages/cli/snap-tests/check-fix-no-fmt-no-lint-typecheck/snap.txt @@ -0,0 +1,2 @@ +> vp check --fix --no-fmt --no-lint +pass: Found no type errors in 2 files (ms, threads) diff --git a/packages/cli/snap-tests/check-fix-no-fmt-no-lint-typecheck/src/index.ts b/packages/cli/snap-tests/check-fix-no-fmt-no-lint-typecheck/src/index.ts new file mode 100644 index 0000000000..3b3d6d4fbc --- /dev/null +++ b/packages/cli/snap-tests/check-fix-no-fmt-no-lint-typecheck/src/index.ts @@ -0,0 +1,2 @@ +const value: number = 42; +export { value }; diff --git a/packages/cli/snap-tests/check-fix-no-fmt-no-lint-typecheck/steps.json b/packages/cli/snap-tests/check-fix-no-fmt-no-lint-typecheck/steps.json new file mode 100644 index 0000000000..f24e7f7c10 --- /dev/null +++ b/packages/cli/snap-tests/check-fix-no-fmt-no-lint-typecheck/steps.json @@ -0,0 +1,6 @@ +{ + "env": { + "VITE_DISABLE_AUTO_INSTALL": "1" + }, + "commands": ["vp check --fix --no-fmt --no-lint"] +} diff --git a/packages/cli/snap-tests/check-fix-no-fmt-no-lint-typecheck/vite.config.ts b/packages/cli/snap-tests/check-fix-no-fmt-no-lint-typecheck/vite.config.ts new file mode 100644 index 0000000000..ecd9dc9d34 --- /dev/null +++ b/packages/cli/snap-tests/check-fix-no-fmt-no-lint-typecheck/vite.config.ts @@ -0,0 +1,8 @@ +export default { + lint: { + options: { + typeAware: true, + typeCheck: true, + }, + }, +}; diff --git a/packages/cli/snap-tests/check-fix-no-lint-typecheck-fail/package.json b/packages/cli/snap-tests/check-fix-no-lint-typecheck-fail/package.json new file mode 100644 index 0000000000..98ed11a3d4 --- /dev/null +++ b/packages/cli/snap-tests/check-fix-no-lint-typecheck-fail/package.json @@ -0,0 +1,5 @@ +{ + "name": "check-fix-no-lint-typecheck-fail", + "version": "0.0.0", + "private": true +} diff --git a/packages/cli/snap-tests/check-fix-no-lint-typecheck-fail/snap.txt b/packages/cli/snap-tests/check-fix-no-lint-typecheck-fail/snap.txt new file mode 100644 index 0000000000..2aa018ce41 --- /dev/null +++ b/packages/cli/snap-tests/check-fix-no-lint-typecheck-fail/snap.txt @@ -0,0 +1,11 @@ +[1]> vp check --fix --no-lint +error: Type errors found +× typescript(TS2322): Type 'string' is not assignable to type 'number'. + ╭─[src/index.ts:1:7] + 1 │ const value: number = "not a number"; + · ───── + 2 │ export { value }; + ╰──── + +Found 1 error and 0 warnings in 2 files (ms, threads) +pass: Formatting completed for checked files (ms) diff --git a/packages/cli/snap-tests/check-fix-no-lint-typecheck-fail/src/index.ts b/packages/cli/snap-tests/check-fix-no-lint-typecheck-fail/src/index.ts new file mode 100644 index 0000000000..2f64bde008 --- /dev/null +++ b/packages/cli/snap-tests/check-fix-no-lint-typecheck-fail/src/index.ts @@ -0,0 +1,2 @@ +const value: number = "not a number"; +export { value }; diff --git a/packages/cli/snap-tests/check-fix-no-lint-typecheck-fail/steps.json b/packages/cli/snap-tests/check-fix-no-lint-typecheck-fail/steps.json new file mode 100644 index 0000000000..68a47942e1 --- /dev/null +++ b/packages/cli/snap-tests/check-fix-no-lint-typecheck-fail/steps.json @@ -0,0 +1,6 @@ +{ + "env": { + "VITE_DISABLE_AUTO_INSTALL": "1" + }, + "commands": ["vp check --fix --no-lint"] +} diff --git a/packages/cli/snap-tests/check-fix-no-lint-typecheck-fail/vite.config.ts b/packages/cli/snap-tests/check-fix-no-lint-typecheck-fail/vite.config.ts new file mode 100644 index 0000000000..ecd9dc9d34 --- /dev/null +++ b/packages/cli/snap-tests/check-fix-no-lint-typecheck-fail/vite.config.ts @@ -0,0 +1,8 @@ +export default { + lint: { + options: { + typeAware: true, + typeCheck: true, + }, + }, +}; diff --git a/packages/cli/snap-tests/check-fix-no-lint-typecheck/package.json b/packages/cli/snap-tests/check-fix-no-lint-typecheck/package.json new file mode 100644 index 0000000000..912ea1e1cb --- /dev/null +++ b/packages/cli/snap-tests/check-fix-no-lint-typecheck/package.json @@ -0,0 +1,5 @@ +{ + "name": "check-fix-no-lint-typecheck", + "version": "0.0.0", + "private": true +} diff --git a/packages/cli/snap-tests/check-fix-no-lint-typecheck/snap.txt b/packages/cli/snap-tests/check-fix-no-lint-typecheck/snap.txt new file mode 100644 index 0000000000..8cd3742c35 --- /dev/null +++ b/packages/cli/snap-tests/check-fix-no-lint-typecheck/snap.txt @@ -0,0 +1,3 @@ +> vp check --fix --no-lint +pass: Formatting completed for checked files (ms) +pass: Found no type errors in 2 files (ms, threads) diff --git a/packages/cli/snap-tests/check-fix-no-lint-typecheck/src/index.ts b/packages/cli/snap-tests/check-fix-no-lint-typecheck/src/index.ts new file mode 100644 index 0000000000..fcfa1b9ab2 --- /dev/null +++ b/packages/cli/snap-tests/check-fix-no-lint-typecheck/src/index.ts @@ -0,0 +1,2 @@ +const value: number = 42; +export { value }; diff --git a/packages/cli/snap-tests/check-fix-no-lint-typecheck/steps.json b/packages/cli/snap-tests/check-fix-no-lint-typecheck/steps.json new file mode 100644 index 0000000000..68a47942e1 --- /dev/null +++ b/packages/cli/snap-tests/check-fix-no-lint-typecheck/steps.json @@ -0,0 +1,6 @@ +{ + "env": { + "VITE_DISABLE_AUTO_INSTALL": "1" + }, + "commands": ["vp check --fix --no-lint"] +} diff --git a/packages/cli/snap-tests/check-fix-no-lint-typecheck/vite.config.ts b/packages/cli/snap-tests/check-fix-no-lint-typecheck/vite.config.ts new file mode 100644 index 0000000000..ecd9dc9d34 --- /dev/null +++ b/packages/cli/snap-tests/check-fix-no-lint-typecheck/vite.config.ts @@ -0,0 +1,8 @@ +export default { + lint: { + options: { + typeAware: true, + typeCheck: true, + }, + }, +}; diff --git a/packages/cli/snap-tests/check-no-fmt-no-lint-typecheck/package.json b/packages/cli/snap-tests/check-no-fmt-no-lint-typecheck/package.json new file mode 100644 index 0000000000..0ee0d8bfd1 --- /dev/null +++ b/packages/cli/snap-tests/check-no-fmt-no-lint-typecheck/package.json @@ -0,0 +1,5 @@ +{ + "name": "check-no-fmt-no-lint-typecheck", + "version": "0.0.0", + "private": true +} diff --git a/packages/cli/snap-tests/check-no-fmt-no-lint-typecheck/snap.txt b/packages/cli/snap-tests/check-no-fmt-no-lint-typecheck/snap.txt new file mode 100644 index 0000000000..16a4fbf9d3 --- /dev/null +++ b/packages/cli/snap-tests/check-no-fmt-no-lint-typecheck/snap.txt @@ -0,0 +1,2 @@ +> vp check --no-fmt --no-lint +pass: Found no type errors in 2 files (ms, threads) diff --git a/packages/cli/snap-tests/check-no-fmt-no-lint-typecheck/src/index.ts b/packages/cli/snap-tests/check-no-fmt-no-lint-typecheck/src/index.ts new file mode 100644 index 0000000000..3b3d6d4fbc --- /dev/null +++ b/packages/cli/snap-tests/check-no-fmt-no-lint-typecheck/src/index.ts @@ -0,0 +1,2 @@ +const value: number = 42; +export { value }; diff --git a/packages/cli/snap-tests/check-no-fmt-no-lint-typecheck/steps.json b/packages/cli/snap-tests/check-no-fmt-no-lint-typecheck/steps.json new file mode 100644 index 0000000000..2052f4dce3 --- /dev/null +++ b/packages/cli/snap-tests/check-no-fmt-no-lint-typecheck/steps.json @@ -0,0 +1,6 @@ +{ + "env": { + "VITE_DISABLE_AUTO_INSTALL": "1" + }, + "commands": ["vp check --no-fmt --no-lint"] +} diff --git a/packages/cli/snap-tests/check-no-fmt-no-lint-typecheck/vite.config.ts b/packages/cli/snap-tests/check-no-fmt-no-lint-typecheck/vite.config.ts new file mode 100644 index 0000000000..ecd9dc9d34 --- /dev/null +++ b/packages/cli/snap-tests/check-no-fmt-no-lint-typecheck/vite.config.ts @@ -0,0 +1,8 @@ +export default { + lint: { + options: { + typeAware: true, + typeCheck: true, + }, + }, +}; diff --git a/packages/cli/snap-tests/check-no-lint-typecheck-fail/package.json b/packages/cli/snap-tests/check-no-lint-typecheck-fail/package.json new file mode 100644 index 0000000000..357942c3d4 --- /dev/null +++ b/packages/cli/snap-tests/check-no-lint-typecheck-fail/package.json @@ -0,0 +1,5 @@ +{ + "name": "check-no-lint-typecheck-fail", + "version": "0.0.0", + "private": true +} diff --git a/packages/cli/snap-tests/check-no-lint-typecheck-fail/snap.txt b/packages/cli/snap-tests/check-no-lint-typecheck-fail/snap.txt new file mode 100644 index 0000000000..d5266439a8 --- /dev/null +++ b/packages/cli/snap-tests/check-no-lint-typecheck-fail/snap.txt @@ -0,0 +1,11 @@ +[1]> vp check --no-lint +pass: All 4 files are correctly formatted (ms, threads) +error: Type errors found +× typescript(TS2322): Type 'string' is not assignable to type 'number'. + ╭─[src/index.ts:1:7] + 1 │ const value: number = "not a number"; + · ───── + 2 │ export { value }; + ╰──── + +Found 1 error and 0 warnings in 2 files (ms, threads) diff --git a/packages/cli/snap-tests/check-no-lint-typecheck-fail/src/index.ts b/packages/cli/snap-tests/check-no-lint-typecheck-fail/src/index.ts new file mode 100644 index 0000000000..21f1da94fe --- /dev/null +++ b/packages/cli/snap-tests/check-no-lint-typecheck-fail/src/index.ts @@ -0,0 +1,2 @@ +const value: number = "not a number"; +export { value }; diff --git a/packages/cli/snap-tests/check-no-lint-typecheck-fail/steps.json b/packages/cli/snap-tests/check-no-lint-typecheck-fail/steps.json new file mode 100644 index 0000000000..8f1a7ce30d --- /dev/null +++ b/packages/cli/snap-tests/check-no-lint-typecheck-fail/steps.json @@ -0,0 +1,6 @@ +{ + "env": { + "VITE_DISABLE_AUTO_INSTALL": "1" + }, + "commands": ["vp check --no-lint"] +} diff --git a/packages/cli/snap-tests/check-no-lint-typecheck-fail/vite.config.ts b/packages/cli/snap-tests/check-no-lint-typecheck-fail/vite.config.ts new file mode 100644 index 0000000000..76a798b58b --- /dev/null +++ b/packages/cli/snap-tests/check-no-lint-typecheck-fail/vite.config.ts @@ -0,0 +1,11 @@ +export default { + lint: { + options: { + typeAware: true, + typeCheck: true, + }, + rules: { + "no-eval": "error", + }, + }, +}; diff --git a/packages/cli/snap-tests/check-no-lint-typecheck/package.json b/packages/cli/snap-tests/check-no-lint-typecheck/package.json new file mode 100644 index 0000000000..bccda07052 --- /dev/null +++ b/packages/cli/snap-tests/check-no-lint-typecheck/package.json @@ -0,0 +1,5 @@ +{ + "name": "check-no-lint-typecheck", + "version": "0.0.0", + "private": true +} diff --git a/packages/cli/snap-tests/check-no-lint-typecheck/snap.txt b/packages/cli/snap-tests/check-no-lint-typecheck/snap.txt new file mode 100644 index 0000000000..469b0db71e --- /dev/null +++ b/packages/cli/snap-tests/check-no-lint-typecheck/snap.txt @@ -0,0 +1,3 @@ +> vp check --no-lint +pass: All 4 files are correctly formatted (ms, threads) +pass: Found no type errors in 2 files (ms, threads) diff --git a/packages/cli/snap-tests/check-no-lint-typecheck/src/index.ts b/packages/cli/snap-tests/check-no-lint-typecheck/src/index.ts new file mode 100644 index 0000000000..6211486d2f --- /dev/null +++ b/packages/cli/snap-tests/check-no-lint-typecheck/src/index.ts @@ -0,0 +1,8 @@ +// Includes a no-eval violation to verify that `--type-check-only` suppresses +// lint rules while still running type-check. The file itself is type-correct. +function run(code: string): string { + eval(code); + return code; +} + +export { run }; diff --git a/packages/cli/snap-tests/check-no-lint-typecheck/steps.json b/packages/cli/snap-tests/check-no-lint-typecheck/steps.json new file mode 100644 index 0000000000..8f1a7ce30d --- /dev/null +++ b/packages/cli/snap-tests/check-no-lint-typecheck/steps.json @@ -0,0 +1,6 @@ +{ + "env": { + "VITE_DISABLE_AUTO_INSTALL": "1" + }, + "commands": ["vp check --no-lint"] +} diff --git a/packages/cli/snap-tests/check-no-lint-typecheck/vite.config.ts b/packages/cli/snap-tests/check-no-lint-typecheck/vite.config.ts new file mode 100644 index 0000000000..76a798b58b --- /dev/null +++ b/packages/cli/snap-tests/check-no-lint-typecheck/vite.config.ts @@ -0,0 +1,11 @@ +export default { + lint: { + options: { + typeAware: true, + typeCheck: true, + }, + rules: { + "no-eval": "error", + }, + }, +}; From 0030c91dc348862ecf729a4a55205f74fbaa6a02 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=EC=9D=B4=EC=A2=85=EA=B2=BD?= Date: Thu, 23 Apr 2026 00:08:23 +0900 Subject: [PATCH 4/4] docs(check): document --no-fmt/--no-lint flags and type-check-only use case --- docs/guide/check.md | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/docs/guide/check.md b/docs/guide/check.md index 1f5b984e1c..067b6b02aa 100644 --- a/docs/guide/check.md +++ b/docs/guide/check.md @@ -14,9 +14,14 @@ We recommend turning `typeCheck` on so `vp check` becomes the single command for ```bash vp check -vp check --fix # Format and run autofixers. +vp check --fix # Format and run autofixers. +vp check --no-fmt # Skip format; run lint (and type-check if enabled). +vp check --no-lint # Skip lint rules; keep type-check when enabled. +vp check --no-fmt --no-lint # Type-check only (requires `typeCheck` enabled). ``` +When `lint.options.typeCheck` is enabled, `--no-lint` keeps type diagnostics by forwarding Oxlint's `--type-check-only` flag — useful for triaging type errors without lint noise. If `typeCheck` is not enabled, `--no-lint` simply skips the lint phase altogether, and `vp check --no-fmt --no-lint` exits with `No checks enabled` (enable `lint.options.typeCheck` to use the type-check-only invocation). + ## Configuration `vp check` uses the same configuration you already define for linting and formatting: