Si aún no has seguido los pasos de los anteriores capítulos, sería importante que lo hicieras, especialmente los puntos que se llaman "Antes de empezar", que encontrarás en ellos.
También resultará imprescindible que te hagas a la idea de qué són los loaders para webpack; para ello te recomendamos leer esta página.
Finalmente, ya que vamos a trabajar (indirectamente) con el archivo webpack.config.js es necesario que tengas una noción clara sobre qué archivo se trata y cual es su uso. En este último caso, te aconsejamos leer el apartado "Using a configuration" de la guía "GETTING STARTED" de la web de webpack.
Si has seguido los pasos del capítulo 5, tendrás tu proyecto listo para iniciar los pasos del presente capítulo. Pero antes, deberás atender a una cuestión importante: estás usando un proyecto git, que está conectado a un repositorio. Esto te permitirá hacer una entrega de tu trabajo para poderlo conservar y recuperarlo en este estado actual si lo necesitaras en un futuro.
Por lo tanto, empecemos con algunos pasos previos para asegurar que tu trabajo no corre peligro:
Ejecuta las siguientes acciones con la herramienta git:
- Primero de todo añade todos los archivos de tu proyecto a la entrega que realizarás, con la instrucción:
git add -A
- Acto seguido realiza una entrega de los archivos que dispones, con la instrucción:
git commit -m "Entrega del capítulo 5"
Si lo deseas, y sabes cómo puedes llevarlo a cabo, te aconsejamos también que publiques esta entrega en el/los repositorio/s git remoto con el/los que esté conectado tu proyecto.
Si tu proyecto git está correctamente configurado, te bastará con ejecutar:
git push
- Empecemos con el loader llamado
sass-loader.
Para usarlo en el proyecto, instálalo primero con el siguiente comando:npm install --save-dev sass-loader
- Instala ahora su principal dependencia para cuando va a usarse en un proyecto webpack, el package llamado
node-sass, con el siguiente comando:npm install --save-dev node-sass
- Ahora añade
sass-loaderal archivo webpack.module.js del siguiente modo, creando una nueva rule:rules: [ { test: /\.css$/, use: [MiniCssExtractPlugin.loader,'css-loader'], }, { test: /\.s(a|c)ss$/, use: [MiniCssExtractPlugin.loader,'css-loader','sass-loader'], }, ]
- En el archivo
index.jsque hay en la carpetasrc, comenta la línea que realiza el import debulma.min.css, tal que te quede:// import 'bulma/css/bulma.min.css'; - Y añade la siguiente instrucción al principio del archivo
style.cssque hay en la carpetacssdentro desrc:@import '~bulma/css/bulma.min.css';
- Lanza el proceso de empaquetado, con:
npx webpack
Si observas el archivo
style.[hash].cssgenerado en la carpetadist/css, verás que la directiva@importde CSS ha sido capaz de sostener la importación del archivo bulma que anteriormente estaba siendo importado desde la directivaimportde javascript.
- Cambiemos ahora CSS por SASS en ese
@import, modificandolo para que quede así:@import '~bulma/bulma.sass';
- Ejecuta el proceso de empaquetado para observar los cambios en el archivo
style.[hash].cssque se crea en la carpetacssdentro de la carpetadist, con:npx webpack
Como habrás podido observar, en el archivo CSS que se ha creado, aparece el contenido del archivo
bulma.sass, pero este no se ha compilado hacia CSS.
- Para lograr que el código SASS se compile hacia CSS bastará con renombrar el archivo
style.csscomostyle.scss. Para ello puedes usar la siguiente instrucción:git mv ./src/css/style.css ./src/css/style.scss
- Acto seguido corrige la importación del archivo
index.jsque hay en la carpetasrc, tal que quede:import './css/style.scss';
- Ejecuta nuevamente el proceso de empaquetado con:
npx webpack
Observarás que en esta ocasión el archivo
style.[hash].cssya contiene el código CSS tras haberse compilado el código SASS.
- Puedes lograr este mismo resultado, unificando la carga de código CSS y SASS con una única cadena de loaders. Para ello adapta el archivo
webpack.module.jspara que contenga esta única regla:rules: [ { test: /\.s?[ac]ss$/, use: [MiniCssExtractPlugin.loader,'css-loader','sass-loader'], },
- Por lo tanto, debes deshacer el cambio de extensión del archivo
style.scssde la carpetacssque hay ensrc, y volver a dejarlo comostyle.css. Puedes usar el siguiente comando para ello:git mv ./src/css/style.scss ./src/css/style.css
- En consecuencia corrige el
importdel archivoindex.jsque hay en la carpetasrc, para que quede como:import './css/style.css';
- Ejecuta el proceso de empaquetado nuevamente y comprueba que se sigue produciendo correctamente el archivo
style.[hash].cssen la carpetacssque hay endist.npx webpack
Nuestro proyecto ya está casi listo para la VERSIÓN 6.0!
- Elimina la línea con
@importdel archivostyle.cssque importaba bulma, que era como la que sigue:@import '~bulma/bulma.sass';
- Sustituye la línea comentada en
index.jsde la carpetasrcpor la siguiente:import './css/bulma.sass';
- Crea un archivo llamado
bulma.sassdentro de la carpetacssque hay en la carpetasrc, con el siguiente contenido:@import '~bulma/sass/utilities/initial-variables'; @import '~bulma/sass/utilities/functions'; @import '~bulma/sass/utilities/derived-variables'; @import '~bulma/sass/utilities/mixins'; @import '~bulma/sass/base/_all'; @import '~bulma/sass/grid/columns';
- Finalmente puedes ejecutar el proceso de empaquetado para obtener un archivo
styles.[hash].csscon únicamente el mínimo CSS necesario de bulma, reduciendo el tamaño del archivo de 191KB a 46KB.npx webpack
HEMOS TERMINADO!
Si echas un vistazo a tu carpeta webpack-essential encontrarás el siguiente contenido:
config/
webpack/
webpack.module.js
webpack.optimization.js
webpack.plugins.js
dist/
css/
img/
1.svg
2.svg
3.svg
style.[hash].css
index.html
main.js
sitemap.html
index.html
node_modules/
package.json
package-lock.json
src/
assets/
img/
<imágenes>
css/
img/
<imagen1.svg>
<imagen2.svg>
<imagen3.svg>
bulma.sass
style.css
templates/
index.html
sitemap.html
index.js
webpack.config.js
Eso significa que los archivos de configuración de webpack: webpack.config.js, webpack.module.js, webpack.optimization.js y webpack.plugins.js están correctamente escritos!
En el siguiente capítulo usaremos loaders para la gestión de imágenes y otros archivos mientras continuamos modificando el archivo webpack.module.js, ¡pero también el archivo webpack.plugins.js!
-
En el primer paso has instalado un package de npm llamado
sass-loader, que básicamente es un loader de webpack que permite la correcta carga de archivos escritos en lenguaje SASS, y que por lo tanto tengan extensión.scsso.sass.
Para entendernos, los loaders actuán allá donde webpack no llega, durante la resolución de cargas de archivos que no sean javascript o json, y que deban resolverser por haberse encontrado sentenciasrequireoimportde javascript, o@importde CSS, o funcionesimport(..)de javascript ourl(..)de CSS, por poner unos ejemplos.
Si aún y así, el concepto loader era algo sobre lo que guardas dudas, deberías leer el apartado Loaders que hay en la sección "CONCEPTS" en la página oficial de webpack.
Respecto al paquetesass-loader, puedes encontrar documentación e información en esta página. -
Para que webpack, pueda compilar el código SASS y convertirlo en código CSS, es por lo que en el paso 2 has instalado el package
node-sass, que básicamente es un paquete que hace de enlace entre node y la librería libsass, que es la que realmente realiza la compilación del código SASS.
Sobre la librería libsass así como sobre métodos para instalarla en tu sistema, puedes documentarte visitando esta página.
Sobre el paquetenode-sass, puedes obtener información visitando esta otra página.
Finalmente, y sobre la compilación (que ocurre en los pasos 11, 15 y 19), cabe mencionar que es el proceso por el cual a partir de un "código informático" se obtiene otro más compacto y procesable, ya sea por un procesador o por un intérprete.
Los conceptos "compilación", "procesador" o "intérprete", así como el propio término SASS los puedes consultar en estos recursos: -
En el paso 3 has creado una nueva rule (regla) para webpack. La reglas se expresan mediante dos propiedades:
testyuse, y permiten seleccionar una cadena (un array para ser concretos) de loaders que serán utilizados para transformar o cargar en webpack, un determinado tipo de archivos de los que se detecte una importación. En la primera regla, había indicado (en la propiedadtest) una expresión regular que identificaba todo aquello que termine con.cssy en la segunda regla, has indicado una expresión regular que identifica todo aquello que termine con.scsso con.sass.
Y es que la función de la propiedadtestes la de expresar una fórmula de detección de archivos (normalmente mediante una expresión regular) que se usa por cada importación detectada a partir del archivo de punto de entrada (en nuestro casoindex.jsensrc). Cuando la fórmula detecta que el archivo debe ser procesado por la regla, es entonces cuando se usan los loaders que se han indicado en la propiedaduse.
Esta propiedad, se expresa como una lista de loaders (expresados mediante su nombre), que deberán emplearse de manera consecutiva sobre el archivo detectado. El procesamiento se inicia siempre con el último loader de la lista y se recorre la lista en sentido inverso (de fin a principio). Por lo tanto, el último loader indicado, será el primero en aplicarse.
Y es justamente por esta razón que el loader proporcionado por el pluginmini-css-extrac-pluginse coloca el primero de la lista, en tanto que será el responsable de facilitar el código entregado por su antecesor (el loadercss-loader) al plugin para que este genere una archivocsscon dicho código, como vimos en el capítulo 5.
Como puedes imaginar, el loadercss-loaderse encarga de obtener el código CSS que pueda haber en los archivos CSS que vengan siendo importados a partir de nuestro entry pointindex.js.Sobre las propiedades
testyusede las rules, encontrarás la información de referencia en el apartado module que hay en la sección "CONFIGURATION" de la página oficial de webpack. -
En los pasos 4 y 5 has trasladado una importación del archivo
bulma.min.cssde un archivo escrito en javascript a un archivo escrito en CSS, para poder observar que las importaciones son identificadas por webpack y son procesadas a través de los loaders con relativa "independencia" de su procedencia, siempre y cuando esta importación haya sido consecuencia del procesamiento inicial de un entry point, en nuestro casoindex.js.
En el caso concreto de estos pasos, la "cadena de importación" empieza enindex.js(de la carpetasrc) que contiene una sentenciaimportpara el archivostyle.css(de la carpetasrc/css). Y tras el paso 5, este archivo importa, mediante una directiva@importel archivobulma.min.css.
Es importante resaltar que la sentenciaimportno resuelve las rutas del mismo modo que la directiva@import, y es por ello que se añade la tilde (~) al principio de la ruta importada en el archivostyle.css. El uso de la tilde para lograr la importación de archivos que se hallan ennode_modulesen la directiva@import, está documentado en la entrada import que hay en la página dedicada acss-loaderen la sección "LOADERS" de la web oficial de webpack.esta página (ahora bien) -
En el paso 6 has puesto a prueba la cadena de importación descrita para los pasos anteriores (
index.js->style.css->bulma.min.css). -
En los pasos 7 y 8, has tratado de usar el archivo
bulma.sassque es, según la web oficial de bulma el archivo a partir del cual se genera (mediante compilación) el mismo código CSS que el contenido en el archivobulma.min.css. Con todo esto, que cabía esperar tener el mismo resultado al ejecutar el proceso de empaquetado, que el que habías logrado en el paso 6, ya que en los pasos 1, 2 y 3 habías preparado el proyecto para realizar la compilación de código SASS mediante el loadersass-loader. Pero hay un "pero", que lo impide.
Habrás podido ver en su momento, que el código resultante en el archivostyle.[hash].cssya no era el mismo y que aparecían en el toda una serie de importaciones como las siguientes:@import "sass/utilities/_all" @import "sass/base/_all" @import "sass/elements/_all" @import "sass/form/_all" @import "sass/components/_all" @import "sass/grid/_all" @import "sass/layout/_all"
Todo ello es porqué la cadena de loaders que se había preparado para procesar el archivo
style.css(que era el archivo que importababulma.sass) no conteníasass-loader, con lo que aunque a lo largo de su cadena aparecieran archivos escritos en SASS los loaders disponibles no serían capaces de continuar correctamente la cadena de procesamiento, y por lo tanto no se obtendría la compilación del código debulma.sass, tal y como ha ocurrido. -
Por lo ocurrido en estos pasos (7 y 8), en los pasos siguientes, es decir, los pasos 9, 10 y 11, lo que se ha hecho es mitigar este problema, mediante el cambio de lenguaje del hasta entonces archivo
style.css, para que pasara a ser un archivo inicialmente escrito en SASS, cuya extensión de archivo (scss) contentara la fórmulatestde la segunda regla que se había añadido en el paso 3. Gracias al cambio de nombre destyle.cssastyle.scssse detectaría como un archivo al que aplicar la segunda regla y por lo tanto se prepararía una lista de loaders en la que encontraba yasass-loader. Es por ello que el resultado de ejecutar el paso 11 resulta tan exitoso como cuando se ejecutó el paso 6.
Cabe resaltar que, a falta de mayor profundidad en el estudio del apartadomoduleen la configuración de webpack, las rules que se han configurado en el archivowebpack.module.jsse usan en las importaciones que se encuentran directamente en los archivos javascript, cargando una única lista de loaders por cada importación.
Dicho de otro modo, una vez cargada la lista de loaders para un archivo CSS, aunque esta contenga importaciones de otros recursos (imágenes u otros archivos CSS, por ejemplo), ya no se utilizará ninguna otra rule, y por lo tanto no se usarán otros loaders que los que ya se habían elegido para la primera importación del archivo CSS. -
En los pasos 12, 13 y 14, lo que has hecho es justamente preparar una única lista de loaders para usarla con archivos con extensiones
.css,.sassy.scss, es decir, archivos CSS y archivos SASS, por igual. Es por ello que al ejecutar el paso 15, el resultado ya es exitoso, porque el loadersass-loaderse usa en las importaciones originadas por elimportinicial del archivostyle.css, y por lo tanto el código debulma.sassse compila (al contrario de lo que nos ocurría con los pasos 7 y 8). -
Finalmente, en los pasos 16, 17 y 18, lo que has hecho es utilizar la posibilidad que ofrecen los frameworks CSS, como bulma de compilar únicamente el código SASS que crea las reglas CSS que usaremos sin tener que compilar todo el framework íntegro. Es por eso que se crea un archivo
bulma.sassdentro de la carpetasrc/cssque contiene las importaciones indispensables para crear el código CSS que da formato a las clases que se usan en el HTML que hay en el archivoindex.htmlque se encuentra ensrc/templates:column,columnsyhas-text-centered.
Y el paso 19 te permite comprobar el correcto funcionamiento de la compilación obtenida a partir del uso desass-loader, cuyo resultado en forma de CSS es procesado a continuación porcss-loadery finalmente por el loader del pluginmini-css-extract-plugin.