Skip to content

Commit 52fa070

Browse files
branchseerclaude
andcommitted
refactor(static-config): use specific oxc_* crates and add README
Replace umbrella `oxc` dependency with `oxc_ast`, `oxc_parser`, and `oxc_span` for more precise dependency tracking. Add README documenting supported patterns, config resolution order, return type semantics, and limitations. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
1 parent dd117c3 commit 52fa070

File tree

5 files changed

+70
-9
lines changed

5 files changed

+70
-9
lines changed

Cargo.lock

Lines changed: 3 additions & 1 deletion
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

Cargo.toml

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -211,7 +211,10 @@ oxc = { version = "0.115.0", features = [
211211
"cfg",
212212
] }
213213
oxc_allocator = { version = "0.115.0", features = ["pool"] }
214+
oxc_ast = "0.115.0"
214215
oxc_ecmascript = "0.115.0"
216+
oxc_parser = "0.115.0"
217+
oxc_span = "0.115.0"
215218
oxc_napi = "0.115.0"
216219
oxc_minify_napi = "0.115.0"
217220
oxc_parser_napi = "0.115.0"

crates/vite_static_config/Cargo.toml

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,8 +8,10 @@ license.workspace = true
88
repository.workspace = true
99

1010
[dependencies]
11-
oxc = { workspace = true }
1211
oxc_allocator = { workspace = true }
12+
oxc_ast = { workspace = true }
13+
oxc_parser = { workspace = true }
14+
oxc_span = { workspace = true }
1315
rustc-hash = { workspace = true }
1416
serde_json = { workspace = true }
1517
vite_path = { workspace = true }
Lines changed: 56 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,56 @@
1+
# vite_static_config
2+
3+
Statically extracts configuration from `vite.config.*` files without executing JavaScript.
4+
5+
## What it does
6+
7+
Parses vite config files using [oxc_parser](https://crates.io/crates/oxc_parser) and extracts
8+
top-level fields whose values are pure JSON literals. This allows reading config like `run`
9+
without needing a Node.js runtime (NAPI).
10+
11+
## Supported patterns
12+
13+
**ESM:**
14+
```js
15+
export default { run: { tasks: { build: { command: "echo build" } } } }
16+
export default defineConfig({ run: { cacheScripts: true } })
17+
```
18+
19+
**CJS:**
20+
```js
21+
module.exports = { run: { tasks: { build: { command: "echo build" } } } }
22+
module.exports = defineConfig({ run: { cacheScripts: true } })
23+
```
24+
25+
## Config file resolution
26+
27+
Searches for config files in the same order as Vite's
28+
[`DEFAULT_CONFIG_FILES`](https://github.com/vitejs/vite/blob/25227bbdc7de0ed07cf7bdc9a1a733e3a9a132bc/packages/vite/src/node/constants.ts#L98-L105):
29+
30+
1. `vite.config.js`
31+
2. `vite.config.mjs`
32+
3. `vite.config.ts`
33+
4. `vite.config.cjs`
34+
5. `vite.config.mts`
35+
6. `vite.config.cts`
36+
37+
## Return type
38+
39+
`resolve_static_config` returns `Option<FxHashMap<Box<str>, StaticFieldValue>>`:
40+
41+
- **`None`** — config is not statically analyzable (no config file, parse error, no
42+
`export default`/`module.exports`, or the exported value is not an object literal).
43+
Caller should fall back to runtime evaluation (e.g. NAPI).
44+
- **`Some(map)`** — config object was successfully located:
45+
- `StaticFieldValue::Json(value)` — field value extracted as pure JSON
46+
- `StaticFieldValue::NonStatic` — field exists but contains non-JSON expressions
47+
(function calls, variables, template literals with interpolation, etc.)
48+
- Key absent — field does not exist in the config object
49+
50+
## Limitations
51+
52+
- Only extracts values that are pure JSON literals (strings, numbers, booleans, null,
53+
arrays, and objects composed of these)
54+
- Fields with dynamic values (function calls, variable references, spread operators,
55+
computed properties, template literals with expressions) are reported as `NonStatic`
56+
- Does not follow imports or evaluate expressions

crates/vite_static_config/src/lib.rs

Lines changed: 5 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -4,12 +4,10 @@
44
//! top-level fields whose values are pure JSON literals. This allows reading
55
//! config like `run` without needing a Node.js runtime.
66
7-
use oxc::{
8-
ast::ast::{Expression, ObjectPropertyKind, Program, Statement},
9-
parser::Parser,
10-
span::SourceType,
11-
};
127
use oxc_allocator::Allocator;
8+
use oxc_ast::ast::{Expression, ObjectPropertyKind, Program, Statement};
9+
use oxc_parser::Parser;
10+
use oxc_span::SourceType;
1311
use rustc_hash::FxHashMap;
1412
use vite_path::AbsolutePath;
1513

@@ -171,7 +169,7 @@ fn extract_config_from_expr(expr: &Expression<'_>) -> StaticConfig {
171169
/// [`StaticFieldValue::NonStatic`]. Spread elements and computed properties
172170
/// are not representable so they are silently skipped (their keys are unknown).
173171
fn extract_object_fields(
174-
obj: &oxc::ast::ast::ObjectExpression<'_>,
172+
obj: &oxc_ast::ast::ObjectExpression<'_>,
175173
) -> FxHashMap<Box<str>, StaticFieldValue> {
176174
let mut map = FxHashMap::default();
177175

@@ -236,7 +234,7 @@ fn expr_to_json(expr: &Expression<'_>) -> Option<serde_json::Value> {
236234

237235
Expression::UnaryExpression(unary) => {
238236
// Handle negative numbers: -42
239-
if unary.operator == oxc::ast::ast::UnaryOperator::UnaryNegation
237+
if unary.operator == oxc_ast::ast::UnaryOperator::UnaryNegation
240238
&& let Expression::NumericLiteral(lit) = &unary.argument
241239
{
242240
return Some(f64_to_json_number(-lit.value));

0 commit comments

Comments
 (0)