Cómo hacer procesamiento de CSS, para ejecutar los preprocesadores necesarios para convertir nuestro código CSS, con Webpack. Usaremos Sass.
Una de las tareas típicas del desarrollo frontend actual es el procesamiento de CSS, para ejecutar los correspondientes preprocesadores y producir un código de hojas de estilo compatible con los navegadores y optimizado para una rápida descarga.
Esta tarea de procesamiento del código CSS permite pasar nuestro código escrito en Sass, Less, etc. en código CSS estándar, compatible con los navegadores. Para realizar esta acción los distintos preprocesadores tienen herramientas específicas, pero nosotros queremos usar Webpack, básicamente porque así podremos tener un mismo flujo de trabajo para todos los lenguajes o componentes del proyecto frontend.
Este paso requiere la transformación del código CSS, para lo que tenemos que usar un loader distinto de los que hemos visto hasta este momento en el Manual de Webpack. En este artículo explicaremos los pasos necesarios para configurar la herramienta y poder hacer el paso del procesamiento del código Sass en código CSS estándar.
Incluir el código CSS en nuestro entry point
Recordemos que en Webpack se trabaja con un punto de entrada, que es un archivo Javascript. Webpack analiza el código de este archivo JS para producir los correspondientes bundles de código. En el caso que nos ocupa, el procesamiento del CSS, Webpack necesita encontrar el código CSS a partir del punto de entrada. Por tanto, aunque parezca un poco raro, dentro de nuestro Javascript tendremos que hacer el import del código CSS.
/* css */
import './css/estilos.css';
Como dentro de un archivo Javascript no podemos incluir código CSS, si ejecutas el proceso de Webpack en estos momentos apreciarás un error, producido por la sintaxis del archivo estilos.css. Es normal que esto ocurra, pues en este archivo colocaremos código CSS, que el intérprete de Javascript no acepta como válido. Pero no te preocupes, porque realmente nos faltaba un paso muy importante para dejarlo todo listo.
Extraer el código CSS del bundle Javascript
Ahora vamos a sacar todo el CSS que se ha importado dentro del Javascript, para enviarlo a un archivo de CSS común. Para esta tarea necesitamos un par de paquetes.
Plugin mini-css-extract-plugin
Para realizar esta tarea tenemos que usar un plugin llamado mini-css-extract-plugin, que realizará la extracción de todo el código CSS que tengamos dentro de Javascript. Este plugin creará el archivo .css para llevar a producción.
El primer paso será instalar el plugin:
npm install -D mini-css-extract-plugin
Loader css-loader
Recuerda además que las transformaciones del código en Webpack se realizan mediante loaders. Los Loaders permiten procesar y transformar el código fuente de tu aplicación, según se importa en el archivo Javascript mediante la sentencia import. Puedes pensar en los loaders como una especie de tareas a realizar por Webpack. En el caso del css-loader sirve para poder importar CSS como si fueran módulos Javascript.
Para disponer de este loader tenemos que instalarlo en nuestro proyecto.
npm install -D css-loader
Configurar Webpack para la extracción del CSS
Ahora veamos la configuración que tenemos que realizar de Webpack, con css-loader y mini-css-extract-plugin, para realizar las siguientes acciones:
- Retirada de todo código CSS, para que no figure dentro del código Javascript
- Creación de un archivo .css con el código CSS que se ha importado
- Inyección del código CSS dentro del código HTML, con la etiqueta LINK, dirigida hacia el archivo .css creado.
Esta configuración se realiza en dos pasos:
- Instanciación del plugin mini-css-extract-plugin
- Definición de las reglas de transformación del código para archivos CSS
Además, para el paso de la inyección del código CSS dentro del HTML generado tienes que usar html-webpack-plugin, como se explicó en el artículo dedicado a HtmlWebpackPlugin.
Puedes ver a continuación el código de un ejemplo básico de uso de mini-css-extract-plugin y css-loader.
const HtmlWebpackPlugin = require('html-webpack-plugin');
const MiniCSSExtractPlugin = require('mini-css-extract-plugin');
module.exports = {
plugins: [
new HtmlWebpackPlugin({
filename: 'index.html',
template: 'src/index.html',
hash: true
}),
new MiniCSSExtractPlugin()
],
module: {
rules: [
{
test: /\.css$/,
loader: [
MiniCSSExtractPlugin.loader,
"css-loader"
]
}
]
}
}
Los puntos importantes que debes fijarte en el anterior código son:
- El require de 'mini-css-extract-plugin', necesario para poder usar el plugin dentro del archivo de configuración Webpack.
- En el array de plugins, la instanciación de MiniCSSExtractPlugin.
- La regla para hacer las correspondientes transformaciones sobre los archivos CSS. A cada CSS importado (archivos con extensión ".css"), se le aplicarán un par de transformaciones por medio de los loaders: MiniCSSExtractPlugin.loader y "css-loader". El orden de aparición de estos loaders es importante!
Como consecuencia de la ejecución de Webpack se generará un archivo CSS llamado "main.css", que contendrá todo el CSS importado. En este caso se usará "main.css" como nombre de archivo, ya que no hemos configurado ningún otro nombre de archivo. Pero podríamos hacer la personalización del nombre de archivo CSS resultante por medio del objeto de configuración pasado al instanciar el plugin.
new MiniCSSExtractPlugin({
filename: "estilos.css",
})
Preprocesamiento de Sass con Webpack
Una vez que tenemos montado todo el sistema para el procesamiento del CSS, adaptarlo para trabajar también con Sass, u otro preprocesador de nuestra preferencia, será muy sencillo.
Básicamente necesitas instalar dos paquetes nuevos en tu proyecto. Por un lado node-sass que es quien tiene el código para poder preprocesar Sass desde el lenguaje NodeJS. Por otro lado sass-loader que sirve para que desde Webpack puedas hacer las transformaciones pertinentes sobre tu código CSS.
npm i -D node-sass sass-loader
Luego nos toca configurar el correspondiente loader. Algo que es muy sencillo, pues solamente lo tenemos que agregar al array de loaders que tenemos en la regla de transformación de nuestro CSS.
rules: [
{
test: /\.scss$/,
loader: [
MiniCSSExtractPlugin.loader,
"css-loader",
'sass-loader'
]
}
]
Solo un detalle que no debe pasar desapercibido: fíjate que la expresión regular de "test" ha cambiado, ya que en Sass se suelen usar extensiones de archivos "scss" en lugar de "css". Es por ello que ahora debemos extraer el CSS que viene de archivos .scss. Obviamente, si sigues usando extensión .css, aunque escribas en Sasss (algunos desarrolladores lo hacen así), ese "test" tendría que tener la expresión regular del ejemplo anterior.
Eso es todo! ahora al ejecutarse Webpack se generará el Código CSS de nuestra aplicación y se meterá en un archivo .css, separado del código Javascript. Además el código Sass se preprocesará, de modo que tendremos únicamente código CSS compatible con todos los navegadores.
Solo ten en cuenta de nuevo que los loaders usados para esta regla tienen que ejecutarse en el orden correcto, definido por la posición dentro de la declaración del array. Por ejemplo, si intentas colocar el "sass-loader" antes del "css-loader" apreciarás que Webpack te responde con un error.
Resumen del entorno para CSS y preprocesamiento de Sass
Para que sirva de guía para crear tu entorno de desarrollo Webpack, capaz de procesar los CSS y hacer el preprocesamiento de Sass, vamos a hacer un relatorio de los archivos que tenemos. Comenzamos mostrando el árbol de archivos y carpetas involucrados.
Nuestro package.json, una vez instaladas las dependencias y creados los scripts para compilación de Webpack, lucirá de una manera parecida a esta:
{
"name": "frontend-css-y-sass",
"version": "1.0.0",
"description": "",
"main": "index.js",
"scripts": {
"build": "webpack --mode production",
"builddev": "webpack --mode development"
},
"author": "",
"license": "ISC",
"devDependencies": {
"css-loader": "^2.1.1",
"html-webpack-plugin": "^3.2.0",
"mini-css-extract-plugin": "^0.6.0",
"node-sass": "^4.12.0",
"sass-loader": "^7.1.0",
"webpack": "^4.32.1",
"webpack-cli": "^3.3.2"
}
}
Ahora puedes ver el archivo webpack.config.js de ejemplo. Ten en cuenta que algunas cosas relacionadas con este archivo de configuración ya se vienen explicando, o se van a explicar, en el Manual de Webpack. Especialmente el artículo dedicado al webpack.config.js y el dedicado a Inyectar bundles Javascript / CSS
const path = require('path');
const HtmlWebpackPlugin = require('html-webpack-plugin');
const MiniCSSExtractPlugin = require('mini-css-extract-plugin');
module.exports = {
plugins: [
new HtmlWebpackPlugin({
filename: 'index.html',
template: 'src/index.html',
hash: true
}),
new MiniCSSExtractPlugin({
filename: "./css/estilos.css",
})
],
module: {
rules: [
{
test: /\.scss$/,
loader: [
MiniCSSExtractPlugin.loader,
"css-loader",
"sass-loader"
]
}
]
}
}
Ahora, dentro de la carpeta "src" tenemos los archivos fuente de nuestro proyecto. Comenzamos a verlos atendiendo al archivo que se usa como punto de entrada, "src/index.js", que tendrá un código como este:
console.log('Arrancada la aplicación compilando CSS y SaSS');
/* CSS */
import './css/estilos.scss';
A continuación podemos ver el archivo de CSS, "css/estilos.scss", en el que podemos colocar perfectamente instrucciones de Sass.
body {
background-color: aquamarine;
}
.Panel {
background-color: #fff;
padding: 25px;
&-destacado {
background-color: red;
}
}
Por último vamos a ver el archivo de código HTML, "src/index.html", que sería el template del que tiraría Webpack para colocar como documento raíz de publicación.
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Template principal para el sitio web</title>
</head>
<body>
<h1>Mi sitio web</h1>
<div class="Panel">
Esto es un panel
</div>
<div class="Panel Panel-destacado">
Esto es un panel destacado
</div>
</body>
</html>
Del archivo anterior se tiene que destacar el hecho de no contener ninguna referencia al index.js del proyecto, ni a los archivos de estilos CSS. Las correspondientes etiquetas para enlazar el Javascript y el CSS procesado (SCRIPT para el Javascript y LINK para los CSS) las va a inyectar Webpack cuando lancemos los scripts correspondientes de compilación de proyecto, como "npm run build".
Conclusión
Hemos aprendido a incorporar CSS en nuestras aplicaciones de una nueva manera, importando directamente desde Javascript. Es algo antinatural, pero gracias a Webpack cada cosa se pondrá en su sitio al llevar los archivos a producción.
Hemos conocido los paquetes necesarios para producir las transformaciones necesarias en el código CSS, incluyendo la posibilidad de escribir código Sass y preprocesarlo para obtener el código CSS estándar, compatible con los navegadores.
Miguel Angel Alvarez
Fundador de DesarrolloWeb.com y la plataforma de formación online EscuelaIT. Com...