Cómo compilar tu código Sass en aplicaciones web usando Webpack 5. Explicaciones paso a paso para poder extraer el código SCSS y convertirlo a CSS para entornos de desarrollo y producción.
En un artículo anterior aprendimos a usar archivos CSS dentro del flujo de trabajo con Webpack. En resumen vimos que Webpack es capaz de procesar el CSS de un sitio o aplicación web si lo configuramos con el correspondiente loader.
Sin embargo, en la mayoría de los casos no queremos solamente procesar el CSS, sino compilar algún tipo de lenguaje basado en CSS, como Sass o SCSS, incluso usar herramientas de optimización o transformación como PostCSS. En este artículo vamos a explorar la compilación del código del preprocesador Sass a CSS, usando por supuesto Webpack.
Vamos a resumir aquí los comandos y complementos que necesitas, sin entrar mucho en el detalle del paso a paso y de por qué se hacen las cosas así en Webpack, ya que eso lo puedes ver en el Manual de Webpack.
En un artículo anterior explicamos cómo compilar tu CSS y Sass con Webpack 4. Los pasos son muy parecidos, por lo que es una buena referencia si quieres guías generales te sirven también aquí.
1.- Comenzamos con el setup para procesar el código CSS
Nuestra guía comienza por todos los pasos que ya hemos explicado anteriormente para CSS común, ya que el proceso es prácticamente el mismo, simplemente tendremos que cambiar el loader.
Así que comienza por configurar Webpack para CSS con esta guía.
2.- Instalar los packages para Sass
Ahora, para compilar tu código Sass con Webpack 5, usarás estos packages: sass-loader
y sass
. Los puedes instalar usando el siguiente comando.
npm install sass-loader sass --save-dev
3.- Añadir el archivo scss a los imports en el Javascript
En el archivo de Javascript que hace el arranque del proyecto necesitas importar el código CSS de tu aplicación, que deseas compilar con Sass, típicamente un archivo .scss
.
import './app.scss';
Ya lo mencionamos en el artículo anterior, pero volvemos a repetir que ese import lo tienes que hacer en el código Javascript. En realidad puede ser un poco antinatural, pero Webpack funciona así. Gracias a los loader de Webpack se consigue luego separar el JS del CSS, o SCSS en este caso.
Dado el import
anterior, se entiende que app.scss
es el archivo raíz desde el cual se importan todos los demás archivos scss de tu proyecto.
4.- Usar este código en tu archivo webpack.config.js
Te vamos a dar varias alternativas de código para que puedas tener diversas plantillas.
Compilar Sass en modo desarrollo
Si tienes que compilar Sass, archivos en formato scss, en modo desarrollo, puedes usar este webpack.config.js
.
const path = require('path');
module.exports = {
entry: './src/index.js',
output: {
filename: 'main.js',
path: path.resolve(__dirname, 'public'),
},
module: {
rules: [
{
test: /\.s[ac]ss$/i,
use: [
"style-loader",
"css-loader",
"sass-loader",
]
}
]
},
};
En este caso tu CSS quedaría embebido en tu propio archivo de Javascript, que puede estar bien para desarrollo, pero para producción no es aconsejable, por lo que generalmente querrás realizar la extracción del CSS con 'mini-css-extract-plugin
'.
Compilar Sass en modo producción
Si quieres compilar Sass con Webpack 5 y además extraer el CSS (para que no quede mezclado con el Javascript), puedes usar este otro archivo de webpack.config.js
.
Este paso no solo es aconsejable para producción, sino que resulta fundamental.
const path = require('path');
const MiniCssExtractPlugin = require('mini-css-extract-plugin');
module.exports = {
entry: './src/index.js',
output: {
filename: 'main.js',
path: path.resolve(__dirname, 'public'),
},
module: {
rules: [
{
test: /\.s[ac]ss$/i,
use: [
MiniCssExtractPlugin.loader,
"css-loader",
"sass-loader",
]
}
]
},
plugins: [
new MiniCssExtractPlugin()
]
};
5.- Crear scripts en el package.json
Lo normal es que tengas scripts como estos en tu package.json:
"scripts": {
"build": "webpack --mode=production",
"dev": "webpack --mode=development"
},
Uno compila para producción y otro para desarrollo.
Solo ten en cuenta que estos scripts invocarían siempre al archivo webpack.config.js
. Tú tendrías que haber implementado ese archivo con alguna de las alternativas de código que hemos visto antes.
distinguir entre desarrollo y producción mediante variables de entorno
Para distinguir entre desarrollo y producción, lo que le ayudaría a decidir a Webpack si tiene o no que extraer el CSS, tendrías varias posibilidades. Una de ellas sería usar un webpack.config.js
distinto para cada entorno. Esto es una buena solución si las compilaciones son muy distintas en desarrollo y producción, pero te obligaría a mantener dos archivos de configuración de Webpack, lo que puede darte algo más de trabajo.
Otra alternativa sería reconocer mediante código Javascript (NodeJS) dentro de webpack.config.js
si estás ejecutando Webpack para desarrollo o para producción. Esto lo podemos conseguir por medio de variables de entorno en NodeJS.
Dada esta situación podríamos usar el siguiente código para webpack.config.js
, en el que se hace un condicional para ver si se desea extraer el CSS, o no, dependiendo de una variable de entorno.
const path = require('path');
const MiniCssExtractPlugin = require('mini-css-extract-plugin');
const devMode = process.env.NODE_ENV !== "production";
module.exports = {
entry: './src/index.js',
output: {
filename: 'main.js',
path: path.resolve(__dirname, 'public'),
},
module: {
rules: [
{
test: /\.s[ac]ss$/i,
use: [
devMode ? "style-loader" : MiniCssExtractPlugin.loader,
"css-loader",
"sass-loader",
]
}
]
},
plugins: [
new MiniCssExtractPlugin()
]
};
Para conseguir generar las correspondientes variables de entorno, tus scripts de npm en el package.json
deberían cambiar algo, mediante la incorporación de NODE_ENV
, indicando el valor adecuado de la variable de entorno correspondiente para cada caso.
"scripts": {
"build": "NODE_ENV=production webpack --mode=production",
"dev": "NODE_ENV=development webpack --mode=development"
},
Este formato de invocación de scripts con variables de entorno funciona en MacOS y debería de funcionar en Linux exactamente igual. Según tengo entendido, en Windows podría tener otra sintaxis. Si no te va, prueba a usar ese otro formato:
"build": "set NODE_ENV=production && webpack --mode=production"
Esto último no lo he probado porque no tengo un sistema Windows a mano ahora mismo. Pero otra alternativa que seguro que te funciona en Windows es usar WSL2, que te permite trabajar en Windows con una instalación de una máquina virtual Linux, lo que te ofrece una experiencia mucho mejor para desarrolladores.
Miguel Angel Alvarez
Fundador de DesarrolloWeb.com y la plataforma de formación online EscuelaIT. Com...