Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to properly minify/combine CSS/JS in web projects with url rewriting

I've been struggling for hours trying to set up proper minification that actually rewrites urls. I've used useref and usemin, and they do good job of scanning html, aggregating all JS and CSS and outputting into one file. But, for the life of me, I cannot make the url rewrite to work properly. My structure is simple:

\root
   index.html
   application.css       // minified
   application.js        // minified
   \vendor
       \bootstrap
           \fonts        // font files here
           bootstrap.css // pre-minified 

bootstrap.css refers to font files by using relative url - font/bootstrap_font.ttf When bootstrap gets minified, it lands as part of application css, that is in my root now, so the path would point from root to /font/bootstrap_font.ttf. Original directory hierarchy stays, so I would basically like to have this url rewritten to /vendor/bootstrap/font/bootstrap_font.ttf

And, oh, why cssmin task doesn't accept more than one file?

UPDATE Here's my current grunt file:

module.exports = function(grunt) {
    grunt.initConfig({
        pkg: grunt.file.readJSON('package.json'),
        useminPrepare: {
            html: 'web/public/index.html',
            options: {
                dest: 'web/public-dist'
            }
        },
        usemin: {
            html: 'web/public-dist/index.html',
        },
        copy: {
            all: {
                files: [{
                    expand: true,
                    cwd: 'web/public/',
                    src: ['**'],
                    dest: 'web/public-dist/'
                }]
            },
            resources: {
                files: [{
                    expand: true,
                    cwd: 'web/public/',
                    src: ['**/*.*', '!**/*.js', '!**/*.css', '!**/*.txt'],
                    dest: 'web/public-dist/'
                }]
            }
        },
        uglify: {
            options: {
                mangle: true,
                sourceMap: false,
                compress: true,
                banner: '/*! <%= pkg.name %> <%= grunt.template.today("yyyy-mm-dd") %> */\n'
            },
            standard: {
                files: [{
                    expand: true,
                    cwd: 'web/public-dist/',
                    src: ['**/*.js'],
                    dest: 'web/public-dist/'
                }]
            }
        },
        cssmin: {
            options: {
                banner: '/*! <%= pkg.name %> <%= grunt.template.today("yyyy-mm-dd") %> */\n',
            },
            standard: {
                files: [{
                    expand: true,
                    cwd: 'web/public-dist/',
                    src: ['**/*.css'],
                    dest: 'web/public-dist/'
                }]
            },
        }
    });

    grunt.registerTask('package', [ 'copy:resources', 'useminPrepare', 'concat:generated','cssmin:generated', 'uglify:generated', 'usemin']);
};

In this form, cssmin cannot be even used as separately called target, because apparently its configuration is wrong - it complains that it cannot accept many files. What am I doing wrong here?

From the bits and pieces I've gathered, apparently it's crucial to change usemin flow and not allow it to concatenate all the css and cssmin later - because this way, it would obviously lose the vital information about the directory origin of every css file. I've tried changing the flow, but then it doesn't work because of the same cssmin error - cannot accept many files.

like image 829
rattkin Avatar asked Nov 07 '14 14:11

rattkin


People also ask

How do you minify CSS and JavaScript?

To minify CSS, try CSSNano and csso. To minify JavaScript, try UglifyJS. The Closure Compiler is also very effective. You can create a build process that uses these tools to minify and rename the development files and save them to a production directory.

How does Minifying a file CSS JS HTML help?

Minification is the process of minimizing code and markup in your web pages and script files. It's one of the main methods used to reduce load times and bandwidth usage on websites. Minification dramatically improves site speed and accessibility, directly translating into a better user experience.


1 Answers

Okay, I has definitely same problem when started to build my css and js with grunt. Here is my solution of "relative urls" problem. Please, note that this post is not answering your actual question, but provide another way of problem solution. I have even more nested folder structure but it works well for me, and hope it helps you.

The gist is to build all css/js to another folder and copy assets files relatively to this new folder. Let give "build" name for it:

\root
   \build
       application.css - minified
       application.js  - minified       
       \fonts
           ...
       \img
           ...
       ...
   index.html
   \ ...

Using grunt-contrib-copy plugin copy all your assets to /build/assets directory without breaking their original structure. So relative passes for your css saves, fonts are still in ./fonts/ folder.

The problem you'll faced to with such approach is saving folder structure for assets. Well, it is solved with detalization of your build configuration in your gruntfile. Now you can not say "okay grunt, build all /**/*.css files to application.css" but have to describe different cases for different options of file structures. If your project have obvious and logical file structure it is not complicated to add them.

I used rule that every css file must have assets directory as it sibling. So gruntfile expanded just by several lines and build structure look something like this

\root
   \build
       \css
           \assets
               \fonts
               \img
           application.css - minified    //all relative passes saved
   \foo
       \bar
           \biz
               \assets
                   \fonts
               first.css
       \row
           \assets
               \img
           second.css
   index.html

Obviously you must have assets names naming rules to prevent overriding files.

Hope, this helps you

like image 153
Glen Swift Avatar answered Oct 19 '22 11:10

Glen Swift