swc-project/swc · error

The const_module namespace `{}` cannot be used without membe

Error message

The const_module namespace `{}` cannot be used without member accessor

What it means

The const_modules pass (swc_ecma_transforms_optimization) inlines imports of modules you register as compile-time constant maps. Named/default imports are replaced by their literal values, but a namespace import (`import * as ns from '...'`) is only supported when accessed through a member (`ns.FLAG`), because the namespace itself has no single value. When such a binding is used bare as an object shorthand property (`{ ns }` in visit_mut_prop, const_modules.rs:216-233), the pass panics rather than emit incorrect code; the sibling arm at const_modules.rs:170 panics the same way for bare `ns` expressions.

Source

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

                n.visit_mut_children_with(self);
            }
        };
    }

    fn visit_mut_prop(&mut self, n: &mut Prop) {
        match n {
            Prop::Shorthand(id) => {
                let sym_wtf8: Wtf8Atom = id.sym.clone().into();
                if let Some(value) = self.scope.imported.get(&sym_wtf8) {
                    *n = Prop::KeyValue(KeyValueProp {
                        key: id.take().into(),
                        value: Box::new((**value).clone()),
                    });
                    return;
                }

                if self.scope.namespace.contains(&id.to_id()) {
                    panic!(
                        "The const_module namespace `{}` cannot be used without member accessor",
                        id.sym
                    )
                }
            }
            _ => n.visit_mut_children_with(self),
        }
    }
}

View on GitHub (pinned to 5176682b65)

Solutions

  1. Switch to named imports from the const module (`import { FLAG } from '@app/constants'`) so each use inlines a literal value.
  2. Change every bare use of the namespace to member access (`ns.FLAG`) before running the pass.
  3. If you need the namespace as a real value, remove that module from the const-modules globals map so it stays a runtime import.

Example fix

// before
import * as env from '@app/constants';
const cfg = { env };

// after
import { env } from '@app/constants';
const cfg = { env };
Defensive patterns

Strategy: validation

Validate before calling

// Before applying const_modules, ensure every namespace import from a
// configured const module is only used via member access.
#[derive(Default)]
struct FindBareNamespaceUse {
    ns_ids: HashSet<Id>,
    bad: Vec<Id>,
}
impl Visit for FindBareNamespaceUse {
    fn visit_member_expr(&mut self, m: &MemberExpr) {
        // ns.member is fine; only inspect the property side
        m.prop.visit_with(self);
    }
    fn visit_expr(&mut self, e: &Expr) {
        if let Expr::Ident(i) = e {
            if self.ns_ids.contains(&i.to_id()) {
                self.bad.push(i.to_id());
            }
        }
        e.visit_children_with(self);
    }
    fn visit_prop(&mut self, p: &Prop) {
        if let Prop::Shorthand(i) = p {
            if self.ns_ids.contains(&i.to_id()) {
                self.bad.push(i.to_id());
            }
        }
        p.visit_children_with(self);
    }
}

Try / catch

// Last resort around a pass that panics:
let result = std::panic::catch_unwind(std::panic::AssertUnwindSafe(|| {
    program.apply(const_modules(globals));
}));
if result.is_err() {
    // surface file name + the const-module namespace usage to the user
    return Err(anyhow!("const_modules rejected this file; check namespace imports"));
}

Prevention

When it happens

Trigger: Running const_modules(globals) (e.g. via swc's jsc.experimental.constModules config) on a file with `import * as ns from '<module-listed-in-globals>'` followed by an object shorthand `{ ns }`, or any bare value use of `ns` (e.g. `console.log(ns)`).

Common situations: Refactoring named imports to namespace imports while using constant modules for feature flags/env values; copy-pasting code that spreads or logs the whole namespace (`{ ...ns }`, `{ ns }`).

Related errors


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