Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Angular Application Doesn't load up App Module/Components after Upgrade to Angular 8.3.5

We have an Angular 4 project that I've recently tried to upgrade to Angular 8. I followed the migration guide in Angular website, changed some of the syntaxes, and everything preventing project to be built. I faced the problem of my styles were not loading properly locally and not at all on Azure. I found Webpack and tried to configure it, added style-loader, sass-loader, and css-loader. Now when I'm running locally, I can see in the network tab in the browser that all styles are loading properly, but it only loads the default index.html file and not bootstrapping the application.

When I deploy the app on Azure, it loads other components, but none of the styles are loading. I spent 3 weeks on migration, nothing promising yet.

Tools/Plugins version:

Angular CLI: 8.3.5
Node: 10.15.1
OS: win32 x64
Angular: 8.2.7
... animations, common, compiler, compiler-cli, core, forms
... language-service, platform-browser, platform-browser-dynamic
... platform-server, router

Package                           Version
-----------------------------------------------------------
@angular-devkit/architect         0.803.5
@angular-devkit/build-angular     0.803.5
@angular-devkit/build-optimizer   0.803.5
@angular-devkit/build-webpack     0.803.5
@angular-devkit/core              8.3.5
@angular-devkit/schematics        8.3.5
@angular/cdk                      8.2.0
@angular/cli                      8.3.5
@angular/http                     5.2.11
@angular/material                 8.2.0
@ngtools/webpack                  8.3.5
@schematics/angular               8.3.5
@schematics/update                0.803.5
rxjs                              6.5.3
typescript                        3.5.3
webpack                           4.40.2

Here is my Webpack config:

const { resolve } = require('path');
const rxPaths = require('rxjs/_esm5/path-mapping');
const CopyWebpackPlugin = require('copy-webpack-plugin');
const ProgressPlugin = require('webpack/lib/ProgressPlugin');
const CircularDependencyPlugin = require('circular-dependency-plugin');
const { AngularCompilerPlugin } = require('@ngtools/webpack');
const { IndexHtmlWebpackPlugin } = require('@angular-devkit/build-angular/src/angular-cli-files/plugins/index-html-webpack-plugin');

module.exports = {

  mode: 'development',

  devtool: 'eval',

  entry: {
    main: './src/main.ts',
    polyfills: './src/polyfills.ts',
    styles: './src/styles.scss'
  },

  output: {
    path: resolve('./dist/'),
    filename: '[name].js',
  },

  resolve: {
    extensions: ['.ts', '.js'],
    alias: rxPaths()
  },

  node: false,

  performance: {
    hints: false,
  },

  module: {
    rules: [
      {
        test: /\.ts$/,
        use: '@ngtools/webpack'
      },
      {
        test: /\.js$/,
        exclude: /(ngfactory|ngstyle).js$/,
        enforce: 'pre',
        use: 'source-map-loader'
      },
      {
        test: /\.html$/,
        use: 'raw-loader'
      },
      {
        test: /\.s[ac]ss$/i,
        use: ['sass-loader'],
        // use: ['to-string-loader, css-loader, sass-loader'],
        exclude: [resolve('./src/styles.scss')]
      },
      {
        test: /\.s[ac]ss$/i,
        // use: ['sass-loader'],
        include: [resolve('./src/styles.scss')]
      },
      {
        test: /\.(eot|svg|cur)$/,
        loader: 'file-loader',
        options: {
          name: `[name].[ext]`,
          limit: 10000
        }
      },
      {
        test: /\.(jpg|png|webp|gif|otf|ttf|woff|woff2|ani)$/,
        loader: 'url-loader',
        options: {
          name: `[name].[ext]`,
          limit: 10000
        }
      },

      // This hides some deprecation warnings that Webpack throws

      {
        test: /[\/\\]@angular[\/\\]core[\/\\].+\.js$/,
        parser: { system: true },
      }
    ]
  },

  plugins: [
    new IndexHtmlWebpackPlugin({
      input: 'index.html',
      output: 'index.html',
      inject: 'body',
      entrypoints: [
        'styles',
        'polyfills',
        'main'
      ]
    }),

    new AngularCompilerPlugin({
      mainPath: resolve('./src/main.ts'),
      sourceMap: true,
      nameLazyFiles: true,
      tsConfigPath: resolve('./src/tsconfig.app.json')
      // ,
      // skipCodeGeneration: true
    }),

    new ProgressPlugin(),

    new CircularDependencyPlugin({
      exclude: /[\\\/]node_modules[\\\/]/
    }),

    new CopyWebpackPlugin([
      {
        from: 'src/assets',
        to: 'assets'
      },
      {
        from: 'src/favicon.ico'
      }
    ])
  ]
};

Please note that the reason I've commented use[] in Webpack config was that it was throwing some postcss-loader exception and on an issue on Github found that some conflict will occur with default sass-loader and Webpack and you should remove them.

Here is the build config in angular.json

        "build": {
          "builder": "@angular-builders/custom-webpack:browser",
          "options": {
            "customWebpackConfig": {
              "path": "./webpack.config.js",
              "replaceDuplicatePlugins": true
            },
            "outputPath": "./dist/",
            "index": "src/index.html",
            "main": "src/main.ts",
            "tsConfig": "src/tsconfig.app.json",
            "polyfills": "src/polyfills.ts",
            "assets": [
              "src/assets",
              "src/config",
              "src/favicon.ico"
            ],
            "styles": [
              "./src/styles.scss"
            ],
            "scripts": [
              "node_modules/jquery/dist/jquery.min.js",
              "node_modules/bootstrap/dist/js/bootstrap.min.js",
              "node_modules/metismenu/dist/metisMenu.js",
              "node_modules/vis/dist/vis.min.js",
              "vendor/js/jvectormap/jquery-jvectormap-2.0.2.min.js",
              "vendor/js/jvectormap/jquery-jvectormap-us-mill.js",
              "vendor/js/iCheck/icheck.js",
              "node_modules/toastr/toastr.js"
            ]
          },
          "configurations": {
            "dev": {
              "optimization": true,
              "sourceMap": false,
              "extractCss": true,
              "namedChunks": false,
              "aot": true,
              "extractLicenses": true,
              "vendorChunk": false,
              "buildOptimizer": true,
              "fileReplacements": [
                {
                  "replace": "src/environments/environment.ts",
                  "with": "src/environments/environment.dev.ts"
                }
              ]
            },
            "local": {
              "optimization": true,
              "sourceMap": false,
              "extractCss": true,
              "namedChunks": false,
              "aot": true,
              "extractLicenses": true,
              "vendorChunk": false,
              "buildOptimizer": true
            },
            "production": {
              "optimization": true,
              "sourceMap": false,
              "extractCss": false,
              "namedChunks": false,
              "aot": true,
              "extractLicenses": true,
              "vendorChunk": false,
              "buildOptimizer": true,
              "fileReplacements": [
                {
                  "replace": "src/environments/environment.ts",
                  "with": "src/environments/environment.prod.ts"
                }
              ],
              "styles": [
                "./src/styles.scss"
              ]
            }
          }
        },

And here is the serve config in Angular.json.

"serve": {
          "builder": "@angular-builders/custom-webpack:dev-server",
          "options": {
            "browserTarget": "projectName:build",
            "customWebpackConfig": {
              "path": "./webpack.config.js"
            }
          },
          "configurations": {
            "local":{
              "browserTarget": "projectName:build:local"
            }
            ,
            "dev": {
              "browserTarget": "projectName:build:dev"
            },
            "production": {
              "browserTarget": "projectName:build:production"
            }
          }
        },

I have imported all styles in styles.scss using @import statements. Just one thing I am not sure about is that I'm using Highcharts and getting some warnings during the build.

WARNING in ./node_modules/angular2-highcharts/dist/index.js
Module Warning (from ./node_modules/source-map-loader/index.js):
(Emitted value instead of an instance of Error) Cannot find source file '../src/index.ts': Error: Can't resolve '../src/index.ts'

Other than these, there is not compile/runtime error in the project.

Thank you for taking the time to read my problem. I appreciate any hint/tip.

Update: This is how the project structure looks like:

|   .editorconfig
|   .gitignore
|   angular.json
|   browserslist
|   karma.conf.js
|   package-lock.json
|   package.json
|   protractor.conf.js
|   README.md
|   tsconfig.json
|   tslint.json
|   webpack.config.js
|          
+---src
|   |   favicon.ico
|   |   index.html
|   |   index.js
|   |   main.ts
|   |   polyfills.ts
|   |   styles.scss
|   |   test.ts
|   |   tsconfig.app.json
|   |   tsconfig.spec.json
|   |   typings.d.ts
|   |   webpack.config.common.js
|   |   
|   +---app       
|   +---assets
|   |   |
|   |   +---images
|   |   \---styles
|   |       |   style.scss
|   |       |   
|   |               
|   +---config
|   |       dev-config.js
|   |       local-config.js
|   |       prod-config.js
|   |       qa-config.js
|   |       
|   +---environments
|   |       environment.dev.ts
|   |       environment.prod.ts
|   |       environment.qa.ts
|   |       environment.ts
 
like image 922
Mustafa Mohammadi Avatar asked Sep 27 '19 04:09

Mustafa Mohammadi


2 Answers

The file index.ts is missing from the project it seems that the file index.js extension was changed from ts to js and it is looking for it as ts.

Try with changing the index.js extension with index.ts in the src folder.

like image 159
Hitech Hitesh Avatar answered Nov 13 '22 00:11

Hitech Hitesh


If I understood correctly, the main problem is that styles are not applied.

You are using Bootstrap files according to this row of your config: "node_modules/bootstrap/dist/js/bootstrap.min.js", however you have not imported this styles into final bundle. So try to write this into angular.json file:

"styles": [
          "node_modules/bootstrap/dist/css/bootstrap.min.css",
          "src/styles.scss"
],

In addition, you need to import bootstrap styles to use them in your application into style.scss file:

/* You can add global styles to this file, and also import other style files */
@import "~bootstrap/dist/css/bootstrap.css";

<!-- 
     h1, h2, h3 {
         margin-bottom: 1.5rem;
     } 
-->

UPDATE:

  1. Our app.module.ts should look like this after creating through Angular CLI:

    @NgModule({
        declarations: [
        AppComponent
        ],
        imports: [
            BrowserModule,
            AppRoutingModule
        ],
        providers: [],
        bootstrap: [AppComponent]
    })
    export class AppModule { }
    

Every application should have a start place. In Angular, we have a convention, that our application should start at AppModule. AppModule is our rout module. So we are telling to Angular that when it creates our root module(AppModule) at start that we want to set AppComponent as a starting point(bootstrap) into the DOM.

The code that will bootstrap your application placed into main.ts file:

import { enableProdMode } from '@angular/core';
import { platformBrowserDynamic } from '@angular/platform-browser-dynamic';

import { AppModule } from './app/app.module';
import { environment } from './environments/environment';

if (environment.production) {
  enableProdMode();
}

platformBrowserDynamic().bootstrapModule(AppModule)
  .catch(err => console.error(err));

The above code uses Just in Time compilation.

Let me show how index.html looks:

<!doctype html>
<html lang="en">
<head>
  <meta charset="utf-8">
  <title>Frontend</title>
  <base href="/">
  <meta name="viewport" content="width=device-width, initial-scale=1">
  <link rel="icon" type="image/x-icon" href="favicon.ico">
</head>
<body>
  <app-root></app-root>
</body>
</html>

Where <app-root></app-root> is a selector for app.component.ts:

import { Component } from '@angular/core';

@Component({
  selector: 'app-root',
  templateUrl: './app.component.html',
  styleUrls: ['./app.component.scss']
})
export class AppComponent {
  title = 'Frontend';
  test = {};
}

You can change the default page to show by replacing by the selector of your component in the index.html.

Double check your selector of app.component.html and selector used in in your index.html.

  1. Try to set projectName to your name of project in the serve section of angular.json file. For example, if your project is named as superappl, then you should write like this:

    serve": {
      "builder": "@angular-builders/custom-webpack:dev-server",
      "options": {
        "browserTarget": "superappl:build",
        "customWebpackConfig": {
          "path": "./webpack.config.js"
        }
      },
      "configurations": {
        "local":{
          "browserTarget": "superappl:build:local"
        }
        ,
        "dev": {
          "browserTarget": "superappl:build:dev"
        },
        "production": {
          "browserTarget": "superappl:build:production"
        }
      }
    },
    
  2. If above actions will not run your application. Then I suggest you to create new brand application using Angular CLI and compare your index.html file and app.module.ts files. Commands to create new brand application to compare your existing application (especially, package.json and angular.json files):

    npm install -g @angular/cli
    ng new angular-newapp --skip-install
    npm install @angular/core@latest
    npm install @angular/http@latest
    npm install
    ng serve
    

Some questions:

  1. Have you created manually Webpack.config? What's reason to use it? You can avoid using and tuning Webpack config if it is applicable to you. As Angular CLI by default does not create this file. You should manually write ng-eject command to get webpack file.

  2. Can you post your index.html and app.module.ts?

  3. Does your application work when you run your application locally? I mean when you run command ng serve?
like image 34
StepUp Avatar answered Nov 13 '22 00:11

StepUp