Search code examples
javascriptreactjswebpackhtml-webpack-plugin

Webpack HtmlWebpackPlugin removes DOM elements


I am using Python Flask for my backend with the / route going to static/dist which is webpack's build destination. I am using React on the frontend. When I do a build in web pack it removes all nodes within the body tag. Which causes Error: _registerComponent(...): Target container is not a DOM element. I have verified this is the issue by adding the div to the generated index.html. Anybody know a way to copy those nodes? I have tried adding different configurations for the HtmlWebpackPlugin. I have also tried to dynamically add a document element in my index.jsx file before calling render. Here is my webpack config.

const webpack = require('webpack');
const ExtractTextPlugin = require('extract-text-webpack-plugin');
const HtmlWebpackPlugin = require('html-webpack-plugin');
const config = {
    entry:  __dirname + '/js/index.jsx',
    output: {
        path: __dirname + '/dist',
        filename: 'bundle.js',
        publicPath: '/dist'
    },
    resolve: {
        extensions: [".js", ".jsx", ".css"]
    },
    module: {
        rules: [
            {
                test: /\.jsx?/,
                exclude: /node_modules/,
                use: 'babel-loader'
            },
            {
                test: /\.css$/,
                use: ExtractTextPlugin.extract({
                    fallback: 'style-loader',
                    use: 'css-loader',
                })
            },
            {
                test: /\.(png|svg|jpg|gif)$/,
                use: 'file-loader'
            }
        ]
    },
    plugins: [
        new ExtractTextPlugin('styles.css'),
        new HtmlWebpackPlugin({title:"my app"})
    ]
};

module.exports = config;

Solution

  • HtmlWebpackPlugin does not generate "react" specific html. In this case, the html generated would be:

    <!DOCTYPE html>
    <html>
      <head>
        <meta charset="UTF-8">
        <title>Webpack App</title>
      </head>
      <body>
        <script src="bundle.js"></script>
      </body>
    </html>
    

    In this case, you can specify a template, where you would manually create this div that you need.

    To make this work, you simply:

    new HtmlWebpackPlugin({
      template: path_to_where_my_template_is,
      inject: 'body',
      alwaysWriteToDisk: true
    });
    

    Webpack will inject the required script tags to you.