Cómo instalar y configurar Bootstrap con Symfony Webpack Encore
Pasos para instalar Bootstrap con el bundle Symfony Webpack Encore

En este artículo quiero contaros los pasos que he seguido para hacer funcionar Bootstrap 4 junto con Webpack Encore y Symfony 4.
De primeras puede que su instalación parezca muy sencilla pero durante el proceso he encontrado alguna peculiaridad que me ha inspirado para hacer este pequeño artículo por si os topáis con lo mismo.
Así que, como siempre, vamos a ello!
Paso 1. Instalar y configurar Webpack Encore
Para empezar, instalaremos y configuraremos Webpack Encore siguiendo la magnífica documentación que posee este bundle:
Una de las cosas que más me gustan de Symfony es la extensa documentación que tiene de cada bundle / funcionalidad. Agiliza mucho el proceso de aprendizaje y siempre que me preguntan algún libro sobre este framework les remito a ella porque no creo que exista nada mejor. Un diez por quienes la mantienen!
Además, instalaremos Bootstrap mediante yarn
de la forma habitual:
yarn add bootstrap
lo cual nos dejará sus archivos en la carpeta node_modules
.
A partir de aquí puede que comiencen algunos problemas.
Paso 2. Problemas
Supongamos que necesitáis usar alguna librería de Bootstrap (como por ejemplo collapse.js
).
Puesto que no vamos a importar el archivo dist/bootstrap.js
entero (si no, para que queremos Webpack Encore) lo que haremos será crear dentro de la carpeta assets/js
un archivo similar al siguiente:
// assets/js/collapse-menu.jsvar $ = require(‘jquery’);import 'node_modules/bootstrap/js/src/util.js';import 'node_modules/bootstrap/js/src/collapse.js';
El problema es que si ahora tratáis de generar el build
mediante Webpack Encore:
yarn run encore dev
es probable que os salte el siguiente fallo:
error in ./node_modules/bootstrap/js/src/collapse.jsModule parse failed: Unexpected token (278:8)You may need an appropriate loader to handle this file type.| _getConfig(config) {| config = {| ...Default,| ...config| }
Provocado por el uso del spread operator de javascript que apareció en la especificación ES6 de Javascript.
O que todo vaya bien, pero sin embargo, el archivo resultante todavía contenga el spread operator, algo que probablemente no le gustará a algún que otro navegador antiguo:
_getConfig(e){return(e={...p,...e})
Es aquí donde la librería Babel acude al rescate, permitiéndonos transpilar el código Javascript de nuestros archivos a código compatible con los motores empleados por los navegadores (que suele ser habitual que se demoren en integrar las novedades de las nuevas especificaciones de Javascript).
Para configurarlo (Webpack Encore lo emplea por defecto como loader
de los archivos javascript) podemos crear un archivo .babelrc
en la raíz de nuestro proyecto o bien escribir las instrucciones de configuración directamente en nuestro archivo webpack.config.js
. Personalmente prefiero la primera opción por evitar mezclar en un mismo archivo la configuración de varias librerías pero por desgracia hasta la versión 0.26 de WebpackEncore ambos métodos eran incompatibles, por lo que os tendréis que decantar por uno u otro.
Para Babel < 7
En el caso de que por lo que sea estéis trabajando con un proyecto que emplee alguna versión de Babel anterior a la 7, la solución se basa en instalar los presets es-2015
y stage3
.
stage3
añade la posibilidad de usar el spread operator en nuestros archivos mientras que es-2015
permitirá usar las novedades surgidas con la especificación aparecida en ES6. Los instalaremos mediante yarn:
yarn add babel-preset-es2015 --save-devyarn add babel-preset-stage-3 --save-dev
Y, a continuación, en el archivo .babelrc
añadimos lo siguiente:
{“presets”: [ [“es2015”, { “loose”: true, “modules”: false, “useBuiltIns”: true }], “stage-3”]
}
Para Babel ≥ 7
Con la llegada de la versión 7 de Babel, se recomienda emplear el plugin preset-env
el cual hará el trabajo sucio por nosotros ahorrándonos tener que instalar a mano las dependencias que necesitemos para transpilar correctamente nuestro código.
Su instalación la haremos mediante yarn:
yarn add @babel/preset-env --save-dev
Mientras que su configuración podéis llevarla a cabo bien mediante un archivo babel.config.js
en la raíz del proyecto (no sirve el archivo .babelrc
ya que no es leído para transpilar los archivos situados en node_modules
):
{
“presets”: [
[
“@babel/preset-env”,
{
“targets”: {
“chrome”: “58”,
“ie”: “11”
},
“useBuiltIns”: “usage”
}
]
]
}
O bien dentro del archivo package.json
añadiendo la siguiente propiedad al objeto principal
"browserslist": [ "> 0.25%, not dead"]
Sin embargo, con cualquiera de estas dos configuraciones seguiremos con el mismo problema tras pedirle a encore
que genere nuestra build
.
Paso 3. Soluciones
Rebuscando por Internet no parece haber mucha información acerca de este problema por lo que me tocó bajar un poco al barro hasta dar con la causa de ese error:
Webpack Encore configura por defecto Babel para que no pase por node_modules
Concretamente en el archivo:
@symfony/webpack-encore/lib/config-generator.js
Esto tiene sentido, pues así se ahorra un tiempo considerable a la hora de generar la build
. Sin embargo, en casos como el que nos ocupa es necesario tener alguna forma de permitir que Babel pase por determinadas carpetas dentro de node_modules
.
Concretamente en este ejemplo queremos que Babel pase por la carpeta node_modules/bootstrap
de cara a transpilar esos spread operators y así hacer nuestra build
compatible con navegadores antiguos.
La solución se basa en añadir lo siguiente al archivo webpack.config.js
:
.configureBabel(null, { includeNodeModules: ['bootstrap']})
Bastante limpio. Además, si estáis empleando una versión de Webpack Encore superior a 0.26 podéis compatibilizar esta solución con emplear el archivo babel.config.js
para el resto de la configuración de Babel.
Podéis ver esta configuración funcionando en el siguiente repositorio:
Espero que os haya servido este artículo. Recordad que si tenéis cualquier duda integrando Bootstrap u otra librería con Webpack Encore podéis dejarla en los comentarios e intentaré resolverla.
Hasta el siguiente artículo!
¿Quieres recibir más artículos como este?
Suscríbete a nuestra newsletter: