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
- RequireJS – for writing modular Javascript code (and manage modules dependencies).
Introduction
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
- modular Javascript code (thanks to RequireJS)
- 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.
Requirements
There are some requirements that needs that need to be met before processing.
Install Git
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).
Install Node.js
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.
Install Bower
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).
Install Grunt
Grunt is a Javascript task runner.
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.
Configuration
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.
.bowerrc
.jshintrc
bower.json
package.json
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 node_modules
directory.
All bootstrap files have been created and it’s time to take care of the Gruntfile.js
.
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:
RequireJS
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.
main.js
common.js
homepage.js
JSHint
Symlink
Uglify
Less
Watch
Symfony configuration
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_dev.yml
& config_prod.yml
files and modifying Gruntfile paths.
I store the RequireJS view in app/Resources/views/requirejs.html.twig
file.
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. AppBundle/Resources/views/Homepage/index.html.twig
:
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
Zapisz
Zapisz