将 Angular 17 部署到 AWS 无服务器

问题描述 投票:0回答:1

我创建了一个全新的 Angular 17 独立应用程序。使用简单的路线创建了两个组件。 我安装了以下

npm i -S aws-serverless-express

npm i -D serverless serverless-api-compression serverless-apigw-binary serverless-associate-waf serverless-offline

我尝试使用以下 serverless.yml 文件将其部署到 AWS Serverless lambda

service: seventeentest-app

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

provider:
  name: aws
  runtime: nodejs20.x
  stage: dev
  region: ap-south-1
  memorySize: 512
  timeout: 10

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

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

package:
  excludeDevDependencies: true
  patterns:
    - "!node_modules/**"
    - "!**/*.ts"
    - "!**/*.html"
    - "!**/*.json"
    - "!**/*.scss"
    - "dist/**"
    - "!src/**"
    - "!e2e/**"
    - "angular.json"
    - "package.json"
    - "tsconfig.json"
    - "tsconfig.app.json"
    - "tsconfig.spec.json"
    - "tslint.json"
    - "README.md"
    - "!firebug-lite/**"
    - "!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/**"

lambda.js 文件

// Import the required modules
const awsServerlessExpress = require('aws-serverless-express');

// Define your MIME types
const binaryMimeTypes = [
    'application/javascript',
    'application/json',
    'application/octet-stream',
    'application/xml',
    'font/eot',
    'font/opentype',
    'font/otf',
    'image/jpeg',
    'image/png',
    'image/svg+xml',
    'text/comma-separated-values',
    'text/css',
    'text/html',
    'text/javascript',
    'text/plain',
    'text/text',
    'text/xml'
];

let server;

// Import the app from the ES module
import('./dist/seventeentest/server/server.mjs').then((app) => {
    // Create a server with the specified MIME types
    server = awsServerlessExpress.createServer(app.default, null, binaryMimeTypes);
}).catch((error) => {
    console.error('Failed to import app:', error);
});

// Export the universal function
exports.universal = (event, context) => {
    console.log(`EVENT: ${JSON.stringify(event)}`);
    if (!server) {
        console.error('Server is not initialized');
        return;
    }
    return awsServerlessExpress.proxy(server, event, context, 'PROMISE').promise;
};

但是部署失败并向我显示错误

{"message": "内部服务器错误"}

控制台显示错误

加载资源失败:服务器响应状态403() favicon.ico:1 无法加载资源:服务器响应 502 () dev 的状态:1

angular amazon-web-services deployment serverless
1个回答
0
投票

使用无服务器和 Lambda 的 AWS 解决方案

服务器.ts

import { APP_BASE_HREF } from '@angular/common';
import { CommonEngine } from '@angular/ssr';
import express from 'express';
import { fileURLToPath } from 'url';
import { dirname, join, resolve } from 'path';
import bootstrap from './src/main.server';

// The Express app is exported so that it can be used by Serverless Functions.
export function app(): express.Express {      
  const server = express();
  const serverDistFolder = dirname(fileURLToPath(import.meta.url));
  const browserDistFolder = resolve(serverDistFolder, '../browser');
  const indexHtml = join(serverDistFolder, 'index.server.html');
  const commonEngine = new CommonEngine();
    
  server.set('view engine', 'html');
  server.set('views', browserDistFolder);
         
  // Serve static files from /browser
  server.get('*.*', express.static(browserDistFolder, {
    maxAge: '1y'
  }));
    
  // All regular routes use the Angular engine
  server.get('*', (req, res, next) => {       
    const { protocol, originalUrl, baseUrl, headers } = req;        
    commonEngine
      .render({
        bootstrap: bootstrap,
        documentFilePath: indexHtml,
        url: `${protocol}://${headers.host}${originalUrl}`,
        publicPath: browserDistFolder,
        providers: [{ provide: APP_BASE_HREF, useValue: baseUrl }],
      })
      .then((html) => {              
        res.send(html)
      })
      .catch((err) => {            
        next(err)
      });
  });
    
  return server;
}

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

lambda.js

const awsServerlessExpress = require('aws-serverless-express');
const awsServerlessExpressMiddleware = require('aws-serverless-express/middleware');
const binaryMimeTypes = [
  "application/javascript",
  "application/json",
  "application/octet-stream",
  "application/xml",
  "image/jpeg",
  "image/png",
  "image/webp",
  "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",
  "font/ttf",
  "font/otf",
  "font/woff",
  "font/woff2"
];

module.exports.handler = async (event, context) => {
  console.log(`EVENT: ${JSON.stringify(event)}`);

  try {
    // Import the app from the ES module
    const server = await import('./dist/app-name/server/server.mjs');
    const app = await server.app();

    app.use(awsServerlessExpressMiddleware.eventContext());

    // Create a server with the specified MIME types
    const serverAws = awsServerlessExpress.createServer(app, null, binaryMimeTypes);

    if (!app) {
      console.error('Server is not initialized');
      return;
    } else {
      return awsServerlessExpress.proxy(serverAws, event, context, 'PROMISE').promise;
    }
  } catch (error) {
    console.error('Failed to import app:', error);
  }
};

无服务器.yml

service: service-name

frameworkVersion: '3'

plugins:
  - serverless-apigw-binary

provider:
  name: aws
  runtime: nodejs20.x
  memorySize: 192
  timeout: 10
  region: us-east-1
  apiGateway:
    shouldStartNameWithService: true

package:
  excludeDevDependencies: true
  exclude:
    - ./**
    - '!node_modules/@vendia/**'
  include:
    - "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/**"
    - "node_modules/@angular/ssr"
    - "node_modules/@codegenie/**"
    - "dist/**"
    - "lambda.js"

  functions:
    server:
    handler: lambda.handler
    events:
      - http: ANY /{proxy+}
      - http: ANY /

  resources:
    - ${file(resources.yml)}

另外在 angular.json 你应该更改这一行

"prerender": false, //<-Change to false
© www.soinside.com 2019 - 2024. All rights reserved.