Angular-cli: I need to save templates twice for refreshing

Created on 14 Mar 2018  路  5Comments  路  Source: angular/angular-cli

Versions

$ node --version
v8.9.4
$ yarn --version
1.5.1
$ npm --version
5.6.0
Windows 10 Professional x64

Repro steps

  • Step 1: scaffold project using our company's custom template
  • Step 2: run yarn start (which starts webpack-dev-server)
  • Step 3: make a change to a HTML or CSS file
  • Step 4: save the file

Observed behavior

The console shows that webpack is triggering a recompile (see screenshot below), but claims "App is up to date." and does not show the changes I made.
2018-03-14 13_20_13-gcdb

Pressing save again triggers another compilation which does a full page reload and applies the changes (see screenshot below)
2018-03-14 13_18_47-gcdb

Desired behavior

This behaviour prohibits me from using PHPStorm, since PHPStorm refuses to save a file that wasn't changed, and in general it's rather annoying having to press save twice to see my changes.

Mention any other details that might be useful (optional)

As mentioned, we aren't using Angular CLI, but a custom template (of which I will provide configuration files below, feel free to ask more details when needed), and the problem started occurring when we switched to AOT compilation.

I found similiar issues like https://github.com/angular/angular-cli/issues/9866 and https://github.com/angular/angular-cli/issues/5870

The problem is also very consistent, the first save triggers a compilation that reports nothing changed (despite running for 1-2s) and the second save will trigger a compilation that will effectively reload and show the made changes.
Generally typescript changes seem to reload instantly, but for changes to HTML and CSS I need to save twice.
Not sure if this is relevant too, but we have the HTML and CSS in separate files (as opposed to inline in the decorator).

The webpack configuration used:

const path = require('path');
const webpack = require('webpack');
const HtmlWebpackPlugin = require('html-webpack-plugin');
const ExtractTextPlugin = require('extract-text-webpack-plugin');
const AngularCompilerPlugin = require('@ngtools/webpack').AngularCompilerPlugin;

const root = path.resolve(__dirname, '..');
const sources = path.resolve(root, 'src', 'app');

module.exports = {
    entry: {
        'app': path.resolve(root, 'src', 'index.ts')
    },
    resolve: {
        extensions: ['.ts', '.js'],
        alias: {
            'WorldContainerDb': sources
        }
    },
    module: {
        rules: [
            {
                test: /\.ts$/,
                enforce: 'pre',
                loader: 'tslint-loader',
                options: {
                    configFile: path.resolve(root, 'tslint.json'),
                    tsConfigFile: path.resolve(root, 'tsconfig.json'),
                    typeCheck: true,
                }
            },
            {
                test: /\.ts$/,
                use: '@ngtools/webpack',
            },
            {
                test: /\.html$/,
                loader: 'html-loader'
            },
            {
                test: /\.(png|jpe?g|gif|svg|woff|woff2|ttf|eot|ico)$/,
                loader: 'file-loader',
                options: {
                    name: 'assets/[name].[hash].[ext]'
                }
            },
            {
                test: /\.css$/,
                include: [path.resolve(root, 'node_modules'), path.resolve(sources, 'shared', 'css')],
                loader: ExtractTextPlugin.extract('css-loader?sourceMap')
            },
            {
                test: /\.css$/,
                include: [sources],
                exclude: path.resolve(sources, 'shared', 'css'),
                loader: 'raw-loader'
            },
            {
                test: /\.json$/,
                loader: 'file-loader',
                options: {
                    name: 'assets/[name].[ext]'
                }
            },
        ]
    },
    plugins: [
        // Workaround for angular/angular#11580
        new webpack.ContextReplacementPlugin(
            // The (\\|\/) piece accounts for path separators in *nix and Windows
            /(.+)?angular(\\|\/)core(.+)?/,
            sources, // location of your src
            {} // a map of your routes
        ),
        new webpack.optimize.CommonsChunkPlugin({
            name: 'vendor',
            minChunks: (module, count) => {
                return module.resource && (/node_modules/).test(module.resource);
            },
        }),
        new webpack.optimize.OccurrenceOrderPlugin(),
        new HtmlWebpackPlugin({
            template: 'index.html'
        }),
        new AngularCompilerPlugin({
            tsConfigPath: path.join(root, 'tsconfig.json'),
            sourceMap: true
        }),
    ]
};

our Typescript configuration:

{
    "compilerOptions": {
        "target": "es5",
        "module": "commonjs",
        "moduleResolution": "node",
        "sourceMap": true,
        "strictPropertyInitialization": false,
        "emitDecoratorMetadata": true,
        "experimentalDecorators": true,
        "lib": [ "es2015", "dom" ],
        "noImplicitAny": false,
        "suppressImplicitAnyIndexErrors": true,
        "typeRoots": [ "./node_modules/@types" ],
        "types": [ "node" ],
        "baseUrl": ".",
        "outDir": "dist",
        "paths": {
            "projectName/*": [ "src/app/*" ]
        }
    },
    "angularCompilerOptions": {
        "preserveWhitespaces": false,
        "entryModule": "src/app/app.module#AppModule"
    }
}

Apologies for the long post.
I can't make a git repository for our template (since it uses internal tooling) but if required I am willing to send a zip with a generated project through mail.

devkibuild-angular

Most helpful comment

Hey all! We had the same problem in NativeScript. We fixed it by applying the @ngtools/webpack loader to the ngfactory and ngstyle files:
before

{
    test: /\.ts$/,
    use: [
        "@ngtools/webpack",
    ]
}

after

{
    test: /(?:\.ngfactory\.js|\.ngstyle\.js|\.ts)$/,
    use: [
        "@ngtools/webpack",
    ]
}

All 5 comments

I am suffering from the same issue. Also using @ngtools/webpack

Hey all! We had the same problem in NativeScript. We fixed it by applying the @ngtools/webpack loader to the ngfactory and ngstyle files:
before

{
    test: /\.ts$/,
    use: [
        "@ngtools/webpack",
    ]
}

after

{
    test: /(?:\.ngfactory\.js|\.ngstyle\.js|\.ts)$/,
    use: [
        "@ngtools/webpack",
    ]
}

@sis0k0 you sir are a lifesaver. Your fix works perfectly. Thank you! :beers: :beers:

@sis0k0's solution is indeed the correct one. At the moment we have already updated the usage instructions in https://github.com/angular/angular-cli/blob/master/packages/ngtools/webpack/README.md to reflect this.

This issue has been automatically locked due to inactivity.
Please file a new issue if you are encountering a similar or related problem.

Read more about our automatic conversation locking policy.

_This action has been performed automatically by a bot._

Was this page helpful?
0 / 5 - 0 ratings

Related issues

rajjejosefsson picture rajjejosefsson  路  3Comments

hartjo picture hartjo  路  3Comments

NCC1701M picture NCC1701M  路  3Comments

IngvarKofoed picture IngvarKofoed  路  3Comments

jmurphzyo picture jmurphzyo  路  3Comments