Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Static file public path setup #229

Closed
3 tasks done
subhankarb opened this issue Feb 7, 2017 · 5 comments
Closed
3 tasks done

Static file public path setup #229

subhankarb opened this issue Feb 7, 2017 · 5 comments
Assignees
Labels

Comments

@subhankarb
Copy link
Contributor

subhankarb commented Feb 7, 2017

We have some static file public path issues

  • dpr-js should generate fixed named final css file. Right now it is hash based.
  • The generated main.css file path is not mentioned in dpr-api dataset.html
  • The bundle.js path is not prefixed with s3 cdn path
@Fak3
Copy link
Contributor

Fak3 commented Feb 7, 2017

Extracting from @pwalsh comments on PR:
At some point we will have to switch back to hash-based css filename(url) because of cdn caching issues.

@pwalsh
Copy link

pwalsh commented Feb 7, 2017

It makes little sense not to have kept the hashing, when it was already implemented...

anyway, here are the relevant bits of code and config.

Note that this is from a non-public Django project that I have. The small adjustments for Flask are trivial (Flask config vs. Django settings, Flask context processors vs Django context processors).

# 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']
        }
    }

@pwalsh
Copy link

pwalsh commented Feb 7, 2017

@roll @amercader the above might be useful to you too as you need to do essentially the same in goodtables.io I guess

@subhankarb
Copy link
Contributor Author

@pwalsh thanks a lot

@subhankarb
Copy link
Contributor Author

FIXED.
Fixed by #230

The hash included names for static resources will be implemented with #238

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

No branches or pull requests

3 participants