## Sass: Del @import legado a arquitectura modular moderna con @use y @forward
En el mundo del desarrollo frontend, donde los proyectos crecen en complejidad y las bases de código se expanden, la gestión eficiente de estilos es crucial. Sass, uno de los preprocesadores de CSS más populares, ha experimentado cambios significativos para mejorar la modularidad y mantenibilidad del código. Un paso clave en esta evolución fue abandonar la directiva obsoleta @import en favor de las potentes y flexibles @use y @forward.
Durante mucho tiempo, @import fue el único método para incluir archivos Sass, pero traía serios inconvenientes: contaminación del espacio de nombres global, alto riesgo de conflictos y duplicación de código. Con la inminente salida de Dart Sass 3.0.0, @import ha sido oficialmente deprecado y será eliminado por completo, haciendo imprescindible la adopción del nuevo sistema modular para todo desarrollador moderno.
La directiva @use: Aislamiento y espacios de nombres
@use es un elemento fundamental del nuevo sistema modular de Sass. Carga un archivo Sass (módulo) y pone a disposición su contenido (variables, mixins, funciones) en el archivo actual, pero los aísla en su propio espacio de nombres. Esta es una diferencia clave con @import, que evita conflictos globales y hace explícitas las dependencias.
Uso básico:
@use 'path/to/file';
Por defecto, el nombre del espacio de nombres se deriva de la última parte de la ruta del archivo, sin guiones bajos ni extensiones. Por ejemplo, al usar @use '../helpers/colors';, las variables y funciones de _colors.scss se accederán con el prefijo colors.:
// helpers/_colors.scss
$primary: blue;
$secondary: gray;
// components/_button.scss
@use '../helpers/colors';
.button {
color: colors.$primary; // Accedido vía el espacio de nombres "colors"
background-color: colors.$secondary;
}
Cambiar el espacio de nombres con as:
Por comodidad o claridad, puedes asignar un nombre personalizado a un módulo con la palabra clave as:
@use 'helpers/colors' as myColors;
.button {
color: myColors.$primary; // Accedido vía "myColors"
}
Al nombrar espacios de nombres, debes seguir las reglas de identificadores de Sass:
- Permitidos: letras (a-z, A-Z), dígitos (0-9, pero no al inicio),
camelCase,PascalCase. - No permitidos: guiones (
-), espacios, caracteres especiales, inicio con dígito.
Módulos integrados de Sass
Sass ofrece un conjunto de módulos integrados para tareas comunes como operaciones matemáticas, trabajo con listas, mapas, colores y cadenas. Se importan con el prefijo sass::
@use 'sass:math';
@use 'sass:list';
@use 'sass:map';
@use 'sass:color';
@use 'sass:string';
Ejemplos de uso de funciones de módulos integrados:
$width: math.div(100%, 3); // División
$len: list.length((10px, 20px, 30px)); // Longitud de lista
$color: color.adjust(#336699, $lightness: 20%); // Ajuste de color
$index: string.index('hello world', 'world'); // Búsqueda de subcadena
Es crucial recordar que los módulos integrados, como los regulares, deben importarse explícitamente en cada archivo donde se usen sus funciones. No se heredan a través de otras importaciones.
Organización del código y acceso a módulos
El sistema modular de Sass promueve un enfoque donde cada archivo SCSS declara explícitamente sus dependencias al inicio. Esto garantiza transparencia y simplifica el refactoring. Los mixins y funciones definidos en archivos personalizados también están disponibles a través de espacios de nombres.
Ejemplo de definición de un mixin:
// helpers/_mixins.scss
@mixin flex-center {
display: flex;
align-items: center;
justify-content: center;
}
Y su uso:
// components/_card.scss
@use '../helpers/mixins';
.card {
@include mixins.flex-center;
}
Estructura de carpetas recomendada:
Un proyecto Sass bien estructurado podría verse así:
scss/
helpers/
_colors.scss
_variables.scss
_mixins.scss
components/
_button.scss
_card.scss
pages/
_about-page.scss
template.scss // Archivo principal de compilación
Ejemplo de un archivo de componente usando múltiples módulos:
// components/_button.scss
@use '../helpers/colors' as myColors;
@use '../helpers/variables';
@use '../helpers/mixins';
.button {
background-color: myColors.$primary;
padding: variables.$spacing-md;
@include mixins.border-radius;
}
Ventajas del enfoque modular con espacios de nombres:
- Claridad: Es evidente de inmediato de qué módulo proviene una variable o mixin, mejorando la legibilidad del código.
- Sin conflictos: Los espacios de nombres aislados aseguran que variables y mixins con nombres iguales en módulos distintos no choquen.
- Refactoring más fácil: Cambios en un módulo no afectan a otros, siempre que se mantenga su API, simplificando la escalabilidad y modificación.
- Soporte IDE: Los entornos de desarrollo modernos funcionan mejor con espacios de nombres explícitos, ofreciendo autocompletado preciso.
- Escalabilidad: La base de código sigue siendo comprensible y manejable incluso en proyectos muy grandes.
Configuración de módulos con @use ... with()
La directiva @use ... with() ofrece un mecanismo potente para configurar módulos al importarlos. Permite sobrescribir variables marcadas con !default pasando nuevos valores directamente al importar el módulo.
Cómo funciona !default:
Una variable declarada con !default usa su valor solo si no se ha establecido previamente. Si el valor ya está definido (por ejemplo, en otro archivo o vía @use ... with()), se ignora !default.
// helpers/_theme.scss
$bg-color: #ffffff !default; // Valor por defecto
$text-color: #333333 !default; // Puede sobrescribirse
Sobrescribir valores con with():
Puedes pasar nuevos valores para variables !default dentro de los paréntesis with() al importar un módulo:
// pages/dark-theme.scss
@use '../helpers/theme' with (
$bg-color: #1a1a1a,
$text-color: #f0f0f0
);
body {
background: theme.$bg-color; // Será #1a1a1a
color: theme.$text-color; // Será #f0f0f0
}
Notas importantes sobre with():
@use ... with()solo funciona en la primera importación de un módulo específico en un archivo dado. Intentos posteriores de importar el mismo módulo con valoreswith()distintos se ignoran.- Muchas librerías Sass de terceros usan
!defaultpara sus configuraciones, permitiendo personalizar su comportamiento fácilmente víawith().
La directiva @forward: Creando una API pública
@forward es una directiva que permite reexportar el contenido de uno o más módulos, poniéndolos disponibles para otros archivos que importen un archivo intermediario. Se usa para crear un único punto de entrada (API pública) para un conjunto de módulos, sin hacer accesible su contenido directamente en el archivo donde se usa @forward.
Ejemplo de uso de _core.scss como único punto de entrada:
// _core.scss
@forward 'helpers/colors';
@forward 'helpers/variables';
@forward 'base/fonts';
@forward 'helpers/mixins';
Ahora, en lugar de importar cada archivo por separado, puedes simplemente importar _core.scss:
// pages/about-page.scss
@use '../core.scss';
.button {
color: core.$blue; // Variable de helpers/colors
border-radius: core.$border-radius-medium; // Variable de helpers/variables
@include core.flex-center; // Mixin de helpers/mixins
}
Pros y contras del enfoque _core.scss:
- Pro: Simplifica las importaciones en archivos consumidores, creando una API clara para todo el proyecto.
- Contra: Todos los elementos reenviados usan el espacio de nombres
core(o el que especifiques), lo que puede dificultar saber el archivo original de una variable o mixin sin inspeccionar_core.scss.
Uso interno de módulos reenviados:
Si el archivo _core.scss necesita usar variables o mixins de los módulos reenviados, debe importarlos explícitamente con @use:
// _core.scss
@forward 'helpers/colors'; // Reenvío hacia fuera
@use 'helpers/colors' as c; // Para uso interno en _core.scss
body {
background: c.$bg-color; // Funciona gracias a @use
}
Capacidades avanzadas de @forward:
- Reenvío selectivo (
show/hide): Permite especificar explícitamente qué elementos de un módulo reenviar.
```scss
@forward 'colors' show $primary, $secondary; // Reenvía solo estas variables
@forward 'mixins' hide private-mixin; // Reenvía todo excepto private-mixin
```
- Configuración vía
with()al reenviar: Similar a@use ... with(), puedes sobrescribir variables!defaulten el módulo reenviado.
```scss
// helpers/_theme.scss
$bg-color: #fff !default;
// _index.scss (archivo que reenviará _theme.scss)
@forward 'theme' with (
$bg-color: #f0f0f0
);
```
Gestión de dependencias de módulos
En el sistema modular de Sass, cada archivo debe declarar explícitamente sus dependencias. Esto aplica incluso cuando uno de tus módulos (ej. _variables.scss) usa variables de otro módulo (_colors.scss). Aunque _variables.scss y _colors.scss se reenvíen ambos a través de _core.scss, _variables.scss debe importar explícitamente _colors.scss si usa su contenido.
// _variables.scss
@use 'colors'; // Dependencia explícita en _colors.scss
$button-bg: colors.$primary;
Por qué es importante:
- Claridad: Es evidente de inmediato de qué módulos depende cada archivo, simplificando la comprensión de la estructura.
- Fiabilidad: Al mover o reorganizar archivos, las dependencias permanecen intactas y comprensibles.
- Soporte IDE: Herramientas de análisis estático y autocompletado funcionan con mayor precisión.
- Refactoring: Es fácil rastrear dónde se usan módulos y variables específicas.
Conclusiones clave
- @use y @forward reemplazan el obsoleto
@import, ofreciendo verdadera modularidad en Sass. - Espacios de nombres evitan conflictos y hacen explícitas las dependencias, mejorando la escalabilidad.
- @use ... with() permite configurar módulos de forma flexible sobrescribiendo variables
!default. - @forward se usa para crear puntos de entrada únicos (APIs públicas), simplificando la gestión de muchos módulos.
- Declarar dependencias explícitamente en cada archivo es clave para la mantenibilidad y predictibilidad del código Sass.
— Editorial Team
Aún no hay comentarios.