node.jswebpackaureliahapi.jswebpack-hot-middleware

webpack-hot-middleware throws error on HMR update - status.hot is undefined (cannot read property 'status' of undefined)


This is driving me nuts. I'm trying to set up HMR with hapi/hapi-webpack-plugin and webpack-hot-middleware. My set up is an APS.NE MVC 5 application (serving the data) and Aurelia as a front-end framework.

HMR seems to start properly: enter image description here

Then when I make a change on any of my js/html files a rebuild is fired properly, again: enter image description here

but I'm receiving an error in process-update.js where module.hot is undefined and naturally it will error out when it checks for module.hot.status()

enter image description here

Here are the relevant files: webpack-dev-server.js

/* eslint no-console: 0 */
import {Server} from 'hapi';
import H2o2 from 'h2o2';
import yargs from 'yargs';
import Webpack from 'webpack';
import WebpackPlugin from 'hapi-webpack-plugin';
import webpackConfig from './webpack.config.babel';

const argv = yargs.argv;

const isNumeric = n => !isNaN(parseFloat(n)) && isFinite(n);

if (!isNumeric(argv.port)) {
	console.log(`Port must be numeric`);
	process.exit(-1);
}

const compiler = new Webpack(webpackConfig);

const server = new Server();

server.connection({ host: 'localhost', port: 6789, labels: 'proxy-server' });

const assets = {
	publicPath: webpackConfig.output.publicPath,
	hot: false,
	noInfo: true,
	quiet: false,
	host: 'localhost',
	port: 6790,
	stats: {
		colors: true,
	},
};

const hot = {
	log: console.log,
	path: '/__webpack_hmr',
	heartbeat: 10 * 1000,
};

server.register([
  {
  	register: H2o2,
  },
  {
  	register: WebpackPlugin,
  	options: { compiler, assets, hot },
  },
], error => {
	if (error) {
		return console.error(error);
	}

	server.route({
		method: ['GET', 'POST'],
		path: '/{path*}',
		handler: (request, reply) => {
			if (/^Content\/bundles\/[A-Za-z0-9\-]+\.css/.test(request.params.path)) {
				const response = reply('// This is a fake CSS content... :)');
				response.type('text/css');
				return response;
			}

			return reply.proxy({
				host: 'localhost',
				port: argv.port,
				passThrough: true,
			});
		},
	});

	server.start(() => console.log(`Server running on ${server.info.uri}`));
});

Package.json

{
  "name": "aurelia-skeleton-navigation-webpack",
  "version": "1.1.1",
  "description": "A starter kit for building a standard navigation-style app with Aurelia and webpack.",
  "main": "dist/main.js",
    "scripts": {
       ...
        "start": "babel-node ./webpack-dev-server.js"
       ...
    },
  
  ],
 

  "aurelia": {
    "build": {
      "resources": []
    }
  },
  "dependencies": {
    "aurelia-bootstrapper-webpack": "^1.1.0",
    "aurelia-event-aggregator": "^1.0.0",
    "aurelia-fetch-client": "^1.0.1",
    "aurelia-framework": "^1.0.7",
    "aurelia-history-browser": "^1.0.0",
    "aurelia-http-client": "^1.0.3",
    "aurelia-loader-webpack": "^1.0.3",
    "aurelia-logging-console": "^1.0.0",
    "aurelia-pal-browser": "^1.0.0",
    "aurelia-polyfills": "^1.1.1",
    "aurelia-route-recognizer": "^1.1.0",
    "aurelia-router": "^1.0.7",
    "aurelia-templating-binding": "^1.1.0",
    "aurelia-templating-resources": "^1.2.0",
    "aurelia-templating-router": "^1.0.0",
    "aurelia-ui-virtualization": "1.0.0-beta.3.0.0",
    "babel-polyfill": "^6.20.0",
    "bootstrap": "^3.3.7",
    "d3": "^4.4.0",
    "font-awesome": "^4.7.0",
    "highcharts": "^5.0.6",
    "isomorphic-fetch": "^2.2.1",
    "select2": "3.5.1"
  },
    "devDependencies": {
        "@easy-webpack/config-aurelia": "^2.2.2",
        "@easy-webpack/config-babel": "^4.0.0",
        "@easy-webpack/config-common-chunks-simple": "^2.0.3",
        "@easy-webpack/config-copy-files": "^1.1.2",
        "@easy-webpack/config-css": "^4.0.0",
        "@easy-webpack/config-env-development": "^2.1.5",
        "@easy-webpack/config-env-production": "^3.0.0",
        "@easy-webpack/config-external-source-maps": "^3.1.0",
        "@easy-webpack/config-fonts-and-images": "^2.1.0",
        "@easy-webpack/config-generate-index-html": "^2.1.1",
        "@easy-webpack/config-global-bluebird": "^2.1.0",
        "@easy-webpack/config-global-jquery": "^2.1.0",
        "@easy-webpack/config-global-regenerator": "^1.2.2",
        "@easy-webpack/config-html": "^3.1.0",
        "@easy-webpack/config-json": "^3.1.0",
        "@easy-webpack/config-test-coverage-istanbul": "^3.2.0",
        "@easy-webpack/config-uglify": "^2.2.3",
        "@easy-webpack/core": "^2.0.0",
        "aurelia-tools": "^1.0.0",
        "babel-cli": "^6.4.5",
        "babel-loader": "^6.2.8",
        "babel-plugin-transform-class-properties": "^6.18.0",
        "babel-plugin-transform-decorators-legacy": "^1.3.4",
        "babel-preset-env": "^1.0.0",
        "babel-register": "^6.18.0",
        "concurrently": "^3.1.0",
        "cross-env": "^3.1.3",
        "del-cli": "^0.2.0",
        "eslint": "^3.12.0",
        "extract-text-webpack-plugin": "^1.0.1",
        "file-loader": "^0.8.5",
        "h2o2": "^5.4.0",
        "hapi": "^16.0.2",
        "hapi-webpack-plugin": "^1.3.0",
        "html-webpack-plugin": "^2.24.1",
        "http-server": "^0.9.0",
        "install": "^0.8.2",
        "jasmine-core": "^2.5.2",
        "karma": "^1.3.0",
        "karma-chrome-launcher": "^2.0.0",
        "karma-coverage": "^1.1.1",
        "karma-jasmine": "^1.0.2",
        "karma-mocha-reporter": "^2.2.0",
        "karma-remap-istanbul": "^0.2.1",
        "karma-sourcemap-loader": "^0.3.7",
        "karma-webpack": "^1.8.0",
        "node-sass": "^4.1.0",
        "npm": "^4.0.3",
        "optimize-css-assets-webpack-plugin": "^1.3.0",
        "postcss-cssnext": "^2.9.0",
        "postcss-import": "^9.0.0",
        "postcss-loader": "^1.2.1",
        "protractor": "^4.0.11",
        "sass-loader": "^4.1.0",
        "url-loader": "^0.5.7",
        "wait-on": "^2.0.1",
        "webpack": "2.1.0-beta.27",
        "webpack-dev-server": "2.1.0-beta.12",
        "yargs": "^3.32.0",
        "babel-preset-es2015": "^6.3.13",
        "bootstrap": "^3.3.6",
        "clean-webpack-plugin": "^0.1.8",
        "css-loader": "^0.23.1",
        "font-awesome": "^4.5.0",
        "strip-loader": "^0.1.2",
        "style-loader": "^0.13.0"
    }
}

webpack.confing.babel.js

/**
 * To learn more about how to use Easy Webpack
 * Take a look at the README here: https://github.com/easy-webpack/core
 **/
import { generateConfig, get, stripMetadata, EasyWebpackConfig } from '@easy-webpack/core'
import path from 'path'

  ...
process.env.BABEL_ENV = 'webpack';
const ENV = process.env.NODE_ENV && process.env.NODE_ENV.toLowerCase() || (process.env.NODE_ENV = 'development');
// basic configuration:
const title = 'Aurelia Navigation Skeleton';
const baseUrl = '.';
const rootDir = path.resolve();
const srcDir = path.resolve('src');
const outDir = path.resolve('dist');


let htmlWebPackPlugin = new HtmlWebpackPlugin({
	inject: false,
	template: 'Areas/Aurelia/Views/Shared/_AureliaLayoutTemplate.cshtml',
	filename: '../Areas/Aurelia/Views/Shared/_AureliaLayout.cshtml'
});

let optimizeCssAssetsPlugin = new OptimizeCssAssetsPlugin({
	assetNameRegExp: /\.css$/,
	cssProcessorOptions: { discardComments: { removeAll: true } }
});
let plugins = ENV === 'production'
	? { plugins: [htmlWebPackPlugin, optimizeCssAssetsPlugin] }
	: { plugins: [htmlWebPackPlugin, new webpack.HotModuleReplacementPlugin(),  new webpack.NoErrorsPlugin() ] };

const coreBundles = {
	bootstrap: [
	  'aurelia-bootstrapper-webpack',
	  'aurelia-polyfills',
	  'aurelia-pal',
	  'aurelia-pal-browser',
	  'regenerator-runtime'

	],
	// these will be included in the 'aurelia' bundle (except for the above bootstrap packages)
	aurelia: [
	  'aurelia-bootstrapper-webpack',
	  'aurelia-binding',
	  'aurelia-dependency-injection',
	  'aurelia-event-aggregator',
	  'aurelia-framework',
	  'aurelia-history',
	  'aurelia-history-browser',
	  'aurelia-loader',
	  'aurelia-loader-webpack',
	  'aurelia-logging',
	  'aurelia-logging-console',
	  'aurelia-metadata',
	  'aurelia-pal',
	  'aurelia-pal-browser',
	  'aurelia-path',
	  'aurelia-polyfills',
	  'aurelia-route-recognizer',
	  'aurelia-router',
	  'aurelia-task-queue',
	  'aurelia-templating',
	  'aurelia-templating-binding',
	  'aurelia-templating-router',
	  'aurelia-templating-resources',
	  'aurelia-ui-virtualization',
	  'select2',
	  'webpack-hot-middleware/client',
	  'webpack/hot/only-dev-server'
	]
}

/**
 * Main Webpack Configuration
 */
let config = generateConfig(
	{
		entry: {
			'app': ['./src/main' /* this is filled by the aurelia-webpack-plugin */,
	  'webpack-hot-middleware/client',
	  'webpack/hot/only-dev-server'],
			'aurelia-bootstrap': coreBundles.bootstrap,
			'aurelia': coreBundles.aurelia.filter(pkg => coreBundles.bootstrap.indexOf(pkg) === -1)
		},
		output: {
			path: outDir,
			publicPath: '/dist/'
		},
	...

module.exports = stripMetadata(config);

Am I missing something in the config that leaves module.hot property undefined?


Solution

  • I'm answering my own question for posterity:

    This is related to my other question:

    Aurelia, running webpack-dev-server --hot throws error on App Hot Update - 'Cannot read property 'status' of undefined'

    In short, Aurelia doesn't support HMR ... yet (only css).

    https://github.com/aurelia/skeleton-navigation/issues/629

    http://blog.aurelia.io/2016/12/08/big-aurelia-release-update/