< 9 mins read

Compilando Sass con Webpack

Mimotic
Full-stack Developer

Si estás buscando las instrucciones sobre cómo poder automatizar la compilación de sus ficheros SASS (o SCSS) automáticamente y al vuelo en CSS mientras trabajas en ellos, estás en el sitio adecuado.

En el proceso de configuración se tarda, literalmente, 10 minutos. Puede parecer un poco complejo de primeras, pero vamos a ir paso por paso para que no haya ninguna duda.

Para realizar esta tarea, vamos a utilizar webpack. Si ya lo estás utilizando, puedes saltar al paso 3 directamente.

Webpack es un empaquetador de módulos de javascript que sirve para muchas cosas. Por resumirlo, se encarga de automatizar una serie de tareas a la hora de desarrollar una aplicación cualquiera, importando librerías y organizando los archivos al vuelo y en segundo plano mientras tú trabajas en tu código. Lo que vamos a hacer en este pequeño tutorial es indicarle a webpack que cada vez que haya un cambio en nuestro SASS, lo compile automáticamente en un fichero CSS.

Como vamos a hacerlo por pasos, trabajaremos complicando un poco el proceso en cada apartado. Empezaremos por hacer funcionar webpack, luego trataremos de hacer que webpack pueda trabajar e interpretar css, después añadiremos compatibilidad con sass, y por último haremos que todo este proceso se realice en un segundo plano mientras trabajamos.

Paso 0 – Requerimientos

Para realizar la instalación y ejecutar webpack, vamos a utilizar node package modules. Si no lo tienes instalado, viene por defecto con NodeJS. Haz la prueba, y en la consola o terminal que suelas utilizar, escribe

npm -v

Si te aparece un número de versión, quiere decir que está todo correcto y que podemos continuar. En el momento de escribir este artículo, estoy utilizando la versión 6.14.4

Si no sabes qué es una consola, o no sabes utilizarla, te recomiendo, como forma sencilla, que utilices Visual Studio Code, que integra automáticamente una terminal que apunta a la raíz del proyecto que tengas abierto.

Paso 0,5 – Entendiendo cómo funciona webpack

Webpack trabaja con javascript, y todas las órdenes que le daremos serán en dicho lenguaje. No te preocupes si no lo manejas con fluidez, ya que los comandos van a ser muy simples.

Entonces, si webpack funciona con javascript, ¿cómo va a poder trabajar con css o sass? Pues muy fácil, importando los archivos de estilos dentro de un archivo de JS. Parece un poco loco, ¿verdad? Ahora no lo entenderás muy bien, pero ya verás como todo se aclara un poco más adelante.

Paso 1 – Instalación de webpack

En primer lugar, necesitamos poner a funcionar npm en nuestro proyecto, por lo que, en la raíz del mismo, ejecutaremos:

npm init

Nos pedirá algunas opciones (nombre, descripción, etc). Podemos darle al enter a todo para aceptar los valores por defecto.

Este comando generará un archivo llamado package.json donde se guardará la configuración básica de npm en nuestro proyecto. De momento es un fichero muy básico:

{
  "name": "mimotic",
  "version": "1.0.0",
  "description": "",
  "main": "index.js",
  "scripts": {
    "test": "echo \"Error: no test specified\" && exit 1"
  },
  "author": "",
  "license": "ISC"
}

Lo siguiente que necesitamos, ahora que ya tenemos en marcha npm, es instalar webpack y webpack-cli (para poder darle órdenes por comandos a webpack)

npm install -D webpack webpack-cli

con esa -D nos aseguramos que tanto webpack como webpack-cli se guarden en las dependencias de desarrollo de nuestro fichero package.json

"devDependencies": {
    "webpack": "^4.43.0",
    "webpack-cli": "^3.3.11"
  }

Como veréis, se han creado, además un fichero llamado package-lock.json y una carpeta llamada node_modules. Nada de esto tendremos que tocarlo manualmente. Ya se encarga npm de gestionar todo eso. Son las librerías externas que utilizará npm en nuestro proyecto. Si estás trabajando con un repositorio, la carpeta npm_modules debería ignorarse.

