npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2024 – Pkg Stats / Ryan Hefner

asset-fingerprint-webpack-rails

v1.2.1

Published

A webpack plugin to fingerprint your JS for consumption by Rails

Downloads

73

Readme

Asset Fingerprint Webpack Rails

A webpack plugin to fingerprint your JS for consumption by Rails

Build Status

Install

npm install asset-fingerprint-webpack-rails --save-dev

Usage

Note: You will likely want to avoid running the fingerprinting in anything but a production build. Otherwise, if you have file watching setup for instance, it will rebuild the fingerprinting each time a file is updated, requiring you to bounce the Rails server to pickup the new fingerprint. One way to avoid this is by passing an option to your command for dev vs prod: (webpack for dev without fingerprinting, and webpack --env.fingerprint for prod build).

This plugin requires you to set your initializer directory path relative to your webpack config, such as: config/initializers as the first argument. The second optional argument determines whether or not the fingerprinting should take place. By default, this is set to true.

const AssetFingerprintPlugin = require('asset-fingerprint-webpack-rails');
new AssetFingerprintPlugin('config/initializers', true);

It uses the hash values from the webpack stats object. This is the value that will be output into a new initializer called asset_fingerprint.rb, as: ASSET_FINGERPRINT=XXXXXXXX. You should setup your webpack.config.js to use this hash when building your output file (see sample config below).

It is also recommended that you use a plugin such as clean-webpack-plugin in conjunction with this plugin to clean out your output directory on each build, if you wish to avoid a collection of old files.

Option 1

Use a local variable in webpack.config.js to pass into the plugin to inform it whether not not it should fingerprint, calling webpack without any args. plugin defualts to fingerprint=true with no args

// webpack.config.js

...
/**
 * require the plugin
 */
const AssetFingerprintPlugin = require('asset-fingerprint-webpack-rails');
const needsFingerprint = someLocalBoolean;
const initializerDirectory = 'config/initializers';
/**
 * add it to your plugins and conditionally use the hash in the filename
 */
module.exports = {
  entry: "./entry.js",
  output: {
    path: __dirname,
    filename: needsFingerprint ? "bundle-[hash].js" : "bundle.js"
  },
  plugins: [
    new AssetFingerprintPlugin(initializerDirectory, needsFingerprint)
  ]
};

Option 2

Setup your webpack.config.js to conditionally return an object based on an argument passed into the webpack command, like webpack --env.fingerprint

start webpack with an option: webpack --env.fingerprint

Then in webpack.config.js

// webpack.config.js

/**
 * require the plugin
 */
const AssetFingerprintPlugin = require('asset-fingerprint-webpack-rails');

/**
 * return a configuration object based on the option passed in, only using the plugin when it exists
 * and conditionally using the hash in the filename
 */
module.exports = function(fingerprint) {
  if (fingerprint) {
    return {
      entry: "./entry.js",
      output: {
        path: __dirname,
        filename: "bundle-[hash].js"
      },
      plugins: [
        new AssetFingerprintPlugin(initializerDirectory)
      ]
    }
  } else {
    return {
      entry: "./entry.js",
      output: {
        path: __dirname,
        filename: "bundle.js"
      }
    }
  }
};

Integration with Rails

Now that our asset_fingerprint.rb file is setup, we can conditionally use it in our views by setting up a helper method in application_helper.rb:

  def asset_with_fingerprint(asset_name)
    Rails.env.production? ? "#{asset_name}-#{ASSET_FINGERPRINT}" : asset_name
  end

And in your layout:

  = javascript_include_tag asset_with_fingerprint('path_of_bundled_js_output/bundle')

That's it! Now if you use a cleaner as suggested, along with file watching, you'll be able to run this in development and have bundle.js rebuild without fingerprinting, and your Rails app with use that directly. Once you build for production, your Rails app and your bundle.js will use a fingerprinted version of the file.

Managing multiple webpack builds

If your build setup launches webpack multiple times a new hash will be generated with each run. This can cause problems when using the default arguments. The last run will overwrite any previously written hash value. An additional parameter can be passed to tell the plugin to append a new named value that has the key from the subsequent run.

Passing a name in the third paramenter will generate a new line in asset_fingerprint.rb having the name assigned to the new hash. For example:

AssetFingerprintPlugin(rubyConfigInitPath, true, 'CUSTOM_ASSET_FINGERPRINT')

will generate a new line in the file like this:

ASSET_FINGERPRINT = '0556f9ab7cbd607d10ed'
CUSTOM_ASSET_FINGERPRINT = '921dcffe35e5f2740ef5'

The format for the fingerprint name must uppercase separating words with underscore i.e. "CUSTOM_ASSET_FINGERPRINT". The name also needs to end with "_FINGERPRINT".

Credit

Concept adapted from @samullen - http://samuelmullen.com/articles/replacing-the-rails-asset-pipeline-with-webpack-and-yarn/