📜 ⬆️ ⬇️

Experience with GruntJS

image

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:



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) { //  config.json var config = grunt.file.readJSON('config.json') || grunt.fatal('config.json not found'); //     - config.ignore = getIgnorePatterns(config); var tasks = { clean: { dst: path.join(config.dst, '**/*'), ignore: config.ignore }, livereload: {…}, regarde: {…}, copy: {…}, ect: {…}, less: {…}, uglify: {…}, rsync: {…} }; grunt.initConfig(tasks); grunt.registerTask('lvrld', ['livereload-start', 'connect', 'regarde']); grunt.registerTask('main', ['clean:dst', 'copy:main', 'clean:ignore','uglify:main', 'ect', 'less:browser']); grunt.registerTask('browser', ['main', 'lvrld']); grunt.registerTask('phonegap', ['clean:dst', 'copy:main', 'clean:ignore', 'uglify:main', 'less:phonegap', 'ect']); grunt.registerTask('deploy', ['main', 'rsync:deploy']); grunt.registerTask('default', ['browser']); require('matchdep').filterDev('grunt-*').forEach(grunt.loadNpmTasks); }; 


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.

Source: https://habr.com/ru/post/193092/


All Articles