Skip to content
This repository has been archived by the owner on Feb 24, 2024. It is now read-only.

Asset Fingerprinting #578

Closed
paganotoni opened this issue Aug 3, 2017 · 14 comments
Closed

Asset Fingerprinting #578

paganotoni opened this issue Aug 3, 2017 · 14 comments
Assignees

Comments

@paganotoni
Copy link
Member

In order to avoid cache issues for Buffalo applications, buffalo apps should fingerprint its assets based on file contents.

Probably rails documentation explains this better than me.

@paganotoni
Copy link
Member Author

@markbates thoughts ?

@markbates
Copy link
Member

This would require two different things. 1) WebPack would need to be configured to do this sort of finger printing. 2) some sort of assetPath helper that would return the path to an asset with the correct fingerprinting on it.

It may also require changes to packr.

@paganotoni paganotoni self-assigned this Aug 3, 2017
@paganotoni
Copy link
Member Author

I think we can start by adding the assetPath helper which could be a separate story. Im also thinking that this should be one of those opt-out things that as a developer you could disable if you don't want to have in your app.

@paganotoni
Copy link
Member Author

@markbates i would love to work on this one if its ok to work on this now, WDYT ?

@markbates
Copy link
Member

Knock yourself out kid. ;)

@frederikcreemers
Copy link
Contributor

I think you could use a plugin like webpack-manifest-plugin to generate a manifest JSON file, which maps JavaScript file names to the file names of the corresponding output file. Then, the helper can just read that JSON file. If I'm not mistaken, Packr can pack up an entire, directory, so it can just pack up the entire output directory.

@paganotoni
Copy link
Member Author

paganotoni commented Aug 5, 2017

@markbates @bigblind i did an initial attempt at fingerprinting here:

https://github.com/apaganobeleno/app/tree/feature-assets-sample

So far it works and Webpack does the heavy-lifting, however while implementing this (outside buffalo) solution it made me notice somehow when rendering css we need to provide users this helpers as well, so inside a css rule like:

@font-face {
    font-family: myFirstFont;
    src: url(sansation_light.woff);
}

body {
  background: url("some_image.png"),
}

Users can do something like url(<%= assetPath("some_image.png") %>) and use the fingerprinted version of the image.

@frederikcreemers
Copy link
Contributor

frederikcreemers commented Aug 12, 2017

In webpack, file-loader and url-loader take care of this. In the webpack config file that buffalo generates, there are already rules for font files, and for my own project, I've added a rule for png images as well:

{
    test: /\.png$/,
    use: "url-loader?limit=10000&mimetype=image/png" + fileLoaderPath
 }

Given your example background image, this will put a file named "some_image.fq0hx5bh4dx0d.png", and replace the url in the css file with the correct path.

But they'd still need a helper if they ant to reference these resources outside of the webpack-generated bundle.

@paganotoni
Copy link
Member Author

thanks @bigblind !

@paganotoni
Copy link
Member Author

@bigblind one question regarding the png rule you've set, what did you assigned into fileLoaderPath?

@frederikcreemers
Copy link
Contributor

frederikcreemers commented Aug 17, 2017

fileLoaderPath = "&publicPath=/assets"

I have a slightly wonky frontend setup, and I experimented with this setting and the useRelativePath setting.

@paganotoni
Copy link
Member Author

Added in #583

@sbry
Copy link

sbry commented Aug 29, 2017

There is a simpler solution for asset-fingerprinting. Instead of parsing the manifests json from the app, HtmlWebpackPlugin can process the application.html template like this:

...
 output: {
        filename: "application.[chunkhash].js",
        path: __dirname + "/public/assets",
        publicPath: "/assets/"
    },
    plugins: [
        new HtmlWebpackPlugin({
            filename: __dirname + "/public/assets/application.html",
            template: '!!raw-loader!templates/application.html',
        }),
        new ExtractTextPlugin({
            filename: "application.[contenthash].css"
        }),
...

The only other change is referencing the new path in actions/render.go HTMLLayout: "../public/assets/application.html".

@markbates
Copy link
Member

markbates commented Aug 29, 2017 via email

Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
None yet
Projects
None yet
Development

No branches or pull requests

4 participants