roadhog.js supporting hash and CDN

07 May, 2017Front-end, Webpack

This post only applies to roadhog.js 1.x version, it is no longer valid, please upgrade to the latest version

Workaround:

Ideas

Installation

npm i -D ejs-loader html-webpack-plugin webpack-md5-hash

There is no need to install extract-text-webpack-plugin because roadhog already has version 1.0.1. If you install version 2.x yourself, it may cause problems. Need to install additional ejs-loader because it will be used in the webpack configuration

webpack.config.js

const ExtractTextPlugin = require('extract-text-webpack-plugin')
const HtmlWebpackPlugin = require('html-webpack-plugin')
const WebpackMd5Hash = require('webpack-md5-hash')

module.exports = function (config, env) {
  config.module.loaders[0].exclude.push(/\.ejs$/) // Note 1
  if (env ==='production') {
    config.output.filename ='[name].[chunkhash].js'
    config.output.chunkFilename ='[chunkhash].async.js'
    config.plugins[3] = new ExtractTextPlugin('[contenthash:20].css') // Note 2
    config.plugins.push(
      new HtmlWebpackPlugin({
        template:'ejs!src/index.ejs', // Note 3
        inject: false,
        minify: {collapseWhitespace: true },
        production: true,
      }),
      new WebpackMd5Hash()
    )
  } else {
    config.plugins.push(
      new HtmlWebpackPlugin({
        template:'ejs!src/index.ejs',
        inject: true,
      }),
    )
  }
  return config
}

[1] The roadhog default configuration uses url-loader to load, but the ejs file needed by html-webpack-plugin will be base64 encoded, so the ejs format should be added to the loader whitelist, refer to

[2] Override roadhog’s configuration

[3] Roadhog uses the file-loader by default for html. The html-webpack-plugin here needs to read its content as a template, so if you change to ejs, you no longer need index.html

.roadhogrc

{
  "env": {
    "production": {
      "define": {
        "__CDN__": "https://cdn.example.com"
      }
    }
  }
}

.eslintrc

{
  "globals": {
    "__CDN__": false
  }
}

index.ejs

<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <title>Example</title>
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <meta http-equiv="X-UA-Compatible" content="IE=edge">
  <% if (htmlWebpackPlugin.options.production) {%>
    <%= htmlWebpackPlugin.files.css.map((item) => {
      return `<link href="${__CDN__}${item}" rel="stylesheet">`
    }) %>
  <%} %>
</head>
</head>
<body>
  <div id="root"></div>
  <% if (htmlWebpackPlugin.options.production) {%>
    <%= htmlWebpackPlugin.files.js.map((item) => {
      return `<script src="${__CDN__}${item}" charset="utf-8"></script>`
    }) %>
  <%} %>
</body>
</html>

Remove import'./index.html' in index.js` (if any)

In this way, both the development environment and the deployment environment use the same set of html entries, and the development environment uses local files, and the deployment environment uses CDN files named according to the file content MD5 (for cache control)

References


Powered by Gatsby. Theme inspired by end2end.

© 2014-2021. Made withby mdluo.