Search code examples
webpackhtml-webpack-plugin

Index.html with Webpack - How to put conditional code in it?


I am uisng webpack with the "HtmlWebpackPlugin" and I want to put some google analytic code in but of course I only want it to be put in if it is on the production server.

Is there easy way I can do this?

Here is my "webpack.common.js" (i have one for production, qa and dev).

const path = require("path");
const HtmlWebpackPlugin = require("html-webpack-plugin");
const CleanWebpackPlugin = require("clean-webpack-plugin");
const webpack = require('webpack');

module.exports = {
  entry: ["@babel/polyfill", "./src/index.js"],
  output: {
    // filename and path are required
    filename: "main.js",
    path: path.resolve(__dirname, "dist"),
    publicPath: '/'
  },
  module: {
    rules: [
      {
        // JSX and JS are all .js
        test: /\.js$/,
        exclude: /node_modules/,
        use: {
          loader: "babel-loader",
        }
      },
      {
        test: /\.(eot|svg|ttf|woff|woff2)$/,
        use: [
          {
            loader: 'file-loader',
            options: {}  
          }
        ]
      },
      {
        test: /\.(png|jpg|gif)$/,
        use: [
          {
            loader: 'file-loader',
            options: {}
          }
        ]
      }
    ]
  },
  plugins: [
    new CleanWebpackPlugin(["dist"]),
    new HtmlWebpackPlugin({
      template: "./src/index.html"
    }),
    new webpack.IgnorePlugin(/^\.\/locale$/, /moment$/),
    new webpack.DefinePlugin({
      'process.env.NODE_ENV': JSON.stringify(process.env.NODE_ENV)
   })
  ]
};

I updated to

const path = require('path');
const HtmlWebpackPlugin = require('html-webpack-plugin');
const CleanWebpackPlugin = require('clean-webpack-plugin');
const webpack = require('webpack');

module.exports = (env, argv) => {
  const ga = argv.mode === 'production' ? './index-google.html' : 'index.html';
  return {
    entry: ['@babel/polyfill', './src/index.js'],
    output: {
      // filename and path are required
      filename: 'main.js',
      path: path.resolve(__dirname, 'dist'),
      publicPath: '/'
    },
    module: {
      rules: [
        {
          // JSX and JS are all .js
          test: /\.js$/,
          exclude: /node_modules/,
          use: {
            loader: 'babel-loader'
          }
        },
        {
          test: /\.(eot|svg|ttf|woff|woff2)$/,
          use: [
            {
              loader: 'file-loader',
              options: {}
            }
          ]
        },
        {
          test: /\.(png|jpg|gif)$/,
          use: [
            {
              loader: 'file-loader',
              options: {}
            }
          ]
        }
      ]
    },
    plugins: [
      new CleanWebpackPlugin(['dist']),
      new HtmlWebpackPlugin({
        template: './src/index.html'
      }),
      new webpack.IgnorePlugin(/^\.\/locale$/, /moment$/),
      new webpack.DefinePlugin({
        'process.env.NODE_ENV': JSON.stringify(process.env.NODE_ENV)
      })
    ]
  };
};

but when I build I get

ERROR in ./src/index.js 35:4
Module parse failed: Unexpected token (35:4)
You may need an appropriate loader to handle this file type.
| ReactDOM.render(
| 
>     <Provider routingStore={routingStore} domainStores={DomainStores} uiStores={uiStores}>
|       <Router history={history}>
|         <ErrorBoundary FallbackComponent={ErrorFallbackComponent}>
 @ multi ./src main[0]

babel file

{
  "presets": ["@babel/env", "@babel/react"],
  "plugins": [
    ["@babel/plugin-proposal-decorators", { "legacy": true }],
    "@babel/plugin-transform-object-assign",
    "@babel/plugin-proposal-object-rest-spread",
    "transform-class-properties",
    "emotion"
  ]
}

I have an old repo what I modeled off my real code

https://github.com/chobo2/webpack-serve-example


Solution

  • You can check if it is a production version and thus serve what you like

    new HtmlWebpackPlugin({
      filename: 'index.html',
      template: argv.mode === 'production' ? 'src/index-google.html' : 'src/index.html'
    })
    

    or take a look at this stackoverflow

    EDIT
    I see that your webpack project is divided into dev, prod, common and config. Delete HtmlWebpackPlugin from config and insert into dev and prod with the appropriate html file.

    dev

    new HtmlWebpackPlugin({
      template: "./src/index.html"
    })
    

    prod

    new HtmlWebpackPlugin({
      filename: index.html,
      template: "./src/index-google.html"
    })
    

    I hope this solves the problem