Time for a change
Hi! Today I’ll talk about how we configure and work with assets content in a Symfony application.
The Assetic Bundle is used by default in the Symfony framework to process Javascript, css, Less or sass files. But sometimes during development, this tool can stop working reliably and making collections. Eventually I decided that it was time to find a replacement.
Which tools?
In the world of Javascript many developers use tools such as Gulp, Grunt and Bower. These tools can quickly load libraries and assemble them in our application. I choose to use Gulp for building and Bower for package management of lib-sources.
So on our Ubuntu 14.04 server, suppose we installed NodeJS, (because we need to have Javascript on the server to use the tools I mentioned):
sudo apt-get install nodejs
In the folder with our Symfony application we must initialize the package.json file to npm (Node Package Manager):
npm init
Answer a few basic questions and start to install your tools:
npm install -S bower gulp less gulp-less gulp-clean gulp-concat gulp-uglify
Add the node_modules folder to the .gitignore file. (If you use git as a version control system).
In the next step we initialize the bower.json file to our lib-sources:
./node_modules/.bin/bower init
Again you’ll need to answer a few basic questions. In my projects, I usually use Bootstrap as my default framework for HTML, CSS, and JS developing. I’ll use it today for this example too:
./node_modules/.bin/bower install -S bootstrap
After installing, don’t forget to add the bower_components folder to .gitignore.
Ok, We have all the tools to start building the css file for our pages. Now create a gulpfile.js and start configuring gulp.
In the custom front-end files I make a web-src folder in the root folder of the symfony application. I write Less in the folder web-src/less and js in the web-src/js folder. In my entire application I have just one Less file (web-src/less/app.less) in which I include all required Less/css files from external libraries:
/*---------- app.less ------------*/ @import "../../bower_components/bootstrap/less/bootstrap.less";
/*---------- gulpfile.js ------------*/ var gulp = require('gulp'), less = require('gulp-less'), clean = require('gulp-clean'); gulp.task('less', function() { return gulp.src(['web-src/less/*.less']) .pipe(less({compress: true})) .pipe(gulp.dest('web/css/')); }); gulp.task('images', function () { return gulp.src([ 'web-src/images/*' ]) .pipe(gulp.dest('web/images/')) }); gulp.task('fonts', function () { return gulp.src(['bower_components/bootstrap/fonts/*']) .pipe(gulp.dest('web/fonts/')) }); gulp.task('clean', function () { return gulp.src(['web/css/*', 'web/js/*', 'web/images/*', 'web/fonts/*']) .pipe(clean()); }); gulp.task('default', ['clean'], function () { var tasks = ['images', 'fonts', 'less']; tasks.forEach(function (val) { gulp.start(val); }); }); gulp.task('watch', function () { var less = gulp.watch('web-src/less/*.less', ['less']); });
All images I save in the web-src folder too, because my IDE doesn’t find these files when I use them in app.less:
.. app bin bower_components node_modules src vendor web |_css |_ js web-src |_ less |_ app.less |_ js bower.json composer.json composer.lock package.json README.md
Add the task for building the js to our application:
/*---------- gulpfile.js ------------*/ var gulp = require('gulp'), … concatJs = require('gulp-concat'), minifyJs = require('gulp-uglify'); … gulp.task('lib-js', function() { return gulp.src([ 'bower_components/jquery/dist/jquery.js', 'bower_components/bootstrap/dist/js/bootstrap.js' ]) .pipe(concatJs('app.js')) .pipe(minifyJs()) .pipe(gulp.dest('web/js/')); }); gulp.task('pages-js', function() { return gulp.src([ 'web-src/js/*.js' ]) .pipe(minifyJs()) .pipe(gulp.dest('web/js/')); }); gulp.task('clean', function () { return gulp.src(['web/css/*', 'web/js/*', 'web/images/*', 'web/fonts/*']) .pipe(clean()); }); gulp.task('default', ['clean'], function () { var tasks = ['images', 'fonts', 'less', 'lib-js', 'pages-js']; tasks.forEach(function (val) { gulp.start(val); }); }); gulp.task('watch', function () { var less = gulp.watch('web-src/less/*.less', ['less']), js = gulp.watch('web-src/js/*.js', ['pages-js']); });
After a few seconds we’ll have app.css and app.js files in our symfony application. Include these files in base.html.twig.
Now we have a full replacement for Assetic Bundle in place, it’s time to remove the original:
- remove the assetic configuration in app/config/config.yml and app/config/config_dev.yml
- remove Assetic Bundle from the app/AppKernel.php
- run the following command in console:
composer remove "symfony/assetic-bundle"
And there you have it! A functioning, reliable replacement for Assetic Bundle.