Why I Switched from Assetic to Gulp
Written by weaverryan, and Leannapelham
tl;dr Assetic was created when there were no real frontend tools for processing and combining CSS/JS. But now there are, and unless you feel really uncomfortable with Node.js, I recommend using Gulp instead of Assetic.
Assetic (PHP library) does one simple job: processes and combines assets. If you've used the Symfony framework, you've probably used it: it's still the recommended tool for taking CSS and JS files, putting them through filters (e.g. Sass, Uglify) and then combining them into one file for production.
But today, I don't recommend using Assetic. Assetic was created back when there were no industry-standard solutions for processing and combining assets. So each language (framework) created their own: Assetic is based off of webassets from Python. And it works really well.
Node.js - and the explosion of packages available via npm
- has changed
all that. There now are asset-processing tools that can be used by PHP
nerds, Python dorks, Java Dude(ttes) and frontend geeks. In this new world,
the tool I like most is Gulp, because it's powerful, and just fun. Using
it over Assetic has some real-world advantages:
Gulp versus Assetic: Pros
A. More people are working on Gulp than Assetic: i.e. you have more tools; B. More people are using Gulp than Assetic: i.e. you find more help on StackOverflow; C. You already know JavaScript: i.e. it's not so scary (and I'll show you).
What about disadvantages? Well, there is one, and it's legit:
Gulp versus Assetic: Cons
A) Gulp adds a new layer to your dev stack (Node.js) and your learning curve;
This last disadvantage is real: if you're low on time, already understand Assetic, and need to do some basic frontend processing: keep using it and stop reading. It's totally ok - Assetic is still a great tool for your case.
For everyone else, let's look at Gulp really quickly in 3 steps:
1) Use Gulp to create Command-Line Tasks
In the simplest sense, Gulp let's you create command-line tasks (like Symfony's
app/console). After installing gulp (npm install gulp
), you create
a single file called gulpfile.js
. This example creates a single task,
which prints a message:
var gulp = require('gulp');
gulp.task('default', function() {
console.log('GULP THIS!');
});
To run it, just do:
gulp default
Got the idea?
2) Read and Process Files
Gulp could be used for anything, but usually you're doing the same thing: reading some files (e.g. .scss files), processing them (e.g. through Sass) then writing out the new files:
var gulp = require('gulp');
var sass = require('gulp-sass');
gulp.task('default', function() {
gulp.src('app/Resources/assets/sass/**/*.scss')
.pipe(sass())
.pipe(gulp.dest('web/css'));
});
Now, any .scss
files in the sass
directory (recursive - that's the
extra /**
part) will have a processed .css
version in web/css
.
3) Combine Files (and a lot more)
Now that our .scss
files have been processed, why not combine them all
into 1 CSS file? That's just a couple extra lines:
var gulp = require('gulp');
var sass = require('gulp-sass');
var concat = require('gulp-concat');
gulp.task('default', function() {
gulp.src('app/Resources/assets/sass/**/*.scss')
.pipe(sass())
.pipe(concat('main.css'))
.pipe(gulp.dest('web/css'));
});
Run gulp default
again (or just gulp
, which triggers the default
automatically) to process and concatenate all your Sass files into one, main.css
.
Feel good? If you want to get a whole working setup, you can find that in our Gulp! tutorial, which includes things like: sourcemaps, minification, uglification and cache busting/versioning.
If you've worked with Gulp and have any tips or warnings for others, I'd love it if you shared.
Cheers!
11 Comments
Enrico Stahn Yea, that's not easy - I do it with a manifest file that tells me the dynamic filename and a Twig extension to do the translation - details are here: http://knpuniversity.com/sc... - and it's more than just "Ryan's method" - the idea is inspired by how Laravel uses Gulp :).
I hope that helps!
Great article. For newer projects gulp might be the way to go. Tried it and it works, though it was a bit of a challenge till I got it as I wanted it (and still, some issues). I'm also one of those who don't like Node.js that much (unless well, I have to use it as in React). I still do a lot of Codeigniter stuff, and been using matthiasmullie/minify. Worked right away. It's more comfy to do all in PHP as PHP is my main thing. Just found Assetic and will try it. Seems awesome (lots of filters!).
Hey Charly!
Thank you for sharing your thoughts about Gulp! Yeah, this tool is cool, and we used to have it installed on SymfonyCasts code base some time... but then Webpack came out, and we switched to Webpack Encore - that brings things to the new level after Gulp, so I would strongly recommend you to watch this tutorial as well: https://symfonycasts.com/sc... - I bet you will decide to move to Webpack Encore someday as it will give you much more features than Gulp does.
And like you, we're mostly coding in PHP too, and we love having Webpack Encore on board :) Btw, Assetic is cool, but it's also in the past in case you switched to Webpack Encore. So, I'd recommend to skip Assetic in favor of Webpack Encore that is the only recommended tool for your assets in Symfony framework now :)
I hope this was useful for you!
Cheers!
Thanks for this good post. I would add a con though.. how do you handle pieces of JavaScript that should run only on a specific page? Any idea? Thanks
Hey @Clément!
Great question! I have 2 things to say about that :)
1) In our Gulp course, we do talk about this. It *is* possible to still have page-specific CSS: http://knpuniversity.com/sc...
2) We've actually switched on KnpUniversity to Webpack, and will be doing a tutorial on this soon! http://knpuniversity.com/sc...
Cheers!
Great intro, thanks, I'll check out the screencast, too.
Seems there's a "var concat = require('gulp-concat');" missing for combining files?
Ah, you're right! Fixed it at https://github.com/knpunive...
Thanks Philipp!
Thanks for the simplest post on this topic!
After setting up bower and gulp for installing, minifying and concating js/css files, I felt the need of a missing functionality that Assetic was providing. That is - busting cached assets. So I wrote a Symfony Bundle to integrate gulp-buster plugin and it's working perfectly.
Here is the Bundle - https://github.com/ajaxray/...
Also explained here: https://symfonycasts.com/sc...
there How do you manage cache busting with Gulp? The filename is usually dynamic and needs to be referenced somehow.