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.
Then when I make a change on any of my js/html files a rebuild is fired properly, again:
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()
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?
I'm answering my own question for posterity:
This is related to my other question:
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/