0

I'm working on an angular projet,

versions:

-Angular CLI: 8.3.29
-Node: 12.14.1
-Angular: 8.2.14

I need to apply side rendering on it, I used the following command to set up angular univeral on my project

npm install @nguniversal/express-engine --save

After solving lot of problems (building, flickering, double loading page...) I now can launch it on my local environment with

build:ssr && serve:ssr

But when i try do deploy it on a production server, after building the project on the production server when I try to start the server with node /dist/server/main.js

I got the following error

Error: Cannot find module 'zone.js/dist/zone-node'

I searched on forums and I found that I've to build my server side code with webpack

so I update my package.json to

"dev:ssr": "ng run my-app-name:serve-ssr",
"serve:ssr": "node dist/server.js",
"build:client-and-server-bundles": "ng build --prod && ng run my-app-name:server:production",
"build-wp:ssr": "npm run build:client-and-server-bundles && npm run webpack:server",
"webpack:server": "webpack --config webpack.server.config.js --progress --colors"

webpack.server.config.js

const path = require('path');
const webpack = require('webpack');

module.exports = {
  mode: 'none',
  entry: {
    // This is our Express server for Dynamic universal
    server: './server.ts'
  },
  externals: {
    './dist/server/main': 'require("./server/main")'
  },
  target: 'node',
  resolve: { extensions: ['.ts', '.js'] },
  optimization: {
    minimize: false
  },
  output: {
    // Puts the output at the root of the dist folder
    path: path.join(__dirname, 'dist'),
    filename: '[name].js'
  },
  module: {
    noParse: /polyfills-.*\.js/,
    rules: [
      { test: /\.ts$/, loader: 'ts-loader' },
      {
        // Mark files inside `@angular/core` as using SystemJS style dynamic imports.
        // Removing this will cause deprecation warnings to appear.
        test: /(\\|\/)@angular(\\|\/)core(\\|\/).+\.js$/,
        parser: { system: true },
      },
    ]
  },
  plugins: [
    new webpack.ContextReplacementPlugin(
      // fixes WARNING Critical dependency: the request of a dependency is an expression
      /(.+)?angular(\\|\/)core(.+)?/,
      path.join(__dirname, 'src'), // location of your src
      {} // a map of your routes
    ),
    new webpack.ContextReplacementPlugin(
      // fixes WARNING Critical dependency: the request of a dependency is an expression
      /(.+)?express(\\|\/)(.+)?/,
      path.join(__dirname, 'src'),
      {}
    )
  ]
};

server.ts

import 'zone.js/dist/zone-node';

import { ngExpressEngine } from '@nguniversal/express-engine';
import * as express from 'express';
import { join } from 'path';

import { AppServerModule } from './src/main.server';
import { APP_BASE_HREF } from '@angular/common';
import { existsSync } from 'fs';

// The Express app is exported so that it can be used by serverless Functions.
export function app(): express.Express {
  const server = express();
  const distFolder = join(process.cwd(), 'dist/browser');
  const indexHtml = existsSync(join(distFolder, 'index.original.html')) ? 'index.original.html' : 'index';


  const DIST_FOLDER = join(process.cwd(), 'dist');

  // Our Universal express-engine (found @ https://github.com/angular/universal/tree/master/modules/express-engine)
  server.engine('html', ngExpressEngine({
    bootstrap: AppServerModule,
  }));

  server.set('view engine', 'html');
  server.set('views', join(DIST_FOLDER, 'browser'));
  //server.set('views', distFolder);

  // Example Express Rest API endpoints
  // server.get('/api/**', (req, res) => { });
  // Serve static files from /browser
  server.get('*.*', express.static(distFolder, {
    maxAge: '1y'
  }));

  // All regular routes use the Universal engine
  server.get('*', (req, res) => {
    res.render(indexHtml, { req, providers: [{ provide: APP_BASE_HREF, useValue: req.baseUrl }] });
  });

  return server;
}

function run(): void {
  const port = process.env.PORT || 4200;

  // Start up the Node server
  const server = app();
  server.listen(port, () => {
    console.log(`Node Express server listening on http://localhost:${port}`);
  });
}

// Webpack will replace 'require' with '__webpack_require__'
// '__non_webpack_require__' is a proxy to Node 'require'
// The below code is to ensure that the server is run only when not requiring the bundle.
declare const __non_webpack_require__: NodeRequire;
const mainModule = __non_webpack_require__.main;
const moduleFilename = mainModule && mainModule.filename || '';
if (moduleFilename === __filename || moduleFilename.includes('iisnode')) {
  run();
}

