我创建了一个全新的 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
使用无服务器和 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