HMR no longer working when upgraded to latest version #972

Closed
opened 2025-08-09 17:18:22 +00:00 by fergalmoran · 0 comments
Owner

Originally created by @ttcg on 3/1/2017

Firstly, this project is based on famous .Net Core and ng2 template for Visual Studio 2015 Link to VS 2015 Template Tutorial

The problem started when I decided to upgrade all libraries to latest version (@angular:^2.4.8 and WebPack:^2.2.1). I got so many errors coz of major breaking changes in this upgrade journey. I managed to sort out almost all and got the app up and running as usual except this final issue.

It doesn't load the changes anymore by using HotModuleReplacement (HMR). All the changes reflect on the page, when I refresh (F5) on the browser. It just stops automatic updating.

Image1

We can see here that it does know the changes, compiled and returned the latest (correct) html codes, but it couldn't load it back on the page.

Image2

I have double checked that the new file is generated for 'dist/main-client.js' and it is re-generated every time I change something in html/ts file. However, it keeps saying that Selector 'app' did not match any elements.

webpack.config.vendor.js

I have included aspnet-prerendering in the vendor entry.

var isDevBuild = process.argv.indexOf('--env.prod') < 0;
var path = require('path');
var webpack = require('webpack');
const ContextReplacementPlugin = require('webpack/lib/ContextReplacementPlugin');
var ExtractTextPlugin = require('extract-text-webpack-plugin');

module.exports = {
    resolve: {
        extensions: [ '*', '.js' ]
    },
    module: {
        loaders: [
            { test: /\.(png|woff|woff2|eot|ttf|svg)(\?|$)/, loader: 'url-loader?limit=100000' },
            { test: /\.css(\?|$)/, loader: ExtractTextPlugin.extract("css-loader") }
        ]
    },
    entry: {
        vendor: [
            '@angular/common',
            '@angular/compiler',
            '@angular/core',
            '@angular/http',
            '@angular/platform-browser',
            '@angular/platform-browser-dynamic',
            '@angular/router',
            '@angular/platform-server',
            'angular2-universal',
            'angular2-universal-polyfills',
            'bootstrap',
            'bootstrap/dist/css/bootstrap.css',
            'es6-shim',
            'es6-promise',
            'jquery',
            'zone.js',
            'aspnet-prerendering' 
        ]
    },
    output: {
        path: path.join(__dirname, 'wwwroot', 'dist'),
        filename: '[name].js',
        library: '[name]_[hash]',
    },
    plugins: [
        //extractCSS,
        new ExtractTextPlugin({
            filename: "vendor.css",
            allChunks: true
        }),
        new webpack.ProvidePlugin({ $: 'jquery', jQuery: 'jquery' }), // Maps these identifiers to the jQuery package (because Bootstrap expects it to be a global variable)
        new webpack.optimize.OccurrenceOrderPlugin(),
        new webpack.ContextReplacementPlugin(/\@angular\b.*\b(bundles|linker)/, path.join(__dirname, './Client')), // Workaround for https://github.com/angular/angular/issues/11580
        new webpack.DllPlugin({
            path: path.join(__dirname, 'wwwroot', 'dist', '[name]-manifest.json'),
            name: '[name]_[hash]'
        })
    ].concat(isDevBuild ? [] : [
        new webpack.optimize.UglifyJsPlugin({ compress: { warnings: false } })
    ])
};

webpack.config.js

var isDevBuild = process.argv.indexOf('--env.prod') < 0;
var path = require('path');
var webpack = require('webpack');
var nodeExternals = require('webpack-node-externals');
var merge = require('webpack-merge');
var allFilenamesExceptJavaScript = /\.(?!js(\?|$))([^.]+(\?|$))/;

// Configuration in common to both client-side and server-side bundles
var sharedConfig = {
    resolve: { extensions: [ '.js', '.ts' ] },
    output: {
        filename: '[name].js',
        publicPath: '/dist/' // Webpack dev middleware, if enabled, handles requests for this URL prefix
    },
    module: {
        loaders: [
            {   // TypeScript files
                test: /\.ts$/,
                include: /ClientApp/,
                exclude: [/\.(spec|e2e)\.ts$/], // Exclude test files | end2end test spec files etc
                loaders: [
                    'awesome-typescript-loader?silent=true', // Amazing TS loader
                    'angular2-template-loader'   // Handles templateUrl stylesUrl and automatically just inserts them into the template|styles
                                                // instead of having the module resource loader handle it
                ]
            },
            { test: /\.html$/, loader: 'raw-loader' },
            { test: /\.css$/, loader: 'raw-loader' },
            { test: /\.(png|jpg|jpeg|gif|svg)$/, loader: 'url-loader', query: { limit: 25000 } }
        ]
    }
};

// Configuration for client-side bundle suitable for running in browsers
var clientBundleConfig = merge(sharedConfig, {
    entry: { 'main-client': './ClientApp/boot-client.ts' },
    output: { path: path.join(__dirname, './wwwroot/dist') },
    devtool: isDevBuild ? 'inline-source-map' : null,
    plugins: [
        new webpack.DllReferencePlugin({
            context: __dirname,
            manifest: require('./wwwroot/dist/vendor-manifest.json')
        })
    ].concat(isDevBuild ? [] : [
        // Plugins that apply in production builds only
        new webpack.optimize.OccurenceOrderPlugin(),
        new webpack.optimize.UglifyJsPlugin()
    ])
});

// Configuration for server-side (prerendering) bundle suitable for running in Node
var serverBundleConfig = merge(sharedConfig, {
    entry: { 'main-server': './ClientApp/boot-server.ts' },    
    output: {
        libraryTarget: 'commonjs',
        path: path.join(__dirname, './ClientApp/dist')
    },
    target: 'node',
    devtool: 'inline-source-map',
    externals: [nodeExternals({ whitelist: [allFilenamesExceptJavaScript] })] // Don't bundle .js files from node_modules
});

module.exports = [clientBundleConfig, serverBundleConfig];

boot-server.ts

import 'angular2-universal-polyfills';
import 'zone.js';
import './__2.1.1.workaround.ts'; // temporary until 2.1.1 things are patched in Core

import { enableProdMode } from '@angular/core';
import { platformNodeDynamic } from 'angular2-universal';
import { AppModule } from './app/app.module';

enableProdMode();

const platform = platformNodeDynamic();

import { createServerRenderer, RenderResult  } from 'aspnet-prerendering';

export default createServerRenderer(params => {

    const doc = '<app></app>';

    return new Promise((resolve, reject) => {
        const requestZone = Zone.current.fork({
            name: 'angular-universal request',
            properties: {
                baseUrl: '/',
                ngModule: AppModule,
                requestUrl: params.url,
                originUrl: params.origin,
                preboot: false,
                // TODO: Render just the <app> component instead of wrapping it inside an extra HTML document
                // Waiting on https://github.com/angular/universal/issues/347
                document: '<!DOCTYPE html><html><head></head><body><app></app></body></html>'
            },
            onHandleError: (parentZone, currentZone, targetZone, error) => {
                // If any error occurs while rendering the module, reject the whole operation
                reject(error);
                return true;
            }
        });

        return requestZone.run<Promise<string>>(() => platform.serializeModule(AppModule)).then(html => {
            resolve({ html: html });
        }, reject);
    });
});

Could you guys please help me to make it work again? Everything except this feature is missing after the upgrade.

