Integrando Webpack en Symfony 4

slxblog-wpencore.jpg
Solucionex
20
Feb 19

Una de las novedades de Symfony 4 es la integración con Webpack. Al igual que Laravel con Mix, Symfony trae Webpack Encore, el wrapper que nos facilita el desarrollo frontend con Webpack.

Instalar Webpack Encore


Vamos empezar a utilizar Encore en nuestro proyecto Symfony 4, para ello necesitamos tener en nuestro entorno de desarrollo NodeJS y Yarn. Si no tenemos estas herramientas ya instaladas, procedemos a instalarlas ejecutando los siguientes comandos:

sudo apt-get install -y nodejs
curl -sS https://dl.yarnpkg.com/debian/pubkey.gpg | sudo apt-key add -
echo "deb https://dl.yarnpkg.com/debian/ stable main" | sudo tee /etc/apt/sources.list.d/yarn.list
sudo apt-get update && sudo apt-get install -y yarn
export PATH="$PATH:`yarn global bin`"

Una vez tenemos instalado NodeJS y Yarn en nuestro sistema, vamos a utilizar Symfony Flex para añadir Webpack Encore a nuestro proyecto, tras lo cual ejecutar Yarn para instalar y desplegar el WebpackEncoreBundle.

composer require encore
yarn install

Tras ello, veremos que se han añadido los directorios assets/, node_modules/ y el archivo webpack.config.js. Ya tenemos Webpack Encore en nuestro proyecto. Ahora vamos a utilizarlo para compilar nuestros archivos SCSS (Sass) en CSS.

Cómo funciona Webpack Encore


Webpack es conocido por su compleja configuración inicial, y es exactamente esto de lo que nos quiere salvar Webpack Encore. Automáticamente se nos ha generado un archivo webpack.config.js listo para que empecemos a trabajar con Webpack.

var Encore = require('@symfony/webpack-encore');
Encore
// Directorio donde se guardarán los assets compilados
.setOutputPath('public/build/')
// Ruta pública utilizada por el navegador para acceder al directorio anterior
.setPublicPath('/build')
// Archivos de entrada
.addEntry('app', './assets/js/app.js')
;
module.exports = Encore.getWebpackConfig();

En la configuración anterior le estamos diciendo que todo lo generado por los procesos de Webpack definidos en ./assets/js/app.js se almacene en public/build y sea accesible desde el navegador por la ruta /build

Según la documentación de Encore, se deben crear tantas entradas como lógica de cada página. Por ejemplo, tendremos una entrada login.js para nuestra lógica de la vista de Login, una entrada landing.js para nuestra Landing page, etc. Aunque en este ejemplo solamente voy a utilizar una única entrada, app.js

A continuación os expongo un ejemplo más concreto.

Compilar Sass con Webpack Encore


Uno de los usos que le vamos a dar Webpack Encore es el de la gestión de los assets, supliendo la funcionalidad que en versiones anteriores de Symfony nos daba Assetic, el cual se recomienda explícitamente no seguir utilizando según la documentación oficial de Symfony 4.

Dando por hecho que ya hemos completado todos los pasos explicados anteriormente, vamos a configurar nuestro Webpack Encore para el uso de SASS.

Para ello vamos a empezar por editar el archivo webpack.config.js habilitando la propiedad SassLoader, quedándonos el código de la siguiente manera:

var Encore = require('@symfony/webpack-encore');
Encore
// Directorio donde se guardarán los assets compilados
.setOutputPath('public/build/')
// Ruta pública utilizada por el navegador para acceder al directorio anterior
.setPublicPath('/build')
// Archivos de entrada
.addEntry('app', './assets/js/app.js')
// Habilitar features
.enableSassLoader() ;
module.exports = Encore.getWebpackConfig();

Tras lo cual tendremos que ejecutar:

yarn encore dev

Nos devolverá el siguiente error:

Error: Install sass-loader & node-sass to use enableSassLoader()
yarn add sass-loader@^7.0.1 node-sass --dev

Cero alarmas, Yarn nos está diciendo que no tenemos los paquetes requeridos para la operación que está llevando a cabo y nos propone una solución, por lo que procedemos a instalarlos con:

yarn add sass-loader node-sass --dev

Ya tenemos listo nuestro proyecto para compilar Sass. Solamente nos queda irnos al archivo assets/js/app.js y apuntar a nuestro archivo SCSS añadiendo la línea:

require('../scss/app.scss');

Ejecutamos de nuevo el comando:yarn encore dev Así Webpack se encargará de construir nuestros assets públicos. Una vez finalizado, en la carpeta public/build/ podéis encontrar el archivo app.css

Copiar assets con CopyWebpackPlugin


Si vuestro Sass utiliza imágenes, Webpack se encará de versionarlos y publicarlos. Pero si queréis evitar esto podéis utilizar el plugin CopyWebpackPlugin. Este plugin os permitirá copiar directorios y archivos de una ubicación a otra. Solamente tenéis que añadir el plugin con yarn. yarn add copy-webpack-plugin --dev Una vez que Yarn termine de añadir el plugin al proyecto, en el webpack.config.js se tendrán que añadir las líneas para importar el plugin y configurarlo, quedando el archivo tal que así:

var Encore = require('@symfony/webpack-encore');
const CopyWebpackPlugin = require('copy-webpack-plugin');
Encore
// Directorio donde se guardarán los assets compilados
.setOutputPath('public/build/')
// Ruta pública utilizada por el navegador para acceder al directorio anterior
.setPublicPath('/build')
// Archivos de entrada
.addEntry('app', './assets/js/app.js')
// Habilitar features
.enableSassLoader()
// Configurar CopyWebpackPlugin
.addPlugin(new CopyWebpackPlugin([
{from: './assets/static', to: 'static'}
]))
;
module.exports = Encore.getWebpackConfig();

Con estas líneas le estamos diciendo a Webpack que el contenido de la carpeta /assets/static/ nos lo copie en /public/build/static. Esto mismo lo podéis hacer con archivos CSS y JS que no queráis tratar con Webpack y simplemente queráis copiarlos en la carpeta pública de assets.

Para aplicar los campos hay que reiniciar Webpack. Basta con ejecutar de nuevo:

yarn encore dev

O en el caso de utilizar el observador de cambios:

yarn encore dev --watch

Más sobre Webpack Encore


Para terminar os dejo varios enlaces interesantes para profundizar más en Symfony 4 Webpack Encore