Paso 2. – Crear el archivo de configuración de webpack

Vamos a crear en la raíz del proyecto un archivo con el nombre webpack.config.js

Este archivo va a ser el que le diga a webpack qué y cómo tiene que hacer. Hoy solamente voy a explicar cómo trabajar con estilos, pero las opciones son infinitas.

La estructura de este archivo puede ser muy compleja. Por lo pronto, vamos a crear el esqueleto, que es así:

module.exports = {
    //Aquí incluiremos muchas cosas
}

Por normal general, vamos a tener un archivo de javascript en alguna de las carpetas de nuestro proyecto, donde estará el código con el que tiene que trabajar webpack. Recordad que para lograr que webpack trabaje con archivos de estilos, tenemos que “engañarle” un poco, e importarlos desde un fichero de javascript, que es el que leerá webpack.

Pongamos por ejemplo que tenemos una carpeta llamada /js y que dentro tenemos un fichero que se llama misScripts.js que es el que queremos que trate webpack. De esta forma, solamente tenemos que configurar cuál es la entrada de datos:

module.exports = {
    entry: './js/misScripts.js'
}

En el archivo tengo, de momento, escrito solamente lo siguiente:

console.log('¡Pedro es el mejor!');

Si ahora mismo, con esta configuración, en nuestra consola escribimos la palabra webpack y le damos al enter, cogerá el contenido de ese archivo y nos lo compilará (ahora veremos cómo) en una nueva carpeta llamada dist. Si abrimos esa carpeta, veremos que hay un único archivo de javascript con un buen churro de código en una sola línea. Es javascript minificado. Como estamos aprendiendo, nos interesa que este archivo sea un poco más legible, ¿no? Para eso vamos a crear en webpack un “modo de desarrollo”:

module.exports = {
    entry: './js/misScripts.js',
    mode: 'development'
}

De esta forma, al ejecutar otra vez webpack, el archivo main.js será un poco más legible. Si le echáis un ojo, veréis que contiene unas 90 líneas de código del propio webpack, y abajo del todo incorpora lo que teníamos escrito en el archivo misScripts.js dentro de una función eval(). Curioso, ¿no? Pero no nos vamos a parar en esto, solo quería que lo vieseis para tratar de entender mejor cómo funciona.

Tal vez no nos interese que el archivo de salida se llame main.js, ¿verdad? La configuración de salida se puede modificar de la siguiente forma:

module.exports = {
    entry: './js/misScripts.js',
    output: {
        filename: 'scriptsFinales.js'
    },
    mode: 'development'
}

Incluso puedes cambiarle la ubicación, con un path absoluto añadiendo la propiedad path, o simplemente poniendo una ruta relativa en el nombre del archivo: ‘../js/scriptsFinales.js’.

Paso 3 – Webpack y CSS

 Ahora que sabemos que webpack está funcionando correctamente, vamos a hacer que sepa interpretar CSS. Para ello vamos a empezar por crear un archivo de estilos, que podemos llamar y ubicar donde queramos, y vamos a importarlo en misScripts.js. De este modo, obligaremos a webpack a leerlo. Lo voy a meter en una nueva linea, debajo del console que ya tenía (que, obviamente, podéis eliminar).

console.log('¡Pedro es el mejor!');

import '../css/misEstilos.css';

Si solo con añadir esta línea a misScripts.js y ejecutamos webpack (teniendo algo de código css en el archivo que estamos llamando), nos saltará un error, ya que webpack está buscando código js. No sabe cómo cargar e interpretar el css. Así que lo que tenemos que hacer ahora es instalar dos pequeñas librerías que nos ayudarán en el proceso: mini-css-extract-plugin y css-loader

npm install -D mini-css-extract-plugin css-loader

Una vez instaladas, volveremos al archivo webpack.config.css, para explicarle a webpack cómo tiene que trabajar.

Vamos a crear un módulo de webpack en el que le diremos que cuando se encuentre con un archivo con extensión .css, utilice el plugin y el loader que acabamos de descargar.