*Originally created by @ttcg on 3/1/2017* Firstly, this project is based on famous .Net Core and ng2 template for Visual Studio 2015 [Link to VS 2015 Template Tutorial](http://blog.stevensanderson.com/2016/10/04/angular2-template-for-visual-studio/) The problem started when I decided to upgrade all libraries to latest version (@angular:^2.4.8 and WebPack:^2.2.1). I got so many errors coz of major breaking changes in this upgrade journey. I managed to sort out almost all and got the app up and running as usual except this final issue. It doesn't load the changes anymore by using HotModuleReplacement (HMR). All the changes reflect on the page, when I refresh (F5) on the browser. It just stops automatic updating. ![Image1](https://i.stack.imgur.com/o3cD5.png) We can see here that it does know the changes, compiled and returned the latest (correct) html codes, but it couldn't load it back on the page. ![Image2](https://i.stack.imgur.com/jp3N3.png) I have double checked that the new file is generated for 'dist/main-client.js' and it is re-generated every time I change something in html/ts file. However, it keeps saying that Selector 'app' did not match any elements. **webpack.config.vendor.js** I have included aspnet-prerendering in the vendor entry. ``` var isDevBuild = process.argv.indexOf('--env.prod') < 0; var path = require('path'); var webpack = require('webpack'); const ContextReplacementPlugin = require('webpack/lib/ContextReplacementPlugin'); var ExtractTextPlugin = require('extract-text-webpack-plugin'); module.exports = { resolve: { extensions: [ '*', '.js' ] }, module: { loaders: [ { test: /\.(png|woff|woff2|eot|ttf|svg)(\?|$)/, loader: 'url-loader?limit=100000' }, { test: /\.css(\?|$)/, loader: ExtractTextPlugin.extract("css-loader") } ] }, entry: { vendor: [ '@angular/common', '@angular/compiler', '@angular/core', '@angular/http', '@angular/platform-browser', '@angular/platform-browser-dynamic', '@angular/router', '@angular/platform-server', 'angular2-universal', 'angular2-universal-polyfills', 'bootstrap', 'bootstrap/dist/css/bootstrap.css', 'es6-shim', 'es6-promise', 'jquery', 'zone.js', 'aspnet-prerendering' ] }, output: { path: path.join(__dirname, 'wwwroot', 'dist'), filename: '[name].js', library: '[name]_[hash]', }, plugins: [ //extractCSS, new ExtractTextPlugin({ filename: "vendor.css", allChunks: true }), new webpack.ProvidePlugin({ $: 'jquery', jQuery: 'jquery' }), // Maps these identifiers to the jQuery package (because Bootstrap expects it to be a global variable) new webpack.optimize.OccurrenceOrderPlugin(), new webpack.ContextReplacementPlugin(/\@angular\b.*\b(bundles|linker)/, path.join(__dirname, './Client')), // Workaround for https://github.com/angular/angular/issues/11580 new webpack.DllPlugin({ path: path.join(__dirname, 'wwwroot', 'dist', '[name]-manifest.json'), name: '[name]_[hash]' }) ].concat(isDevBuild ? [] : [ new webpack.optimize.UglifyJsPlugin({ compress: { warnings: false } }) ]) }; ``` **webpack.config.js** ``` var isDevBuild = process.argv.indexOf('--env.prod') < 0; var path = require('path'); var webpack = require('webpack'); var nodeExternals = require('webpack-node-externals'); var merge = require('webpack-merge'); var allFilenamesExceptJavaScript = /\.(?!js(\?|$))([^.]+(\?|$))/; // Configuration in common to both client-side and server-side bundles var sharedConfig = { resolve: { extensions: [ '.js', '.ts' ] }, output: { filename: '[name].js', publicPath: '/dist/' // Webpack dev middleware, if enabled, handles requests for this URL prefix }, module: { loaders: [ { // TypeScript files test: /\.ts$/, include: /ClientApp/, exclude: [/\.(spec|e2e)\.ts$/], // Exclude test files | end2end test spec files etc loaders: [ 'awesome-typescript-loader?silent=true', // Amazing TS loader 'angular2-template-loader' // Handles templateUrl stylesUrl and automatically just inserts them into the template|styles // instead of having the module resource loader handle it ] }, { test: /\.html$/, loader: 'raw-loader' }, { test: /\.css$/, loader: 'raw-loader' }, { test: /\.(png|jpg|jpeg|gif|svg)$/, loader: 'url-loader', query: { limit: 25000 } } ] } }; // Configuration for client-side bundle suitable for running in browsers var clientBundleConfig = merge(sharedConfig, { entry: { 'main-client': './ClientApp/boot-client.ts' }, output: { path: path.join(__dirname, './wwwroot/dist') }, devtool: isDevBuild ? 'inline-source-map' : null, plugins: [ new webpack.DllReferencePlugin({ context: __dirname, manifest: require('./wwwroot/dist/vendor-manifest.json') }) ].concat(isDevBuild ? [] : [ // Plugins that apply in production builds only new webpack.optimize.OccurenceOrderPlugin(), new webpack.optimize.UglifyJsPlugin() ]) }); // Configuration for server-side (prerendering) bundle suitable for running in Node var serverBundleConfig = merge(sharedConfig, { entry: { 'main-server': './ClientApp/boot-server.ts' }, output: { libraryTarget: 'commonjs', path: path.join(__dirname, './ClientApp/dist') }, target: 'node', devtool: 'inline-source-map', externals: [nodeExternals({ whitelist: [allFilenamesExceptJavaScript] })] // Don't bundle .js files from node_modules }); module.exports = [clientBundleConfig, serverBundleConfig]; ``` **boot-server.ts** ``` import 'angular2-universal-polyfills'; import 'zone.js'; import './__2.1.1.workaround.ts'; // temporary until 2.1.1 things are patched in Core import { enableProdMode } from '@angular/core'; import { platformNodeDynamic } from 'angular2-universal'; import { AppModule } from './app/app.module'; enableProdMode(); const platform = platformNodeDynamic(); import { createServerRenderer, RenderResult } from 'aspnet-prerendering'; export default createServerRenderer(params => { const doc = '<app></app>'; return new Promise((resolve, reject) => { const requestZone = Zone.current.fork({ name: 'angular-universal request', properties: { baseUrl: '/', ngModule: AppModule, requestUrl: params.url, originUrl: params.origin, preboot: false, // TODO: Render just the <app> component instead of wrapping it inside an extra HTML document // Waiting on https://github.com/angular/universal/issues/347 document: '<!DOCTYPE html><html><head></head><body><app></app></body></html>' }, onHandleError: (parentZone, currentZone, targetZone, error) => { // If any error occurs while rendering the module, reject the whole operation reject(error); return true; } }); return requestZone.run<Promise<string>>(() => platform.serializeModule(AppModule)).then(html => { resolve({ html: html }); }, reject); }); }); ``` Could you guys please help me to make it work again? Everything except this feature is missing after the upgrade.
Sign in to join this conversation.
1 Participants
Notifications
Due Date
No due date set.
Dependencies

No dependencies set.

Reference: github/JavaScriptServices#972
No description provided.