Skip to content
This repository was archived by the owner on Apr 8, 2020. It is now read-only.
This repository was archived by the owner on Apr 8, 2020. It is now read-only.

HMR no longer working when upgraded to latest version #725

Closed
@ttcg

Description

@ttcg

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.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions