Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Grunt - Compress and Include assets with timestamp

I've spent the whole day trying to figure out how to start with Grunt, but all the documentation I was able to find (on GitHub) specifies options and nothing else.

I'm searching for a more user-friendly documentation/how-to since I'm new to Grunt itself.

I'd like to automatize the process of minification of several .css files and include them inside my template within a placeholder defined as

<!-- styles -->

<!-- /styles -->

and

<!-- js -->

<!-- /js -->

What Grunt should do is:

  • look inside my css directory
  • compress files in one "main.css" and "main.js" app
  • open up the html template (it would be great if it doesn't require a tmp version, but instead be able to update the same html file) and write there the final <link> and <script> tags linking to the created file appending a timestamp (for cache busting)

It seems to me like a common approach, but I'm not able to find anything ready out there.

I looked at "grunt-contrib-cssmin", "cartero", "grunt-includes", "grunt-include-replace", "grunt-usemin" and tons of alternatives... but none seems to integrate all requirements and I'm not able to make them work togheter to get what I want to.

like image 739
user1978591 Avatar asked Dec 20 '22 01:12

user1978591


1 Answers

You're on the right track here. grunt-usemin will handle most of what you're looking for but it does require other packages. To get your CSS/JS minification on, you'll need to use a combo of grunt-contrib-cssmin (for CSS), grunt-contrib-uglify (for JS), and while we're making our way through cool grunt packages, I'd recommend using grunt-rev for cache breaking.

To get your scripts working as intended, check out the useminPrepare task. This will let you wrap your CSS and JS files then run tasks against them. For example, a project of mine uses a bunch of goodies from Bower so I have the following in my footer.html:

    <!-- build:js js/scripts.min.js -->
    <script src="./bower_components/zepto/zepto.js"></script>
    <script src="./bower_components/underscore/underscore-min.js"></script>
    <script src="./bower_components/eventEmitter/EventEmitter.js"></script>
    <script src="./bower_components/eventie/eventie.js"></script>
    <script src="./bower_components/imagesloaded/imagesloaded.js"></script>
    <script src="./bower_components/spin.js/spin.js"></script>
    <script src="./scripts/lib/zepto.touch.module.js"></script>
    <!-- endbuild -->

Upon running, useminPrepare will "collect" all of these and make a configuration object that can then be used for compression/minification. My task looks like this:

grunt.registerTask('produce',[
  'clean:main',      // clean out the /dist directory if it exists
  'copy',            // copy files to /dist
  'useminPrepare',   // prepare an object of files that will be passed to concat and/or uglify
  'concat',          // concatenate assets
  'uglify',          // minify assets
  'usemin',          // use the minified version of these files in my html
  'compass:produce', // run production version of compass
  'clean:post'       // cleanup junk
]);

If you really wanted to use timestamps, you could look into adding it to the <!-- build --> comment but I'm not entirely sure it works (I haven't tested). One of the maintainers of Yeoman/grunt-usemin, Addy Osmani, recommends just using grunt-rev: https://github.com/yeoman/grunt-usemin/issues/104.

As for the last bullet point, I would imagine you would want to create a tmp file otherwise you'd be destructively editing your base HTML. If that's what you want to do, I bet you can, but I'd highly recommend not doing so.

like image 65
imjared Avatar answered Jan 08 '23 09:01

imjared