swc-project/swc · error

failed to parse jsx option {}: '{}' is not an expression

Error message

failed to parse jsx option {}: '{}' is not an expression

What it means

For the const-modules transform, every globals value is parsed as a JavaScript expression with parse_file_as_expr (per export name, cached by source text). If parsing fails, a diagnostic is emitted first when a HANDLER is set, then the code panics with 'failed to parse jsx option {name}: \'{src}\' is not an expression'. Values must be expressions, not statements.

Source

Thrown at crates/swc_ecma_transforms_optimization/src/const_modules.rs:71

    if let Some(expr) = CACHE.get(&fm.src) {
        return expr.clone();
    }

    let expr = parse_file_as_expr(
        &fm,
        Default::default(),
        Default::default(),
        None,
        &mut Vec::new(),
    )
    .map_err(|e| {
        if HANDLER.is_set() {
            HANDLER.with(|h| e.into_diagnostic(h).emit())
        }
    })
    .map(drop_span)
    .unwrap_or_else(|()| {
        panic!(
            "failed to parse jsx option {}: '{}' is not an expression",
            name, fm.src,
        )
    });

    let expr = Arc::new(*expr);

    CACHE.insert(fm.src.clone(), expr.clone());

    expr
}

struct ConstModules {
    globals: HashMap<Wtf8Atom, HashMap<Wtf8Atom, Arc<Expr>>>,
    scope: Scope,
}

#[derive(Default)]

View on GitHub (pinned to 5176682b65)

Solutions

  1. Make every globals value a valid expression: "true", "'production'", "(() => { ... })()"
  2. Wrap statement-like logic in an IIFE so it becomes a single expression
  3. Check the panic text for the exact (name, src) pair that failed and fix just that entry
  4. Pre-validate values on the JS side by attempting new Function('return (' + value + ')')

Example fix

// before (.swcrc)
"globals": { "@app/env": { "MODE": "const MODE = 'dev'" } }

// after
"globals": { "@app/env": { "MODE": "'dev'" } }
Defensive patterns

Strategy: validation

Validate before calling

// JS: sanity-check every globals value parses as an expression
function validateConstModules(globals) {
  for (const [mod, entries] of Object.entries(globals)) {
    for (const [name, src] of Object.entries(entries)) {
      try { new Function(`return (${src})`); }
      catch { throw new Error(`globals["${mod}"]."${name}" is not an expression: ${src}`); }
    }
  }
}

Prevention

When it happens

Trigger: jsc.transform.constModules.globals entries whose value strings are statements ("let a = 1", "import x") or contain syntax errors (unbalanced brackets, stray characters); the (name, src) pair is reported in the panic.

Common situations: Porting webpack DefinePlugin/babel-plugin-transform-define values that were loose strings, values intended as statements or declarations, template-generated values with trailing semicolons plus statements, JSON configs where quoting got mangled.

Understand the failure class

Related errors


AI-assisted analysis of swc-project/swc@5176682b65 (2026-08-17). Data as JSON: /api/errors/aeb7d272141c2eb9. Report an issue: GitHub.