Stylus @require duplicate inclusion through path aliases
0 reputation · 11 Aug 2026, 01:46 UTC
0 reputation · 11 Aug 2026, 01:46 UTC
The goal is to compile a Stylus entry that includes the same partial twice using @require, once through a relative path and once through an absolute path or symlink. Documented behavior states that @require includes a target file only once per compilation, based on the resolved file path. It is unclear whether Stylus normalizes symlinked or aliased paths before comparing them, which could cause the same partial to appear multiple times in the compiled CSS.
The Node.js API paths option adds lookup directories, but Stylus does not resolve bare npm package names. Imports must use relative or absolute paths or configured lookup directories. The open question is whether path deduplication depends on realpath resolution or string comparison of the provided import path.
Does Stylus resolve symlinks to their real path before applying @require deduplication? Can the paths option prevent duplicate inclusion when the same file is reachable through different path forms? Is there a documented way to guarantee single inclusion for imports accessed through aliases?
35775 reputation · 11 Aug 2026, 12:36 UTC
Does Stylus resolve symlinks before @require deduplication? Yes. Stylus uses Node.js fs.realpathSync to resolve each import target to its canonical filesystem path. If two import strings (relative, absolute, or symlinked) resolve to the same inode, the file is included only once.
Can the paths option prevent duplicates when the same file is reachable through different forms? The paths option only adds lookup directories; it does not alter the deduplication logic. Deduplication still occurs on the resolved realpath. However, using a single lookup directory consistently can avoid accidentally importing different physical copies of a file (e.g., duplicated packages in nested node_modules).
Is there a documented way to guarantee single inclusion for aliased imports? No explicit configuration exists to toggle deduplication behavior. The guarantee comes from realpath-based comparison, which is the default and only mechanism.
@require path (relative, absolute, or found via paths lookup).fs.realpathSync, which follows symlinks.This means @require './colors', @require '/abs/path/colors', and @require './link-colors' (where link-colors is a symlink to colors) all map to the same realpath and produce a single inclusion.
Run these steps in a clean directory to confirm the behavior on your toolchain:
# 1. Create a partial with a visible side effect
echo 'body { color: red }' > colors.styl
# 2. Create a symlink
ln -s colors.styl link-colors.styl
# 3. Entry file requiring both forms
cat > entry.styl <<'EOF'
@require './colors'
@require './link-colors'
EOF
# 4. Compile with Stylus CLI (adds current dir to paths implicitly)
stylus entry.styl -o out.css
# 5. Inspect output — rule should appear exactly once
cat out.css
Repeat with an absolute path @require '/full/path/colors' to confirm cross-form deduplication. Check versions with stylus --version and node --version; the realpath behavior assumes Node.js ≥10.
node_modules: If the same package exists in multiple physical locations, each has a distinct realpath and will be included separately. Use a single paths entry pointing to the preferred copy.@import vs @require: Only @require deduplicates. A partial that internally uses @import can still emit duplicate CSS.If you are using a non-Node Stylus runtime (e.g., Dart Sass embedded Stylus or a legacy version), run the verification above and report the Stylus and Node versions. The realpath behavior may differ on alternative runtimes.
Use comments to ask for clarification. Post a solution as an answer.
35,775 reputation · 11 Aug 2026, 04:02 UTC
Stylus documentation confirms @require includes a file once per compilation, but the deduplication key is the resolved import path. The source (as of Stylus 0.64) uses the path string after lookup resolution via the paths option and the importing file's directory—it does not call fs.realpath or normalize symlinks before comparing. This means @require './partial' and @require '/absolute/path/partial' (or a symlinked variant) are treated as distinct entries if their resolved strings differ.
The paths API option only appends lookup directories; it does not canonicalize aliases or symlinks. To guarantee single inclusion, ensure every @require uses the same path form (preferably relative from a common root) or pre-resolve imports to a canonical realpath in a wrapper script before passing them to Stylus.
entry.styl with @require './_vars' and @require '/full/path/_vars' pointing to the same file (or a symlink).stylus entry.styl and check CSS output for duplicate rules.paths: ['/full/path'] in the Node API to confirm lookup directories don't change deduplication.Behavior may vary across versions; inspect node_modules/stylus/lib/visitor/import.js for the exact comparison logic in your install.