export * from './src/main.server';

angular.json

{
      "$schema": "./node_modules/@angular/cli/lib/config/schema.json",
      "version": 1,
      "newProjectRoot": "projects",
      "projects": {
        "my-app-name": {
          "root": "",
          "sourceRoot": "src",
          "projectType": "application",
          "prefix": "app",
          "schematics": {
            "@schematics/angular:component": {
              "styleext": "scss"
            }
          },
          "architect": {
            "build": {
              "builder": "@angular-devkit/build-angular:browser",
              "options": {
                "outputPath": "dist/browser",
                "index": "src/index.html",
                "main": "src/main.ts",
                "polyfills": "src/polyfills.ts",
                "tsConfig": "src/tsconfig.app.json",
                "assets": [
                  "src/favicon.ico",
                  "src/assets"
                ],
                "styles": [
                  "src/assets/sass/main.scss",
                  "node_modules/bootstrap/scss/bootstrap.scss"
                ],
                "scripts": []
              },
              "configurations": {
                "production": {
                  "fileReplacements": [
                    {
                      "replace": "src/environments/environment.ts",
                      "with": "src/environments/environment.prod.ts"
                    }
                  ],
                  "optimization": true,
                  "outputHashing": "all",
                  "sourceMap": false,
                  "extractCss": true,
                  "namedChunks": false,
                  "aot": true,
                  "extractLicenses": true,
                  "vendorChunk": false,
                  "buildOptimizer": true
                }
              }
            },
            "serve": {
              "builder": "@angular-devkit/build-angular:dev-server",
              "options": {
                "browserTarget": "my-app-name:build",
                "sslKey": "ssl/server.key",
                "sslCert": "ssl/server.crt"
              },
              "configurations": {
                "production": {
                  "browserTarget": "my-app-name:build:production"
                }
              }
            },
            "server": {
              "builder": "@angular-devkit/build-angular:server",
              "options": {
                "outputPath": "dist/server",
                "main": "server.ts",
                "tsConfig": "src/tsconfig.server.json"
              },
              "configurations": {
                "production": {
                  "outputHashing": "media",
                  "fileReplacements": [
                    {
                      "replace": "src/environments/environment.ts",
                      "with": "src/environments/environment.prod.ts"
                    }
                  ],
                  "sourceMap": false,
                  "optimization": {
                    "scripts": false,
                    "styles": true
                  }
                }
              }
            },
            "serve-ssr": {
              "builder": "@nguniversal/builders:ssr-dev-server",
              "options": {
                "browserTarget": "my-app-name:build",
                "serverTarget": "my-app-name:server"
              },
              "configurations": {
                "production": {
                  "browserTarget": "my-app-name:build:production",
                  "serverTarget": "my-app-name:server:production"
                }
              }
            },
            "prerender": {
              "builder": "@nguniversal/builders:prerender",
              "options": {
                "browserTarget": "my-app-name:build:production",
                "serverTarget": "my-app-name:server:production",
                "routes": [
                  "/"
                ]
              },
              "configurations": {
                "production": {}
              }
            }
          }
        },
      },
      "defaultProject": "my-app-name"
    }

Now when i play the command

webpack:server

I got tons of error like this one :

ERROR in ./src/app/components/auth/login/login.component.ts Module not found: Error: Can't resolve 'src/app/web-services/facebook-sdk.service' in 'C:\Code\my-app-name\src\app\components\auth\login' @ ./src/app/components/auth/login/login.component.ts 21:0-79 140:8-26 @ ./src/app/components/auth/login/login.module.ts @ ./src/app/app-routing.module.ts @ ./src/app/app.module.ts @ ./src/app/app.server.module.ts @ ./src/main.server.ts @ ./server.ts

I don't know how to find where is the problems, is it a path which is have a bad value somewhere in my config ?

I checked for hours but i cant find the error.

please help me !!!!

Thank u in advance

Alex

0

1 Answer 1

1

I found the problem:

In my components and in my modules I used imports with the relative paths

import { ApiClientService } from 'src/app/web-services/api-client.service';

I changed it to absolute paths

import { ApiClientService } from '../../web-services/api-client.service';

Build is Ok now

Sign up to request clarification or add additional context in comments.

Comments

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.