Dart Sass @import deprecation: how should a mixed @import/@use codebase sequence its migration?
0 reputation · 02 Dec 2025, 02:02 UTC
0 reputation · 02 Dec 2025, 02:02 UTC
Dart Sass now emits deprecation warnings for @import (starting around the 1.80 release line) while still compiling it, and the documented replacement is the module system built on @use and @forward. The goal is to migrate a large stylesheet codebase to the module system without breaking builds mid-transition.
The constraint is that partial migration is risky. The Sass documentation warns that loading the same file through both @import and @use can produce duplicate CSS output, and @import ignores the leading-underscore/hyphen privacy convention that module files may rely on. The sass-migrator module migration automates the rewrite but is documented as potentially needing manual fixes for complex import graphs and global dependencies.
Assume current Dart Sass; exact warning text, silencing flags such as quietDeps/silenceDeprecations, and the removal timeline should be verified against the installed version.
@use ... with () before deleting any @import?30275 reputation · 02 Dec 2025, 10:12 UTC
Migrate leaf partials first, entry points last, run sass-migrator per feature folder rather than repo-wide, and convert global configuration to @use ... with () before deleting any @import line. The governing rule throughout: no file should ever be reachable through both @import and @use at the same time, because that is what produces duplicated CSS output.
The duplicate-CSS hazard exists only while a file sits on both sides of the boundary. Leaf partials (files nothing else imports) have no downstream dependents, so converting them cannot strand a consumer. Work inward from the leaves toward the entry points, and convert each entry point only after everything it pulls in is already on the module system. Entry points go last for a second reason: they define the public surface of the stylesheet, so changing them early breaks every consumer mid-transition.
A practical ordering:
@import plus a dependency listing is enough to rank files by how many consumers they have).@use/@forward, keeping their old @import names available via @forward shims where consumers still use @import.@import lines in one pass.Per folder is safer for a large codebase. A single repo-wide sass-migrator run surfaces every duplicate-CSS conflict, privacy-convention break, and circular dependency at once, and the tool's own documentation notes its output needs manual fixes on complex graphs. Migrating one feature folder at a time gives you an isolated compile you can diff, and keeps the manual-fix surface small. The trade-off is coordination: folders that share global variables must agree on the configuration module before either one flips, or you get inconsistent variable exposure across the boundary.
Variables that were previously set by import order (a later import overriding an earlier one) have no equivalent in the module system — modules load once, with explicit configuration. The safe sequence:
!default.@use 'config' with ($brand-color: #0055aa); — the with () clause must appear on the first @use of that module.@use should the old @import-based variable files be removed.Also remember that @import ignores the leading-underscore privacy convention. If any partial relied on _private.scss being hidden, verify after migration that those members are not newly exposed through a @forward.
After each folder migrates, compile the full codebase and check three things:
sass --quiet src/:dist/ # no @import deprecation warnings remain
sass --trace src/:dist/ # confirm no file is loaded twiceThen diff the compiled CSS against a pre-migration baseline for that folder — duplicate rules show up immediately as size growth or specificity changes. Exact flag names (quietDeps, silenceDeprecations) and the deprecation/removal timeline vary by Dart Sass release, so confirm them against your installed version with sass --version and sass --help rather than relying on this text. The sequencing advice above is stable across versions; the warning-silencing mechanics are not.
This assumes current Dart Sass in the 1.80+ line where @import still compiles with warnings. If your build pins an older Sass or uses a wrapper (e.g., a bundler plugin) with its own Sass version, verify which binary actually runs. If your import graph has circular dependencies, expect manual restructuring that no sequencing strategy avoids — that is the one detail that would change the recommendation toward extracting shared modules first.
Use comments to ask for clarification. Post a solution as an answer.
No question comments on this page.