Vamos a tener que declarar el plugin al principio del código, y luego dentro de la propiedad plugins lo vamos a instanciar. Es una clase, por lo que no podemos olvidar el new. Luego crearemos un módulo en el que en la propiedad rules vamos a decirle que todos los archivos que cumplan con la dición descrita en test se trabajen con lo que se especifica en use. Como podéis ver, test es una expresión regular. En este caso estamos diciendo que vamos a trabajar con aquellos archivos que acaben en .css

const MiniCssExtractPlugin = require('mini-css-extract-plugin');

module.exports = {
    entry: './js/misScripts.js',
    output: {
        filename: 'scriptsFinales.js'
    },
    mode: 'development',
    module: {
        rules: [
            {
                test: /\.css$/,
                use: [
                    {
                        loader: MiniCssExtractPlugin.loader
                    },
                    'css-loader'
                ]
            }
        ]
    },
    plugins: [
        new MiniCssExtractPlugin()
    ]
}

 Si ejecutamos webpack ahora, va a coger nuestro código css y lo va a compilar en un archivo dentro de la carpeta dist. Por defecto se llamará main.css, pero podemos modificarlo:

¡Perfecto! ya funciona con css, ahora toca afinar para que pueda trabajar con archivos scss.

Paso 4 – Webpack y SCSS

Pongamos que tenemos un archivo scss o sass, y queremos trabajar con él compilándolo con webpack. Por lo pronto parece que lo único que tendríamos que hacer es modificar la expresión regular de nuestro test para que en vez de aplicarse a los archivos css, se aplique a los archivos de sass o de scss. De hecho, podemos modificar la expresión regular para que este módulo funcione con todos los archivos css, scss y sass de una sola tacada:

test: /\.(c|sc|sa)ss$/,

Y en misScripts.js modificaré la ruta del archivo a importar para llamar a mi archivo:

import '../sass/styles.scss';

¿Y ya estaría? Pues casi. Lo único que necesitamos es añadir un cargador de sass, ya que css-loader no es capaz de interpretar código scss. Vamos a utilizar node-sass y sass-loader.

npm install node-sass sass-loader

Y vamos a incorporar sass-loader a nuestro módulo, de tal modo que quedaría tal que así:

module: {
        rules: [
            {
                test: /\.(c|sc|sa)ss$/,
                use: [
                    {
                        loader: MiniCssExtractPlugin.loader
                    },
                    'css-loader',
                    'sass-loader'
                ]
            }
        ]
    },

Si ahora ya por fin ejecutamos webpack, se compilará nuestro código sass o scss en un único y hermoso fichero de css.

Paso 5 – Automatización

Y ahora que ya podemos compilar nuestro código sin depender de otros programas, ¿no sería maravilloso que webpack detectase cada cambio que yo haga en mis archivos de estilos y los compilase automáticamente?

Eso se puede hacer fácilmente ejecutando en la consola

webpack --watch

Pero ya que tenemos instalado npm, ¿por qué no usarlo? Vamos a ir a nuestro archivo package.json, y vamos a crear dos alias para dos scripts. Uno que ejecute webpack y lo compile sin más, y otro para que ejecute ese watch. De este modo, en el futuro podemos añadir más órdenes a estos alias y hacerlos más completos:

Ahora, en nuestra consola, con ejecutar:

npm run watch

Se mantendrá a la escucha, atento a cada cambio para compilar automáticamente.

De esta manera, nuestro archivo final de webpack.config.json será esta preciosidad:

const MiniCssExtractPlugin = require('mini-css-extract-plugin');

module.exports = {
    entry: './js/misScripts.js',
    output: {
        filename: 'scriptsFinales.js'
    },
    mode: 'development',
    module: {
        rules: [
            {
                test: /\.(c|sc|sa)ss$/,
                use: [
                    {
                        loader: MiniCssExtractPlugin.loader
                    },
                    'css-loader',
                    'sass-loader'
                ]
            }
        ]
    },
    plugins: [
        new MiniCssExtractPlugin({
            filename: 'estilosFinales.css'
        })
    ]
}

Contacto

Hola!

¿Quieres contarnos tu proyecto? ¡Escríbenos! Todo nuestro equipo teletrabaja el 100% del tiempo.

Ponte en contacto