openknowledge-archive / dpr-api

DEPRECATED - Data Package Registry API and Frontend
http://frictionlessdata.io/
MIT License
7 stars 6 forks source link

Use hash value for static resources name #238

Open subhankarb opened 7 years ago

subhankarb commented 7 years ago

We have fixed file name for static resources e.g. bundle.js, main.css It is better to use hash values for these resources like bundle.[hash].js

Implementation Details [provided by @pwalsh ]

# package.json

"devDependencies": {
  "webpack-stats-plugin": "^0.1.4"
}
# webpack.base.config.js
'use strict';

var path = require('path');
var ExtractTextPlugin = require('extract-text-webpack-plugin')
var srcDir = path.join(__dirname, 'frontend')
var entryScripts = path.join(srcDir, 'scripts', 'index.js')
var entryStyles = path.join(srcDir, 'styles', 'index.less')
var distDir = path.join(__dirname, 'static')

module.exports = {
  entry: [
    // 'babel-polyfill',
    entryScripts,
    entryStyles
  ],
  output: {
    path: distDir
  },
  resolve: {
    root: path.resolve(__dirname),
    extensions: ["", ".js", ".jsx"]
  },
  module: {
    loaders: [
      {
        test: /\.js$/,
        exclude: /(node_modules|bower_components)/,
        loader: 'babel-loader',
        query: { presets: ['es2015', 'react'] }
      },
      {
        test: /\.less$/,
        loader:  ExtractTextPlugin.extract('style-loader', 'css-loader!less-loader')
      },
      {
        test: /\.woff($|\?)|\.woff2($|\?)|\.ttf($|\?)|\.eot($|\?)|\.svg($|\?)/,
        loader: 'url-loader'
      },
      {
        test: /\.png($|\?)/,
        loader: 'file-loader'
      },
      {
        test: /\.html$/,
        loader: 'raw'
      }
    ]
  }
}
# webpack.development.config.js
'use strict';

var webpack = require('webpack')
var _ = require('lodash')
var ExtractTextPlugin = require('extract-text-webpack-plugin')
var StatsWriterPlugin = require('webpack-stats-plugin').StatsWriterPlugin
var baseConfig = require('./webpack.base.config')
var nodeEnv = 'development'

var developmentConfig = {
  debug: true,
  output: { filename: '[hash].app.js' },
  devtool: 'cheap-module-eval-source-map',
  plugins: [
    new webpack.DefinePlugin({ 'process.env.NODE_ENV':  JSON.stringify(nodeEnv) }),
    new webpack.optimize.OccurenceOrderPlugin(),
    new ExtractTextPlugin('[hash].app.css'),
    new StatsWriterPlugin({
      filename: 'frontend.json',
      fields: null,
      transform: function (data) {
        return JSON.stringify({ hash: data.hash, node_env: nodeEnv }, null, 2);
      }
    })
  ]
}

module.exports = _.merge({}, baseConfig, developmentConfig)
# webpack.production.config.js
'use strict';

var webpack = require('webpack')
var _ = require('lodash')
var ExtractTextPlugin = require('extract-text-webpack-plugin')
var StatsWriterPlugin = require('webpack-stats-plugin').StatsWriterPlugin
var CompressionPlugin = require('compression-webpack-plugin');
var baseConfig = require('./webpack.base.config')
var nodeEnv = 'production'

var productionConfig = {
  debug: false,
  output: { filename: '[hash].app.min.js' },
  devtool: 'source-map',
  plugins: [
    new webpack.DefinePlugin({ 'process.env.NODE_ENV':  JSON.stringify(nodeEnv) }),
    new webpack.optimize.AggressiveMergingPlugin(),
    new webpack.optimize.OccurrenceOrderPlugin(),
    new webpack.optimize.DedupePlugin(),
    new webpack.optimize.UglifyJsPlugin({
      mangle: true,
      compressor: {
        screw_ie8: true,
        pure_getters: true,
        unsafe: true,
        unsafe_comps: true,
        warnings: false
      },
      output: {
        comments: false
      },
      // exclude: [/\.min\.js$/gi]
    }),
    new CompressionPlugin({
      asset: "[path].gz[query]",
      algorithm: "gzip",
      test: /\.js$|\.css$|\.html$/,
      threshold: 10240,
      minRatio: 0
    }),
    new ExtractTextPlugin('[hash].app.min.css'),
    new StatsWriterPlugin({
      filename: 'frontend.json',
      fields: null,
      transform: function (data) {
        return JSON.stringify({ hash: data.hash, node_env: nodeEnv }, null, 2);
      }
    }),
    new webpack.IgnorePlugin(/^\.\/locale$/, [/moment$/])
  ]
}

module.exports = _.merge({}, baseConfig, productionConfig)
# settings.py
def get_frontend_metadata(code_dir):
    """Return the frontend metadata for use in context processors."""
    with io.open(os.path.join(code_dir, 'static', 'frontend.json')) as f:
        return json.loads(f.read())

FRONTEND_METADATA = get_frontend_metadata(REPO_DIR)
# context_processors.py
def frontend_metadata(request):
    """The assets payload, for usage of frontend assets in templates."""
    metadata =  settings.FRONTEND_METADATA
    js_suffix = 'app.js'
    css_suffix = 'app.css'

    if metadata['node_env'] == 'production':
        js_suffix = 'app.min.js.gz'
        css_suffix = 'app.min.css.gz'

    return {
        'frontend': {
            'js': '{hash}.{js_suffix}'.format(hash=metadata['hash'], js_suffix=js_suffix),
            'css': '{hash}.{css_suffix}'.format(hash=metadata['hash'], css_suffix=css_suffix),
            'hash': metadata['hash'],
            'node_env': metadata['node_env']
        }
    }