Skip to content

Commit 16b8058

Browse files
committed
feat(oxfmt): Support vite-plus/resolveConfig for vite.config.ts (#22454)
Closes #21603, fixes #21418 To simplify the review process, I'll first add support to Oxfmt. In the next PR, I'll move that implementation to `shared`.
1 parent 36fc0ec commit 16b8058

20 files changed

Lines changed: 1165 additions & 103 deletions

File tree

apps/oxfmt/package.json

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -36,6 +36,7 @@
3636
"json-schema-to-typescript": "catalog:",
3737
"svelte": "^5.55.5",
3838
"tsdown": "catalog:",
39+
"vite-plus": "catalog:",
3940
"vitest": "catalog:",
4041
"vscode-languageserver-protocol": "^3.17.5",
4142
"vscode-languageserver-textdocument": "^1.0.12"

apps/oxfmt/src-js/cli/js_config.ts

Lines changed: 11 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -19,30 +19,29 @@ export async function loadJsConfig(path: string): Promise<object> {
1919
return config as object;
2020
}
2121

22-
const VITE_OXFMT_CONFIG_FIELD = "fmt";
22+
const VP_OXFMT_CONFIG_FIELD = "fmt";
23+
let vitePlusCache = null as typeof import("vite-plus") | null;
24+
2325
/**
24-
* Load a Vite+ config file (`vite.config.ts`) and extract the `.fmt` field.
26+
* Load a Vite+ config file (`vite.config.ts`) via `vite-plus`'s `resolveConfig` and extract the `.fmt` field.
2527
*
2628
* @param path - Absolute path to the Vite config file
2729
* @returns Config object from `.fmt` field, or `null` to signal "skip"
2830
*/
2931
export async function loadVitePlusConfig(path: string): Promise<object | null> {
30-
const config = await importJsConfig(path, Date.now());
32+
vitePlusCache ??= await import("vite-plus");
33+
const config = await vitePlusCache.resolveConfig({ configFile: path }, "build");
3134

32-
// NOTE: Vite configs may export a function via `defineConfig(() => ({ ... }))`,
33-
// but we don't know the arguments to call the function.
34-
// Treat non-object exports as "no config" and skip for now.
35-
if (!isObject(config)) return null;
35+
// NOTE: return `null` if `.fmt` is missing (signals "skip" to Rust side)
36+
if (VP_OXFMT_CONFIG_FIELD in config === false) return null;
3637

37-
const fmtConfig = (config as Record<string, unknown>)[VITE_OXFMT_CONFIG_FIELD];
38-
// NOTE: return `null` if missing (signals "skip" to Rust side)
39-
if (fmtConfig === undefined) return null;
38+
const fmtConfig = config[VP_OXFMT_CONFIG_FIELD];
4039

4140
if (!isObject(fmtConfig)) {
4241
throw new Error(
43-
`The \`${VITE_OXFMT_CONFIG_FIELD}\` field in the default export must be an object.`,
42+
`The \`${VP_OXFMT_CONFIG_FIELD}\` field in the default export must be an object.`,
4443
);
4544
}
4645

47-
return fmtConfig;
46+
return fmtConfig as object;
4847
}

apps/oxfmt/test/cli/utils.ts

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -316,12 +316,13 @@ function normalizeOutput(output: string, cwd: string): string {
316316

317317
return (
318318
output
319+
// oxlint-disable-next-line no-control-regex
320+
.replace(/\x1b\[[0-9;]*m/g, "")
319321
.replace(/\d+(?:\.\d+)?s|\d+ms/g, "<time>")
322+
.replace(/\.timestamp-[0-9a-f-]+/g, ".timestamp-<timestamp-hash>")
320323
.replace(/\\/g, "/")
321324
.replace(new RegExp(RegExp.escape(cwdPath), "g"), "<cwd>")
322325
.replace(new RegExp(RegExp.escape(rootPath), "g"), "<root>")
323-
// oxlint-disable-next-line no-control-regex
324-
.replace(/\x1b\[[0-9;]*m/g, "")
325326
.replace(/×/g, "x")
326327
.replace(//g, ",")
327328
.replace(//g, "-")

apps/oxfmt/test/cli/vite_plus/0.snap.md

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,9 @@ VP_VERSION=1 oxfmt --check test.ts
1616
- child/
1717
- test.ts
1818
- vite.config.ts
19+
- fn_export/
20+
- test.ts
21+
- vite.config.ts
1922
- no_fmt_field/
2023
- test.ts
2124
- vite.config.ts
@@ -28,9 +31,6 @@ VP_VERSION=1 oxfmt --check test.ts
2831
- child/
2932
- test.ts
3033
- vite.config.ts
31-
- skip_fn_export/
32-
- test.ts
33-
- vite.config.ts
3434
```
3535

3636
# Result

apps/oxfmt/test/cli/vite_plus/1.snap.md

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,9 @@ VP_VERSION=1 oxfmt --check --config vite.config.ts test.ts
1616
- child/
1717
- test.ts
1818
- vite.config.ts
19+
- fn_export/
20+
- test.ts
21+
- vite.config.ts
1922
- no_fmt_field/ <CWD>
2023
- test.ts
2124
- vite.config.ts
@@ -28,9 +31,6 @@ VP_VERSION=1 oxfmt --check --config vite.config.ts test.ts
2831
- child/
2932
- test.ts
3033
- vite.config.ts
31-
- skip_fn_export/
32-
- test.ts
33-
- vite.config.ts
3434
```
3535

3636
# Result

apps/oxfmt/test/cli/vite_plus/2.snap.md

Lines changed: 13 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,9 @@ VP_VERSION=1 oxfmt --check --config vite.config.ts test.ts
1616
- child/ <CWD>
1717
- test.ts
1818
- vite.config.ts
19+
- fn_export/
20+
- test.ts
21+
- vite.config.ts
1922
- no_fmt_field/
2023
- test.ts
2124
- vite.config.ts
@@ -28,9 +31,6 @@ VP_VERSION=1 oxfmt --check --config vite.config.ts test.ts
2831
- child/
2932
- test.ts
3033
- vite.config.ts
31-
- skip_fn_export/
32-
- test.ts
33-
- vite.config.ts
3434
```
3535

3636
# Result
@@ -45,9 +45,18 @@ VP_VERSION=1 oxfmt --check --config vite.config.ts test.ts
4545

4646
## stderr
4747
```
48+
vite.config.ts (1:452) [UNRESOLVED_IMPORT] Warning: Could not resolve 'non-existent-module' in vite.config.ts
49+
,-[ vite.config.ts:1:453 ]
50+
|
51+
1 | const __vite_injected_original_dirname = "<cwd>";const __vite_injected_original_filename = "<cwd>/vite.config.ts";const __vite_injected_original_import_meta_url = "file://<cwd>/vite.config.ts";import "non-existent-module";
52+
| ----------|----------
53+
| `------------ Module not found, treating it as an external dependency
54+
---╯
55+
56+
failed to load config from <cwd>/vite.config.ts
4857
Failed to load configuration file.
4958
<cwd>/vite.config.ts
50-
Error [ERR_MODULE_NOT_FOUND]: Cannot find package 'non-existent-module' imported from <cwd>/vite.config.ts
59+
Error [ERR_MODULE_NOT_FOUND]: Cannot find package 'non-existent-module' imported from <root>/apps/oxfmt/node_modules/.vite-temp/vite.config.ts.timestamp-<timestamp-hash>.mjs
5160
Ensure the file has a valid default export of a JSON-serializable configuration object.
5261
```
5362

apps/oxfmt/test/cli/vite_plus/3.snap.md

Lines changed: 13 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,9 @@ VP_VERSION=1 oxfmt --check test.ts
1616
- child/ <CWD>
1717
- test.ts
1818
- vite.config.ts
19+
- fn_export/
20+
- test.ts
21+
- vite.config.ts
1922
- no_fmt_field/
2023
- test.ts
2124
- vite.config.ts
@@ -28,9 +31,6 @@ VP_VERSION=1 oxfmt --check test.ts
2831
- child/
2932
- test.ts
3033
- vite.config.ts
31-
- skip_fn_export/
32-
- test.ts
33-
- vite.config.ts
3434
```
3535

3636
# Result
@@ -45,9 +45,18 @@ VP_VERSION=1 oxfmt --check test.ts
4545

4646
## stderr
4747
```
48+
vite.config.ts (1:452) [UNRESOLVED_IMPORT] Warning: Could not resolve 'non-existent-module' in vite.config.ts
49+
,-[ vite.config.ts:1:453 ]
50+
|
51+
1 | const __vite_injected_original_dirname = "<cwd>";const __vite_injected_original_filename = "<cwd>/vite.config.ts";const __vite_injected_original_import_meta_url = "file://<cwd>/vite.config.ts";import "non-existent-module";
52+
| ----------|----------
53+
| `------------ Module not found, treating it as an external dependency
54+
---╯
55+
56+
failed to load config from <cwd>/vite.config.ts
4857
Failed to load configuration file.
4958
<cwd>/vite.config.ts
50-
Error [ERR_MODULE_NOT_FOUND]: Cannot find package 'non-existent-module' imported from <cwd>/vite.config.ts
59+
Error [ERR_MODULE_NOT_FOUND]: Cannot find package 'non-existent-module' imported from <root>/apps/oxfmt/node_modules/.vite-temp/vite.config.ts.timestamp-<timestamp-hash>.mjs
5160
Ensure the file has a valid default export of a JSON-serializable configuration object.
5261
```
5362

apps/oxfmt/test/cli/vite_plus/4.snap.md

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,9 @@ VP_VERSION=1 oxfmt --check test.ts
1616
- child/
1717
- test.ts
1818
- vite.config.ts
19+
- fn_export/
20+
- test.ts
21+
- vite.config.ts
1922
- no_fmt_field/ <CWD>
2023
- test.ts
2124
- vite.config.ts
@@ -28,9 +31,6 @@ VP_VERSION=1 oxfmt --check test.ts
2831
- child/
2932
- test.ts
3033
- vite.config.ts
31-
- skip_fn_export/
32-
- test.ts
33-
- vite.config.ts
3434
```
3535

3636
# Result

apps/oxfmt/test/cli/vite_plus/5.snap.md

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,9 @@ VP_VERSION=1 oxfmt --check test.ts
1616
- child/
1717
- test.ts
1818
- vite.config.ts
19+
- fn_export/
20+
- test.ts
21+
- vite.config.ts
1922
- no_fmt_field/
2023
- test.ts
2124
- vite.config.ts
@@ -28,9 +31,6 @@ VP_VERSION=1 oxfmt --check test.ts
2831
- child/ <CWD>
2932
- test.ts
3033
- vite.config.ts
31-
- skip_fn_export/
32-
- test.ts
33-
- vite.config.ts
3434
```
3535

3636
# Result

apps/oxfmt/test/cli/vite_plus/6.snap.md

Lines changed: 7 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,9 @@ VP_VERSION=1 oxfmt --check test.ts
1616
- child/
1717
- test.ts
1818
- vite.config.ts
19+
- fn_export/ <CWD>
20+
- test.ts
21+
- vite.config.ts
1922
- no_fmt_field/
2023
- test.ts
2124
- vite.config.ts
@@ -28,21 +31,20 @@ VP_VERSION=1 oxfmt --check test.ts
2831
- child/
2932
- test.ts
3033
- vite.config.ts
31-
- skip_fn_export/ <CWD>
32-
- test.ts
33-
- vite.config.ts
3434
```
3535

3636
# Result
3737

3838
## Exit code
39-
0
39+
1
4040

4141
## stdout
4242
```
4343
Checking formatting...
4444
45-
All matched files use the correct format.
45+
test.ts (<time>)
46+
47+
Format issues found in above 1 files. Run without `--check` to fix.
4648
Finished in <time> on 1 files using 1 threads.
4749
```
4850

0 commit comments

Comments
 (0)