
Hey. We finally finished work on one interactive book, and now I really want to tell you about one of the most interesting tools we used - GruntJS.
Little about the project
Actually, we did an interactive book of a popular Russian writer. The book is written in JS, templates ECT-JS and LESS. Grunt is building, concatenating, minifying and deploying, the book works on the iPad under Phonegap.
')
Technically, we made a prototype - we actively studied and applied various technologies. With something turned out cool, with something not very. Anyway, the book works, and it can even be downloaded from the App Store.
I think that is enough. Now you can go to GruntJS ...
Grunt Head Brain
- I have two variables, how do I add them?
- I put the plugin “jquery.math”, very convenient!
I'll tell you a bit exaggerated, but instructive story. The main graphic format in our project was PNG24 with transparency. The project took about 500MB. We decided to optimize it. Of course, using the GruntJS plugin ...
Sane result was not. 500MB did not go into any framework. With difficulty squeezed to 450Mb. In the end, after several days of searching, they dropped 250 MB. Like this:
find . -name "*.png" | xargs pngquant -f -v --ext .png --quality 0-90
GruntJS is awesome but addictive. Of course, this story is a bit exaggerated, but I did see how people do such things. Resembles jQuery plugins. Still, it is sometimes easier to get by with a one-liner on a bash, or to connect time-tested console utilities.
In general, you can execute bash scripts and commands via grunt. For this there is a
grunt-shell .
grunt.initConfig({ shell: { compressPNG: { options: { stdout: true }, command: 'find . -name "*.png" | xargs pngquant -f -v --ext .png --quality 0-90' } } }); grunt.loadNpmTasks('grunt-shell'); grunt.registerTask('compress', ['shell: compressPNG']);
Config for Gruntfile.js
In our project, Gruntfile.js contained about 200 lines of code, where logic and parameters were mixed. We decided to make a separate config for Gruntfile. In my project for this purpose, I created a file config.json, in which I store:
- Source Directory
- Deploy directory
- Variables for the template engine (e.g. book title)
- Ignore list (files that do not fall into Deploy)
- List of LESS files and target file
- JS file list and target file
- Parameters for deployment to the server for testing
The benefits of this are many. Firstly, adding files becomes much easier, and secondly, a person completely unfamiliar with Grunt can make small changes in the config file. Well, in the third, the logic does not mix with the parameters.
The config looks like this:
{ "src": "_src", "dst": "www", "port": 8000, "variables": { "bookname": " "}, "ignore": [ "**/*.ect", "**/*.md", "**/*.less"], "less": { "www/app/assets/css/app.min.css": ["_src/app/assets/less/main.less"], "www/content/assets/css/content.min.css": ["_src/content/assets/less/main.less","_src/content/widgets/**/widget.less"] } }, "js": { "www/app/assets/js/app.min.js": [ "_src/app/assets/js/utilities.js", "_src/app/assets/js/modules/*.js", "_src/app/assets/js/setups/*.js", "_src/content/widgets/**/*.js" "_src/app/assets/js/init.js", ] } }
Gruntfile example
module.exports = function (grunt) {
Convenient debugging on devices
Debugging code on a pair of iPads and MacBooks is very inconvenient. You have to constantly update the page with your hands. It's horrible.
This is where Grunt can help. If you run grunt-contrib-watch, configure livereload, and connect all devices by IP, then when changing the code all gadgets will reload the page themselves. This is amazing! Seriously, if you constantly reload the page even on three devices, then in an hour I want to smash everything into pieces.
Generally, there is a problem. There are relatively many files in our project. About a thousand and two. So, if you cover everything with livereload (with different tasks, of course), then the nodejs starts to fall. We have to refuse full coverage. We went under the knife pictures.
Writing plugin
In general, I chose the template engine quite simply - I took the first one I got, with layout and partials. The first one was ECTJS. Now I would take a jade, but then take this one. Not finding a suitable plugin for the template engine, I decided to write my own.
In general, writing a plugin for gruntjs is quite simple. Almost everything you need is written in the
instructions . In general, the algorithm is as follows:
1.
grunt-init gruntplugin
will create a project structure
2. Write the code, connect the modules ...
3. When you need to - we look at
the GruntJS API
Vobschem is all that I wanted to share.