Being a programmer who works mainly with Symfony taught me to use the best tools available – modern, well tested and widely used. I don’t like Assetic for many reasons, and I’ve decided to not touch it any more. In this article, I’ll illustrate how to replace Assetic with modern frontend tools: RequireJS, Grunt & Bower.
- Grunt – for automated tasks
- Bower – for dependency management
There are many advantages of using this approach:
- frontend developers can use the tools of their choice
- assets aren’t coupled with the core of the application (Assetic forces assets to be part of the bundle 1). You can use Git submodules or an independent repository for your assets.
- frontend changes do not require application update 2
- speeding up the process – Assetic is ridiculously slow in big projects (large amount of assets) especially in dev environment
- ease of use – the configuration requires one single command to
- you stop using software that has no advantages.
If you’re still not convinced – ask yourself if you can find one real advantage of using Assetic, then continue reading.
There are some requirements that needs that need to be met before processing.
Bower requires Git. It will most likely be installed on your development environment server. It can be installed from the system repository (yum install git on RHEL based distros).
This can be achieved in many ways:
+ installing from your system repository (
yum install nodejs npm on RHEL based distros)
+ downloading Linux binaries from Node.js website
+ compiling from sources.
Bower is a package manager for frontend dependencies (libraries, frameworks, fonts & stuff).
After installing Node.js & npm you can install Bower simply by running the following command:
npm install -g bower (this will install Bower globally into your system).
Grunt installation requires two steps. You need to install
grunt-cli package globally and provide grunt as a dependency in your
package.json file. At this step, just install it globally by running
npm install -g grunt-cli command.
After all required software has been installed, you can proceed to the next step.
Important! Before moving to the next step, you need to add
node_modules directory to your
.gitignore file as you don’t want to add all node.js modules to your repository.
At this stage, you need to prepare following files:
- package.json – npm dependencies (most likely Grunt plugins)
- bower.json – Bower dependencies
- .bowerrc – Bower runtime configuration
- .jshintrc – JSHint runtime configuration
- Gruntfile.js – Grunt configuration.
As soon as the package.json file is ready, you can install all Grunt plugins by running
npm install command. All required modules should in installed into
All bootstrap files have been created and it’s time to take care of the
At this step, there are two path configuration variables, all required Grunt modules are loaded and two main tasks have been created. Two words about those tasks:
- default – this is the default task and should be used at the development stage
- dist – this task should be used to prepare production-ready assets.
Grunt plugins configuration:
There are three modules configured:
- main.js – the main RequireJS configuration file. Why are jQuery and Bootstrap included as dependencies for this module? Both libraries will be included into main.js file (in fact, this file is always used) and are excluded in other modules. Note: in fact, jQuery and Bootstrap are still dependencies for common and homepage modules but those files won’t be included into both modules’ output file.
- common.js – module that contains code that’s being shared on all pages.
- homepage.js – module for homepage.
There are two steps required to prepare Symfony to use the new approach: configure the assets path and prepare RequireJS view.
Add the assets variable to your Twig globals in app/config/config.yml file:
Note: as you surely must have noticed, I use the same path for development and production assets (same goes for CSS/JS filenames). Why? Ease of use, as you provide only one configuration path and load only one file regardless of environment you are actually working with. It’s still flexible as you can customize this though by providing two separate variables in
config_prod.yml files and modifying Gruntfile paths.
I store the RequireJS view in
I think this code is quite self-explanatory and doesn’t need to be elaborated on.
I always define requirejs block in base.html.twig file:
To use it in a single view, ex.
Everything is set up. You can now start writing your top-notch code and forget about Assetic 3.
I’ve prepared a test repository on Github.
- Visit this Stackoverflow question for more details.
- Imagine the following situation: you need to change a some code/fix some bugs in your LESS/SASS file. In the classic approach it would require updating the code, pushing the changes to the application repository (as assets are part of Symfony bundle), rebuilding & installing assets. In this approach, you only need to update assets, update your assets repository and update them in the application.
- Do not remove it thought as it’s still required for some bundles (ex: Web Debug Toolbar).
Article originally published on osmialowski.net