Si vous utilisez régulièrement Sass dans vos projets en tant que pré-processeur CSS, pour tous les avantages qu'il apporte, vous devez certainement utiliser l'une des deux implémentations : Dart-Sass ou Node-Sass, ce dernier étant en réalité une interface pour LibSass.
Ces outils sont utilisables en ligne de commande ou intégrés aux environnements de développement dans le processus de compilation, par exemple dans weboack, pour Vue, Nuxt, React, etc.
Or, le module node-sass (libSass) est désormais obsolète bien qu'il semble plus performant selon Quick comparison between sass and node-sass par Peter Bengtsson et Node-Sass or Dart-Sass : The CSS Preprocessor Dilemma par Ali Bahraminezhad.
Il y a plusieurs façons de migrer. Même si la documentation vous indique qu'il suffit de remplacer node-sass
par sass
dans package.json
car dart-sass se veut compatible... cela peut être bien plus subtil. Voici quelques explications complémentaires, simplifiées, car évidemment cela dépend de chaque projet et de la version de Node utilisée (12+).
⚠️ Faites une sauvegarde avant toute modification en profondeur. Si votre projet est versionné sur git, c'est encore mieux.
Identifier la situation
Consultez le fichier package.json
à la racine du projet.
S'il comporte "node-sass": "^5.0.0" ou autre numéro de version,
dans les dependencies (dépendances) c'est que vous utilisez bien, pour le moment, node-sass.
Désinstaller/installer
Vous pouvez supprimer manuellement la ligne concernée et le dossier correspondant dans node_modules
, cependant le plus propre sera de passer par les commandes npm :
npm uninstall --save sass
npm install --save sass
À partir de là, vous pouvez déjà tenter de relancer la compilation, et avec un peu de chance vous n'aurez pas besoin de faire autre chose, par exemple npm run dev
ou npm run serve
selon votre framework.
Si des avertissements et erreurs apparaissent, cela signifie que vous utilisez probablement des syntaxes Sass qui doivent être adaptées au nouveau module.
Adapter la syntaxe
Nous prendrons ici un seul exemple car il sera le plus fréquent : la division en CSS. D'autres évolutions peuvent être faites par la suite, optionnelles ou nécessaires si bloquantes.
Dans les fichiers, le caractère /
est utilisé à la fois comme séparateur (dans Grid, rgb, hsl) et comme opérateur de division. C'est une difficulté pour Sass qui doit en comprendre le sens selon le contexte. L'usage de math.div()
pour poser une division devient alors nécessaire.
Exemple :
/* node-sass */
line-height: (19 / 14);
height: (1rem / 16);
/* dart-sass */
line-height: math.div(19, 14);
height: math.div(1rem, 16);
Il existe un script de migration automatique sass-migrator qui peut faire le travail pour vous, mais il ne fonctionnera que sur les fichiers *.scss, pas les fichiers .vue qui associent différentes syntaxes (et il ne semble pas prévu de faire évoluer l'outil pour les supporter).
Vous devez l'installer pour y avoir accès en ligne de commande et spécifier le fichier à analyser comme point d'entrée, par exemple :
npm install -g sass-migrator
sass-migrator division --migrate-deps assets/css/main.scss
L'option --migrate-deps
indique que l'outil passe aussi sur tous les fichiers importés à l'aide de règles @use
, @import
... La transformation menée ici est la division
, il existe aussi module
et namespace
, reportez-vous à la documentation de Migrator.
⚠️ La règle @import est aussi destinée à devenir obsolète.
Sass:math
Il est possible que selon votre organisation de fichiers, la fonction math.div
nécessite l'ajout de l'instruction @use "sass:math";
en début de fichier puisqu'elle dépend du module math. Or, le compilateur pourra vous renvoyer des erreurs si vos fichiers sont assemblés depuis de multiples dossiers ou composants car il ne souhaite cette instruction qu'en début de fichier. La solution est alors d'indiquer à webpack d'injecter cette ligne en préfixe via son loader dédié à Scss, dans la section build
(fichier webpack.config.js, vue.config.js, nuxt.config.js, etc) :
build: {
/* Autres instructions existantes... */
loaders: {
scss: {
additionalData: '@use "sass:math";'
}
}
Et voilà le travail !
Commentaires
Si vous ne pouvez / souhaitez pas utiliser math.div(), vous pouvez aussi remplacer les divisions par des multiplications : 1 / 2 <=> 1 * 0.5
C'est comme cela que certains projets comme Bootstrap ont résolu le problème :
https://github.com/twbs/bootstrap/pull/34571
Depuis quelques années je suis passé de Sass à Stylus et j'adore ce dernier. Stylus avait pour lui d'être natif sous node.js, mais force est de constater qu'il stagne dans son développement, les issues se multiplies, les bugs importants ne sont pas patchés ou prennent des années avant de l'être... Même avec sa dernière grosse mise à jour Stylus rend les dernières fonctionnalités CSS incompatibles avec son runtime dans de nombreux cas (par exemple : min(), max() ou plus récement les requêtes @container). Or, en plus d'être fortement soutenu et développé activement avec des modules prometteurs (ex : colors), l'adage constant de Sass de faire de CSS vanilla du Sass valide est vraiment son point fort.
Je vais donc devoir remigrer... quand je pense aux kilomètre de styles que je vais devoir (re)convertir ! Je vais aussi devoir lire un peu la doc' car il y a pas mal de choses qui ont changé (@import est déprécié au profit de @use par exemple).
Signé : un futur "ex" inconditionnel de Stylus (mais toujours de Pug).