Gulp! Refreshment for Your Frontend Assets

We all need to minify and combine our CSS and JS files. And with Gulp, this is not only easy, but it's actually fun to do!

In this tutorial, I'll show you how to setup Gulp in your PHP or Symfony project to do a bunch of things:

  • Minify CSS and JS files
  • Watch files for changes
  • Combine files
  • Use sourcemaps
  • Publish Font files
  • Have page-specific CSS/JS files
  • Cache-bust with versioning

We'll actually use Laravel's Elixir as a guide, but make things work for any PHP project and learn how we can make Gulp do whatever we need.

Yay!


Your Guides

Ryan Weaver Leanna Pelham

Questions? Conversation?

  • 2016-08-31 Shairyar Baig

    ya, i will try that and see if that helps.

  • 2016-08-29 weaverryan

    Hey Shairyar!

    Oh wow, that just sounds buggy :/. With the "merge: true", the manifest plugin should only *update* the file, and not override it. And with the pipeline, we should not have race conditions if you have multiple CSS or JS files. I do wonder if Basit recommendation will help here - the only thing I can think of is a race condition between the CSS and JS processes themselves. If that *does* help, I'd love to know.

    Cheers!

  • 2016-08-26 Shairyar Baig

    It happens randomly, if i open up a project and run the command gulp first time there is a chance that it will be successful but then there are times even the first gulp command does not work, i have to keep trying it 7 to 8 times to get it to work.

    The same happens if i am in the middle of the project and make a change to the css or js file there are times the manifest does not get updated then i have to manually stop and run gulp again which takes 7 to 8 times to get going again or if i am lucky the first try will work.

  • 2016-08-26 Shairyar Baig

    Thanks Basit I will give this idea a try.

  • 2016-08-25 Basit

    I'm using same technique, have same problem.

    You can overcome by providing finish condition on each task, so don't run other until first is finished, then dont run third, until second is finished.

    gulp.task('styles', ['fonts'], function...

    gulp.task('scripts', ['styles'], function()

    gulp.task('watch', ['styles', 'scripts'],...

    This will help you a lot, but it is still not 100% accurate, because I do get still problem time to time.

  • 2016-08-25 weaverryan

    Hey Shairyar!

    It sounds like the "race condition" we talk about here: https://knpuniversity.com/scre...

    Does it happen during the "watch" task? I mean, if you run gulp, does it compile correctly at first, but then *later* the rev-manifest.json becomes broken after you update some CSS or JS files? Or, does it happen only when initially running gulp? My guess is that there's still a race condition somewhere... Also, make sure you have the merge: true option on the manifest (I'm guessing you do, else you would see this problem constantly).

    Let me know what you see!

  • 2016-08-24 Shairyar Baig

    I have been using this technique since i saw this tutorial 5 months ago, the concept is neat however I do come across a situation occasionally where "rev-manifest.json" does not include either css and js file name in it when i run gulp command, i have to then several times stop the recompile and this becomes annoying after a while. I did not make any change to the code just changed the css and js files that are being compiled plus the location of "rev-manifest.json" is in AppBundle/Resources/public/asset folder.

    Is anyone running into the same issue occasionally? is this the excepted behaviour once in a while? when the "rev-manifest.json" does not include one of the files, i do cross check if these files were actually created and they were as i can see them in css and js folder. I also do not see any error in console either.

    Here is my gulp.js https://gist.github.com/shairy...

  • 2016-06-27 weaverryan

    Hey Mark!

    Ah, I see! So you certainly don't need Symfony to do this - this was just the approach if you *are* in Symfony :). Basically, one way or another, you just need some dynamic code (e.g. PHP) that's able to read that rev-manifest.json file and map each file name (e.g. main.css) to its current revision filename (e.g. main-123abcd.css).

    Let me know how I can help - and of course it's always great when people are able to share their solutions! I look forward to it.

    Cheers!

  • 2016-06-26 Mark33684

    Thanks a lot for ur quick reply Ryan,

    thats what i was wondering, since i dont have a services.yml file...i guess i need to install symfony to the gulp project folder to make it work?. i will try to figure it out. i am working on a gulp project that outputs html and/or craft templates..so i dont have to migrate the site to craft afterwards..if u are interested i will post it once i am done...if i get lost with the yml file and sznfony i will get back to u ..thanks again :)

  • 2016-06-26 weaverryan

    Hey Mark!

    Yep, you'll need 2 things for the Twig extension, and both (as you probably already know) are on this page: https://knpuniversity.com/scre...

    1) You'll need the finished, AssetVersionExtension class itself - check out the code-blocks
    2) You'll need to "steal" the YAML code from the services.yml file and put it into *your* services.yml file. That code is also on the linked page, but I just realized that we're "hiding" the good parts. I'll fix that right now - but you can find the services.yml on that page and click the little errors to expand and see the entire file.

    If you're new to registering things as services, and this "tags" thing, I encourage you to check out http://knpuniversity.com/scree... and http://knpuniversity.com/scree... - those will really help you feel comfortable :).

    Cheers!

  • 2016-06-26 Mark33684

    hey there, thanks for the fantastic tutorial. it really helped me understanding a lot more in gulp. i just got stuck at chache bursting..i dont get how to tell twig where there php extension is and how to load the filter ...i got also confused by the yml file..do i have to install something else to make it work? thanks a lot for ur help.

  • 2016-04-01 Basit

    I Agree soo much with Ryan on this. Angular 3 is coming out soon. No? well wait and check again lol. No really. once you done learning one thing, there is new thing that replaced the thing you learned lolz.

  • 2016-04-01 weaverryan

    Yes, the frontend world moves so fast!

  • 2016-03-30 TheLastTamurai

    Hi Ryan,
    Nice tutorial, please update the "Minify" video script to use "gulp-clean-css" as "gulp-minify-css" is deprecated.

    Regards,
    Tamer

  • 2016-03-15 Shairyar Baig

    thanks for sharing the information, that really sounds like a pain.

  • 2016-03-14 weaverryan

    Yep, webpack and browserify are "competitors" - though I just read an article today that said that webpack seems to be winning.

    However, I'm not sure that "gulp" is necessarily going away - browserify/webpack can be used *inside* of gulp - i.e. https://webpack.github.io/docs.... If you read the first comment there, there's some discussion about this :).

    Anyways, yes, I'd like to make a "2.0" version of this tutorial - the JS world moves so quickly :). But I have a few other tutorials that need to get done first.

    Cheers!

  • 2016-03-14 Basit

    Hi Shairyar,

    if you use bower, then your packages will get updated automatically on new package installation, which is pain. Solution is eaither use npm to manage packages or use git to keep track. It does not work like composer.

    for this reason and many other, people are moving to webpack.

  • 2016-03-14 Shairyar Baig

    Hi Ryan,

    Yes you can call me Baig :)

    Thanks for getting back to me. Sad to hear that gulp is being used less as i just learnt it :)

    Are you planning to create a tutorial on npm + browserify?

    Baig

  • 2016-03-14 weaverryan

    Hey Baig!

    Can I call you Baig - I saw you signed with that this time :)

    1) Yep, this directory can get *huge* - it's just how npm is designed. But, it doesn't even need to be deployed (if you build your assets locally first) - you could ignore it from your deploy. And yes, node is famous for having many, many sub-directories. It's kinda crazy :). Btw, make sure you have the latest npm - *some* of this has changed I believe (but I think it's still huge).

    2) Nope - well, not if you build your css/js first (which I do). If you do that, you can just deploy those generated css/js files and completely ignore the node_modules directory

    3) A quick googling makes this unclear, surprisingly. But, I would keep it anyways - it helps other people understand your project more quickly - many people understand what will live in node_modules. I sometimes move the bower directory because I want it in my web directory (and btw, it seems bower is being used less and less, and things like npm + browserify are being used instead: https://lincolnloop.com/blog/u.... But, I haven't switched over just yet :).

    Cheers!

  • 2016-03-14 Shairyar Baig

    Hi Deric,

    Many thanks for the information. Ya i don't think i will be uploading the node_module either as i am just using gulp to merge and compress files.

    I am really beginning to enjoy gulp and bower :)

    Regards,
    Baig

  • 2016-03-14 Deric Cain

    Hey Shairyar,

    I have worked with npm and can help answer your questions:

    1) I would keep everything that is in your node_modules folder. A lot of times when you install something using npm, it will also load any other dependencies that package may require. It's a lot like Composer for the front-end.
    2) You don't have to upload the folder. If you have dependencies in the node_modules folder that your project requires, you can install node on your production server and just run `npm install` and all of your dependencies with be installed on your server. Again, this is a lot like Composer. You just need to pay attention to whether or not you link to any assets in your node_modules folder. Usually, I do not use npm for assets. Instead, I use Bower, so I know that I do not have to upload my node_modules folder and I don't have to run `npm install` on my production server. I simply use it for Gulp and that just helps me while in development, not in production.
    3) You could move it inside of your vendor folder, but most of the time, all of the things in your node_modules folder are not dependencies, unlike the things in the vendor and bower_components folder. This is more of a personal preference, but I would keep them separated.

  • 2016-03-12 Shairyar Baig

    Hi,

    I understand that gulp puts everything inside `node_modules` directory and I have 3 questions about it.

    1) Do we really need everything thats sitting inside `node_modules` directory, reason I am asking this is because its over 34MB, we only installed like 13 plugins of gulp following the tutorial but there are 295 folders which I am assuming are plugins inside `node_modules` folder.
    2) Do you need to upload `node_modules` folder on production?
    3) Cant we move `node_modules` inside vendor directory that comes with symfony just like `bower_components` directory?

    Regards,
    Baig

  • 2016-02-19 Shairyar Baig

    Great tutorial, finally understand the gulp now :)

  • 2016-01-15 Dimitar Ivanov

    I love to use Gulp in my projects. Check out my blog post on task automation with gulp.js: http://zinoui.com/blog/task-au...

  • 2015-10-28 weaverryan

    Hey Basit!

    Great! Let me know how you like things!

    About clean. I believe what you're saying is that the "clean" task does not return a promise, so there's no guarantee that it will clean will finish before the other tasks start. Your logic is correct, however, the clean task (I believe) is special because I use the "del.sync" - which deletes things *synchronously*. In other words, unlike everything else that gulp is doing, each line in clean waits to finish before it goes to the next line. The result is that the clean function doesn't actually finish until all of its tasks are actually done. This means that it will finish before the others start.

    If you're seeing something different, let me know! But it's very good of you to notice that this function appears to behave different than the others :).

    Cheers!

  • 2015-10-28 Basit

    Thanks. I have decided to go with your version, which covers everything. Just one question I had. You haven't mention about how to make sure clean is done first, before others function start running.

    since everything required on promise and clean does not have such. I have just return true on clean task, would it work fine with return true, to make sure clean is run first and then others.

    btw, if you add requireJs also on this tutorial. It will complete the set. but for those who were interested in requirejs to complete the set, following is link for slideshow by Ryan http://www.slideshare.net/weav...

  • 2015-10-27 weaverryan

    Hi Basit!

    I think you could push more work into Symfony / Assetic if you wanted to, but let's think how that might work. If you didn't combine the files in gulp (just processed sass to CSS etc), you could create an Assetic tag that included the processed filenames. I think that would work. But Assetic doesn't have any versioning. Symfony has a versioning feature but out of the box, it's global: you change the version on a configuration file and it changes the version for all assets. Assetic does have the ability to create a random output filename if you don't give it one, but iirc, this was not meant for versioning.

    Was this along what you were thinking?

    Cheers!

  • 2015-10-26 Basit

    Hi Ryan,

    For versioning you have used gulp-rev and made your own asset twig extension to read and load. Wouldn't it be better to just use symfony assetic features to do compiling and versioning automatically as standard way, rather then doing extra customisations on gulp.

    What are your thoughts on this? :)

  • 2015-07-22 weaverryan

    Yea, I *do* have Elastic specifically in mind. I need to integrate it anyways with our search to make it a lot more awesome. When I do that, I'll put a tut on it :)

  • 2015-07-22 Victor Bocharsky

    Hey Ryan!

    Do you plan to add any tutorial about search engines like ElasticSearch or any other? There are a great bundle FOSElasticaBundle that integrate Elasticsearch in Symfony2 projects but I am interested in your cool examples )

  • 2015-03-19 Tyler Steimle

    Yes! So happy to see the Gulp series. It's my favorite task runner already. Can't wait to dig in, I'm sure you have some things I missed. :)