borodean / postcss-assets

An asset manager for PostCSS
MIT License
537 stars 32 forks source link

Rails and postcss-assets #17

Closed madyankin closed 9 years ago

madyankin commented 9 years ago

Hi, I'm using postcss-assets with Rails-style cachebuster: application-7a0306d552d84deaa57f0af77c99a8ed.js. As you can see It's not query string based. It would be nice to change the cachebuster callback in order to support this. Or pass in an argument with assets paths: {'application': application-7a0306d552d84deaa57f0af77c99a8ed.js}.

ai commented 9 years ago

@borodean problem is that query bases cachbaster like file.js?hash doesn’t work in some rare environment. So, for example, wepback put hash into name too.

It will be better for cachebuster option to have a full path:

cachebuster: function (path) {
    return path.basename(path, path.extname(path)) + '-' + hash(path) + path.extname(path);
}
ai commented 9 years ago

@borodean any updates? This is not only Rails issue. For example, many Gulp pluugins adds hash to the file name.

ai commented 9 years ago

Any updates here? For example, we now has separated plugin for cache buster in dir: https://github.com/code42day/postcss-cachify

But if we had optin that we ask, this plugin will be unnecessary.

madyankin commented 9 years ago

@ai use postcss-url, it fits quite well for that.

borodean commented 9 years ago

I’m trying to get this working using a syntax similar to the one which Compass uses.

Here is how it could look like

To define a custom cachebuster pass a function as an option:

var options = {
  cachebuster: function (filePath) {
    return fs.statSync(filePath).mtime.getTime().toString(16);
  }
};

If the returned value is falsy, no cache busting is done for the asset.

If the returned value is an object the values of pathname and/or query are used to generate a cache busted path to the asset.

If the returned value is a string, it is added as a query string.

The returned values for query strings must not include the starting ?.

Busting the cache via path:

var options = {
  cachebuster: function (filePath, urlPathname) {
    var hash = fs.statSync(filePath).mtime.getTime().toString(16);
    return {
      pathname: path.dirname(urlPathname) + '/' + path.basename(urlPathname, path.extname(urlPathname)) + hash + path.extname(urlPathname),
      query: false // you may omit this one
    }
  }
};

@outpunk and @ai, any thoughts?

ai commented 9 years ago

@borodean yeap, object API is nice way to save current behaviour. Do you need any help?

madyankin commented 9 years ago

:+1: