Html-webpack-plugin: Incremental build error - childCompilation.assets[outputName].source()

Created on 22 Jun 2017  Â·  13Comments  Â·  Source: jantimon/html-webpack-plugin

Description

This error is with webpack 3 and the latest version of this lib.

The error affects incremental builds only, not initial build. Happens every time a inc build is started.

"devDependencies": {
    "@types/material-ui": "^0.15.37",
    "@types/node": "^7.0.12",
    "@types/react": "^0.14.57",
    "@types/react-dom": "^0.14.23",
    "copy-webpack-plugin": "^4.0.1",
    "cross-env": "^3.2.3",
    "css-loader": "^0.27.3",
    "dotenv": "^4.0.0",
    "extract-text-webpack-plugin": "^2.1.2",
    "file-loader": "^0.10.1",
    "html-webpack-plugin": "^2.28.0",
    "jimp": "^0.2.27",
    "json-loader": "^0.5.4",
    "node-sass": "^4.5.2",
    "prettyjson": "^1.2.1",
    "responsive-loader": "^0.7.0",
    "sass-loader": "^6.0.3",
    "style-loader": "^0.13.2",
    "transform-loader": "^0.2.4",
    "ts-loader": "^2.0.3",
    "tslib": "^1.7.1",
    "typescript": "^2.3.4",
    "url-loader": "^0.5.8",
    "webpack": "^3.0.0",
    "webpack-dev-server": "^2.5.0",
    "webpack-dotenv-plugin": "^2.0.2",
    "webpack-merge": "^4.1.0",
    "webpack-s3-plugin": "^1.0.0-rc.0",
    "webpack-visualizer-plugin": "^0.1.11"
  },

Error Message & Stack Trace

/Users/Danijel/projects/am/am-web/node_modules/html-webpack-plugin/lib/compiler.js:98
          content: childCompilation.assets[outputName].source()
                                                      ^

TypeError: Cannot read property 'source' of undefined
    at /Users/Danijel/projects/am/am-web/node_modules/html-webpack-plugin/lib/compiler.js:98:55
    at Compiler.<anonymous> (/Users/Danijel/projects/am/am-web/node_modules/webpack/lib/Compiler.js:298:10)
    at /Users/Danijel/projects/am/am-web/node_modules/webpack/lib/Compiler.js:516:13
    at next (/Users/Danijel/projects/am/am-web/node_modules/tapable/lib/Tapable.js:138:11)

Config

Copy the relevant section from webpack.config.js:

const path = require('path');
const webpack = require("webpack");
const HtmlWebpackPlugin = require('html-webpack-plugin');
const merge = require('webpack-merge');
const webpackParts = require('./webpack');
const ExtractTextPlugin = require('extract-text-webpack-plugin');
const CopyWebpackPlugin = require('copy-webpack-plugin');

// Load target env configuration 
var env = process.env.NODE_ENV || 'development'
let envConfig = require('dotenv').config({ path: `./config/.env.${env}`, silent: env === 'production' })
console.log(envConfig)

const PATHS = {
    app: path.join(__dirname, 'src'),
    images: path.join(__dirname, 'assets'),
    build: path.join(__dirname, 'dist')
};

const common = {
    output: {
        path: PATHS.build,
        filename: '[name].[hash].js',
        publicPath: '/',
        chunkFilename: '[id].[hash].chunk.js'
    },
    plugins: [

        // Script hoisting 
        // @see https://medium.com/webpack/webpack-3-official-release-15fd2dd8f07b
        new webpack.optimize.ModuleConcatenationPlugin(),

        new CopyWebpackPlugin([
            {
                from: `${PATHS.images}/favicon.ico`,
                to: `assets/favicon.ico`
            }
        ]),

        new webpack.LoaderOptionsPlugin({
            // test: /\.xxx$/, // may apply this only for some modules
            options: {
                context: __dirname,
                responsiveLoader: {
                    sizes: [250, 500, 800, 1200, 1600],
                    placeholder: true,
                    placeholderSize: 50,
                    quality: 75
                },
                // fileLoader: {
                //     query: {
                //         useRelativePath: true //process.env.NODE_ENV === "production"
                //     }
                // }
            }
        }),

        // Split build output into logical app / vendor bundles. https://github.com/webpack/webpack/issues/969
        new webpack.optimize.CommonsChunkPlugin({
            name: 'vendor',
            minChunks: Infinity
        }),

        new HtmlWebpackPlugin({
            title: envConfig.name,
            template: 'index.template.ejs',
            env
        }),

        // Extract all styles sheets into seperate bundle
        new ExtractTextPlugin({
            filename: '[hash].css',
            allChunks: true
        }), //ignoreOrder: true
    ],
    resolve: {
        extensions: ['.ts', '.tsx', '.js']
    },
    module: {
        rules: [
            {
                test: /\.tsx?$/,
                use: 'ts-loader',
                include: PATHS.app,
            },
            {
                test: /\.jpg$/,
                use: 'responsive-loader',
                include: PATHS.images,
            },
            {
                test: /\.(png|jpg|svg)$/,
                use: 'url-loader?limit=8192',
                include: PATHS.app,
            },
            {
                test: /\.(jpg|png|svg)$/,
                use: 'file-loader?name=[name].[hash].[ext]', //[path]
                include: PATHS.images
            }
        ]
    }
};

// Build webpack config 
var config;

// Detect how npm is run and branch based on that
switch (process.env.npm_lifecycle_event) {
    case 'development':
    case 'test':
    case 'production':

        config = merge(
            {
                entry: {
                    app: PATHS.app,
                    vendor: ['react', 'react-router', 'material-ui', 'apollo-client', 'redux', 'mobx', 'mobx-react', 'lodash', 'chart.js', 'numeral']
                },
            },
            webpackParts.setEnvVar({
                'process.env': {
                    config: JSON.stringify(envConfig),
                    NODE_ENV: JSON.stringify('production')
                }
            }),
            webpackParts.optimise(),
            common,
            // webpackParts.setupSourceMap("source-map"),
            // webpackParts.setupSourceMap("cheap-module-source-map"),
            webpackParts.setupCSS(PATHS.app),
            webpackParts.deployToS3()
        );
        break;
    default:

        config = merge(
            {
                entry: {
                    app: [
                        'webpack-dev-server/client?http://localhost:3000',
                        'webpack/hot/only-dev-server',
                        // 'react-hot-loader/patch',
                        PATHS.app
                    ],
                    vendor: ['react', 'react-router', 'material-ui', 'apollo-client', 'redux', 'mobx', 'mobx-react', 'lodash', 'chart.js', 'numeral']
                }
            },
            webpackParts.setEnvVar({
                'process.env': {
                    config: JSON.stringify(envConfig),
                    NODE_ENV: JSON.stringify(env)
                }
            }),
            common,
            webpackParts.setupSourceMap("cheap-module-source-map"),
            webpackParts.setupCSS(PATHS.app),
            webpackParts.devServer({
                host: process.env.HOST || "0.0.0.0", // Run webpack-dev-server with --host 0.0.0.0 — this lets the server listen for requests from the network, not just localhost.
                port: process.env.PORT || "3000"
            })
        );
}

console.log(JSON.stringify(config))

module.exports = config; 
exports.setupCSS = function (paths) {
    return {
        module: {
            rules: [
                {
                    test: /\.css/,
                    use: [
                        'style-loader',
                        'css-loader'
                    ],
                    include: paths
                },
                {
                    test: /(\.scss|\.sass)$/,
                    use: ExtractTextPlugin.extract({
                        fallback: "style-loader",
                        use: [
                            {
                                loader: 'css-loader',
                                options: {
                                    sourceMap: false,  // TODO process.env.NODE_ENV != 'production'
                                    importLoaders: 1,
                                    modules: true,
                                    // url: true,
                                    // import: true,
                                    // localIdentName: '[name]__[local]--[hash:base64:5]',
                                    hashPrefix: 'package-name' + Date.now(),
                                    localIdentName: '[path][name]__[local]--[hash:base64:5]',
                                    discardComments: {
                                        removeAll: false  // TODO process.env.NODE_ENV != 'production'
                                    }
                                }
                            },
                            {
                                loader: "sass-loader",
                                options: {
                                    sourceMap: false // TODO process.env.NODE_ENV != 'production'
                                }
                            }
                        ]
                    })
                }
            ]
        }
    };
}

<!DOCTYPE html>
<html>

<head>
    <link rel="shortcut icon" type="image/png" href="/assets/favicon.ico" />
                <meta http-equiv="Content-type" content="text/html; charset=utf-8" />
                <meta name="viewport" content="initial-scale=1.0,user-scalable=no,maximum-scale=1,width=device-width">
                <title>
                    <%= htmlWebpackPlugin.options.title %>
                </title>
</head>

<body>
    <div id="root" />
</body>

</html>
bug wontfix

Most helpful comment

