@import or @require for shared Stylus partials when duplicate output is a concern
0 reputation · 09 Oct 2023, 22:25 UTC
0 reputation · 09 Oct 2023, 22:25 UTC
In a Stylus codebase with many partials that all depend on a shared library of mixins and variables, I need to pick a consistent inclusion strategy. Stylus documents two directives: @import inlines the target file on every reference, while @require includes a given file only once per compilation.
The concrete constraint is stylesheet size: the shared file is referenced from dozens of component partials, so I want to avoid duplicated CSS in the compiled output. @require seems like the obvious default, but I am unsure about the edge cases that affect the decision.
Specifically, the documentation and community notes suggest that @require deduplication is keyed on the resolved file path, which raises questions about symlinked or differently-pathed references to the same file. I also understand that mixing @import and @require on the same file can silently produce duplicates, since @import does not respect the already-loaded tracking.
My questions:
@require safe to rely on as the sole deduplication mechanism when some partials are reached through symlinks or relative paths that resolve differently?@require-managed dependencies without double output?@require 'components/*', or does ordering become ambiguous?Assume a recent Stylus version compiled via the Node.js API; I can verify behavior with a small two-partial test project if needed.
30775 reputation · 10 Oct 2023, 06:03 UTC
To prevent duplicate CSS output in a codebase with shared partials, use @require. While @import inlines the target file every time it is called, @require ensures the file is evaluated and included only once per compilation cycle.
The distinction between these directives centers on how Stylus tracks the execution state of a file. @require maintains a registry of loaded files; once a file is processed, subsequent @require calls for that same file are ignored.
Deduplication is based on the resolved absolute path of the file. If your build system or OS resolves symlinks to their real paths before Stylus processes them, @require remains safe. However, if the environment treats a symlink and its target as distinct paths, Stylus may treat them as different files and include the content twice. To verify this in your specific Node.js environment, create two partials that @require the same file via different paths (one relative, one absolute or symlinked) and check the output for duplicate selectors.
If a file contains logic that must be re-evaluated per call-site (such as emitting specific CSS based on a variable defined in the parent file), @require is inappropriate because it suppresses subsequent executions. The documented pattern for this is to wrap the logic in a mixin. Define the mixin in a @require-ed library file, then call that mixin within your component partials. This provides the benefit of single-file loading while allowing per-call-site output.
When using glob patterns like @require 'components/*', Stylus processes files in the order they are returned by the file system. This makes ordering ambiguous. If your components depend on a specific load order, you should explicitly @require the dependency files first, followed by the glob pattern for the components.
@import with @require across all component partials referencing the shared library.You can verify the output using a simple CLI test to ensure no duplication occurs:
# Create a test file that requires the same partial twice stylus -p test.styl > output.css # Check for duplicate selectors grep ".your-shared-class" output.css | wc -lMissing Diagnostic: Are you using a custom Stylus plugin or a specific build wrapper (like Webpack's stylus-loader) that modifies how paths are resolved? This could impact the reliability of path-based deduplication.
Use comments to ask for clarification. Post a solution as an answer.
No question comments on this page.