DEV Community

Jean Santos
Jean Santos

Posted on

Deploying Angular Universal v16 to AWS Serverless: A Step-by-Step Guide

Introduction

Angular Universal is a powerful framework for server-side rendering (SSR) of Angular applications, providing better SEO, performance, and faster loading times. AWS Serverless services, on the other hand, offer a scalable and cost-effective way to deploy applications without managing infrastructure. Combining these two technologies can lead to a high-performing and easily scalable solution. In step-by-step, we will guide you through the process of deploying Angular Universal version 16 to AWS Serverless services.

Prerequisites

Before we begin, make sure you have the following prerequisites in place:

  1. Node.JS version 18
  2. Angular Cli v16
  3. AWS account with necessary IAM permissions.
  4. AWS CLI (Command Line Interface) installed and configured.
  5. Basic knowledge of Angular, AWS services, and serverless deployment.

Step 1: Create Angular project
Use the Angular CLI to create your Angular app. Ensure that you have version 16 of Angular dependency installed.

To create angular project you can run the command below:

$ ng new my-app
Enter fullscreen mode Exit fullscreen mode

and then setup angular universal, this command will install some dependencies, update files and create others, if you are not familiar I recommend this link: https://angular.io/guide/universal

$ ng add @nguniversal/express-engine
Enter fullscreen mode Exit fullscreen mode

then run the command to make sure everything is OK, it will run your app on localhost port 4000.

$ npm run build:ssr && npm run serve:ssr
Enter fullscreen mode Exit fullscreen mode

This command will generate a production build of your Angular Universal app, including the server-side rendering files.

Step 2: Setup an AWS Serverless Framework

We will set up a basic Serverless Framework project with a handler function in AWS Lambda.

2.1 - First we need to install serverless framework dependencies:

$ npm i -S aws-serverless-express
$ npm i -D serverless serverless-api-compression serverless-apigw-binary serverless-associate-waf serverless-offline
Enter fullscreen mode Exit fullscreen mode

2.2 - Then create a lambda.js file on root and add the SSR handler function.

const awsServerlessExpress = require("aws-serverless-express");
const server = require("./dist/my-app/server/main");
const awsServerlessExpressMiddleware = require("aws-serverless-express/middleware");

const binaryMimeTypes = [
  "application/javascript",
  "application/json",
  "application/octet-stream",
  "application/xml",
  "image/jpeg",
  "image/png",
  "image/gif",
  "text/comma-separated-values",
  "text/css",
  "text/html",
  "text/javascript",
  "text/plain",
  "text/text",
  "text/xml",
  "image/x-icon",
  "image/svg+xml",
  "application/x-font-ttf",
];

const app = server.app();
app.use(awsServerlessExpressMiddleware.eventContext());
const serverProxy = awsServerlessExpress.createServer(app,null,binaryMimeTypes);

module.exports.universal = (event, context) =>
  awsServerlessExpress.proxy(serverProxy, event, context);

Enter fullscreen mode Exit fullscreen mode

2.3 - Next create a serverless.yml file on root as show below:

service: angular-serverless-app

plugins:
  - serverless-apigw-binary
  - serverless-offline
  - serverless-api-compression
  - serverless-associate-waf

provider:
  name: aws
  runtime: nodejs18.x
  memorySize: 2048
  timeout: 10
  stage: dev
  region: us-east-1
  deploymentBucket:

package:
  excludeDevDependencies: true
  exclude:
    - src/**
    - node_modules/**
    - firebug-lite/**
    - e2e/**
    - coverage/**
    - .angular/**
    - .vscode/**
    - '!node_modules/@vendia/**'
    - '!node_modules/aws-serverless-express/**'
    - '!node_modules/binary-case/**'
    - '!node_modules/type-is/**'
    - '!node_modules/media-typer/**'
    - '!node_modules/mime-types/**'
    - '!node_modules/mime-db/**'

custom:
  serverless-offline:
    noPrependStageInUrl: true
  contentCompression: 1024
  apigwBinary:
    types:
      - '*/*'

functions:
  api:
    handler: lambda.universal
    events:
      - http: ANY /{proxy+}
      - http: ANY /
Enter fullscreen mode Exit fullscreen mode

Step 3: Simulate serverless offline mode & deploy to AWS Serverless Services

To simulate serverless offline mode is easy just run the command:

$ serverless offline start
Enter fullscreen mode Exit fullscreen mode

Ensure that serverless package is installed global to run command above.

if everything run OK you can deploy using command:

$ serverless deploy
Enter fullscreen mode Exit fullscreen mode

It will output urls to access your application. Every time you run the command above, a package is created and then uploaded to the S3 bucket, so you can manage them.

obs: Some resources won't be found because the aws service builds the path in your url, to fix it you can create a new build config in angular.json and set the path to baseHref and add a new npm script:

...
  "configurations": {
    "production": {
      "budgets": [
        {
          "type": "initial",
          "maximumWarning": "500kb",
          "maximumError": "1mb"
        },
        {
          "type": "anyComponentStyle",
          "maximumWarning": "2kb",
          "maximumError": "4kb"
        }
      ],
      "outputHashing": "all"
    },
    "serverless": {
      "budgets": [
        {
          "type": "initial",
          "maximumWarning": "500kb",
          "maximumError": "1mb"
        },
        {
          "type": "anyComponentStyle",
          "maximumWarning": "2kb",
          "maximumError": "4kb"
        }
      ],
      "outputHashing": "all",
      "baseHref": "/dev/"
    },
...
Enter fullscreen mode Exit fullscreen mode
"build:ssr:aws": "ng build --configuration serverless && ng run my-app:server",
Enter fullscreen mode Exit fullscreen mode

Step 4: remove serverless application

To remove your application you can run command below:

$ serverless remove
Enter fullscreen mode Exit fullscreen mode

Step 5: Domain Setup (Optional)

If you prefer to use a custom domain for your application, set up a domain and configure it to point to your AWS Serverless app. This step involves setting up DNS records and configuring your AWS resources accordingly.

Conclusion

By following these steps, you can deploy your Angular Universal v16 application to AWS Serverless services, combining the power of SSR with the scalability and cost-effectiveness of AWS Serverless offerings. This setup ensures improved performance, better SEO, and seamless scalability for your Angular app. Remember to keep an eye on Angular Universal and AWS updates for any changes or improvements in the deployment process.

The repository with all changes: https://github.com/jeanfsantos/angular-serverless-app

Happy Deploying!

Top comments (1)

Collapse
 
tprasanth profile image
Prasanth T • Edited

This worked perfectly. One thing is, serverless doctor reported that "Support for "package.include" and "package.exclude" will be removed in the next major release. Please use "package.patterns" instead". so, I updated it to

package:
  excludeDevDependencies: true
  patterns:
    - '!src/**'
    - '!node_modules/**'
    - '!firebug-lite/**'
    - '!e2e/**'
    - '!coverage/**'
    - '!.angular/**'
    - '!.vscode/**'
    - node_modules/@vendia/**
    - node_modules/aws-serverless-express/**
    - node_modules/binary-case/**
    - node_modules/type-is/**
    - node_modules/media-typer/**
    - node_modules/mime-types/**
    - node_modules/mime-db/**
Enter fullscreen mode Exit fullscreen mode