Dart Sass @use module compatibility with legacy @import consumers
0 reputation · 12 Jan 2023, 20:32 UTC
0 reputation · 12 Jan 2023, 20:32 UTC
A Sass library currently exposes its API through a single entry point using @import. The goal is to migrate its internal structure to the Dart Sass module system introduced in 1.23.0 with @use and @forward to gain namespacing and single evaluation, while ensuring downstream projects that still consume the library via @import do not break.
The uncertainty is whether a library can safely use @use internally while still presenting a legacy @import-compatible surface, or whether the presence of @use in any file forces all consumers to migrate to Dart Sass and abandon @import entirely. It is also unclear how private members prefixed with _ or - behave when a module is consumed through a legacy @import path versus a modern @use path.
Can a Dart Sass module system library maintain backward compatibility with @import consumers? What is the supported boundary for exposing @forward members to legacy importers? Is there a documented compatibility strategy for libraries that must support both node-sass and Dart Sass during a transition?
33275 reputation · 13 Jan 2023, 02:42 UTC
Yes – a library that adopts the Dart‑Sass module system can still be consumed by legacy @import consumers, but only if the public entry point contains no @use statements. The internal modules may use @use and @forward, and a thin wrapper file forwards the public API to the legacy consumers.
@use cannot be @import-ed; Sass will throw an error.@forward can be @import-ed, but @forward is not understood by LibSass (node‑sass)._ or -) are exported by @forward unless you explicitly hide them.@use statements must be confined to modules that are never imported directly.@use and @forward.src/_wrapper.scss, that contains only @forward statements and no @use:
@forward "core";
@forward "components";
Optionally, rename or hide private members:
@forward "core" as core hide $internal-color;
@import "_wrapper";.@import:
// legacy.scss – node‑sass compatible
@import "core";
@import "components";
_wrapper.scss for Dart‑Sass and legacy.scss for node‑sass.legacy.scss and keep only the wrapper.@forward membersThe wrapper should only forward the API you want to expose. Use the :as and hide modifiers to keep private helpers out of the public surface.
Most libraries ship two entry points during the transition: a Dart‑Sass‑only wrapper and a node‑sass‑compatible legacy file. This keeps the public API stable for both consumers while the internal codebase moves to the module system.
Do you currently ship a single public entry point, or do you already have separate legacy files? Knowing that will help refine the wrapper strategy or confirm that a dual‑entry approach is necessary.
Use comments to ask for clarification. Post a solution as an answer.
No question comments on this page.