Just to be clear, I followed the suggestion from #533 and did the following:

    169        new webpack.HotModuleReplacementPlugin({
    170 -        multiStep: true
    171 +        multiStep: false

Working for me, now.

All 13 comments

@sokra was the child compiler changed or do you have any idea why this might be broken for webpack 3?

I seem to have resolved my issue by applying the fix mentioned in https://github.com/jantimon/html-webpack-plugin/issues/533.

@dcworldwide Could that fix be having a negative effect on hmr ?

@dcworldwide is the fix to disable multiStep until the issue is resolved?

@joskoanicic @eladchen Not sure to either question.

@dcworldwide disabling off multiStep helped. Incremental builds don't break but HMR is not working as it used to (getting page reloads instead of module reloads)

@joskoanicic Yeah that's correct for me as well. Waiting on someone from core to jump in.

:+1:
Severe issue for me as well.
Do we have any chance to have it fixed soon?

Similar problem here, but now the initial build fails once as well following an incremental build failure.

And of course, no HMR -- this is a major impact to development workflow.

Just for the record, here's my package.json. (And, yes... I am not using devDependencies; this is not-yet production code and it helped get out of npm dependency hell.)

{
  "name": "react-boilerplate",
  "private": true,
  "version": "2.5.6",
  "description": "Boilerplate for [SurviveJS - React](http://survivejs.com/react/introduction/)",
  "scripts": {
    "stats": "webpack --profile --json > stats.json",
    "start": "webpack-dev-server",
    "deploy": "gh-pages -d build",
    "build": "webpack",
    "test": "karma start",
    "test:tdd": "npm run test -- --auto-watch --no-single-run",
    "test:lint": "eslint ./app ./tests --ext .js --ext .jsx --ignore-path .gitignore --ignore-pattern dist --cache"
  },
  "keywords": [],
  "author": "",
  "license": "MIT",
  "dependencies": {
    "babel-core": "^6.9.0",
    "babel-eslint": "^6.0.4",
    "babel-loader": "^6.2.4",
    "babel-preset-es2015": "^6.9.0",
    "babel-preset-react": "^6.5.0",
    "babel-preset-react-hmre": "^1.1.1",
    "babel-preset-survivejs-kanban": "^0.3.3",
    "bootstrap": "3.3.7",
    "bootstrap-v4-dev": "4.0.0-alpha.6",
    "clean-webpack-plugin": "0.1.17",
    "css-loader": "^0.23.1",
    "eslint": "2.10.2",
    "eslint-loader": "^1.3.0",
    "eslint-plugin-react": "^5.1.1",
    "expose-loader": "^0.7.1",
    "extract-text-webpack-plugin": "1.0.1",
    "gh-pages": "^0.11.0",
    "html-webpack-plugin": "2.30.1",
    "html-webpack-template": "5.6.2",
    "isparta-instrumenter-loader": "^1.0.0",
    "jasmine": "2.6.0",
    "jasmine-core": "2.6.2",
    "jquery": "3.2.1",
    "karma": "^0.13.22",
    "karma-coverage": "^1.0.0",
    "karma-jasmine": "1.1.0",
    "karma-mocha": "^1.0.1",
    "karma-phantomjs-launcher": "^1.0.0",
    "karma-sourcemap-loader": "^0.3.7",
    "karma-spec-reporter": "0.0.26",
    "karma-webpack": "^1.7.0",
    "lodash": "4.17.4",
    "mocha": "^2.5.2",
    "node-sass": "4.5.3",
    "npm-install-webpack-plugin": "4.0.0",
    "phantomjs-polyfill": "0.0.2",
    "phantomjs-prebuilt": "^2.1.7",
    "react": "15.4.2",
    "react-dom": "15.4.2",
    "react-perf": "1.0.1",
    "react-router": "4.2.0",
    "react-router-dom": "4.2.2",
    "sass-loader": "6.0.6",
    "style-loader": "^0.13.1",
    "webpack": "3.0.0",
    "webpack-dev-server": "^1.14.1",
    "webpack-merge": "0.13.0",
    "webpack-validator": "2.3.0"
  }
}

Just to be clear, I followed the suggestion from #533 and did the following:

    169        new webpack.HotModuleReplacementPlugin({
    170 -        multiStep: true
    171 +        multiStep: false

Working for me, now.

This issue had no activity for at least half a year. It's subject to automatic issue closing if there is no activity in the next 15 days.

I've just tried html-webpack-plugin alpha version and HMR is still broken with multiStep: true option.

Any plans to fix it?

This issue has been automatically locked since there has not been any recent activity after it was closed. Please open a new issue for related bugs.

Was this page helpful?
0 / 5 - 0 ratings

Related issues

MatthewKosloski picture MatthewKosloski  Â·  3Comments

azat-io picture azat-io  Â·  4Comments

lonelyclick picture lonelyclick  Â·  3Comments

lcxfs1991 picture lcxfs1991  Â·  4Comments

var-bp picture var-bp  Â·  3Comments