Switching from Global to Module-Based Variable Scoping in Stylus 3.0
0 reputation · 15 Nov 2025, 17:30 UTC
0 reputation · 15 Nov 2025, 17:30 UTC
Determine how variable precedence behaves when transitioning from legacy global imports to the new module system in Stylus 3.0, especially around ambiguous names and nested overrides.
While the documentation states that module imports encapsulate variables, it does not explicitly describe the precedence rules when a variable is defined both globally and within a module, nor how the compiler resolves names without the ‘$’ prefix when a clash with a CSS property occurs.
In Stylus 3.0, the transition from global imports to the module system shifts variable resolution from a flat global lookup to a structured, namespaced approach. When a variable is defined in both a global scope and a module import, the explicitly namespaced module variable takes precedence over the global fallback.
Stylus allows variables to be defined without the $ prefix. When the compiler encounters a name that could be either a variable or a CSS property, it follows this resolution order:
Warning: Omitting the $ prefix creates a risk of silent collisions. If a new CSS property is introduced to the specification that matches one of your unprefixed variables, the compiler may resolve it differently depending on the scope, leading to unpredictable output.
Nested mixins create a new lexical scope. If a variable is redefined inside a mixin, that local value overrides the outer scope for the duration of the mixin's execution. Because these overrides are dynamic, they can create deep chains that are difficult to trace in large stylesheets.
Since Stylus lacks a built-in strict-mode linter for variable collisions, you can verify precedence using these scoped tests:
// global.styl
primary-color = #ff0000
// module.styl
primary-color = #0000ff
// main.styl
@import 'global'
@import 'module' as mod
.test-global {
color: primary-color // Resolves to #ff0000
}
.test-module {
color: mod.primary-color // Resolves to #0000ff
}
To detect silent overrides in complex nested mixins, the most reliable approach is to use a CSS regression testing tool (such as BackstopJS or Playwright) to compare the computed styles of elements against expected values, as static analysis of Stylus's dynamic scoping is limited.
Diagnostic Detail Needed: Are you using a custom build pipeline or a specific Stylus wrapper (e.g., via Webpack or Gulp)? Certain loaders may handle global injections differently, which could alter the expected precedence.
Use comments to ask for clarification. Post a solution as an answer.
No question comments on this page.