Once you have an Angular app working with server-side rendering, switching to Serverless Framework isn't that complicated. If you don't have an Angular app using server-side rendering yet, you can take a look here for a starting point.
You're going to need one new package for this whole thing to work:
$ npm install aws-serverless-express
Create a file called server.lambda.ts
in the same directory as the already existing server.ts
file (the one containing all the Express code). Copy the contents of the server.ts
file and paste them in server.lambda.ts
.
The only thing we have to do here is change the last few lines. You should see a few lines similar to this:
// Start up the Node server
app.listen(PORT, () => {
console.log(`Node server listening on http://localhost:${PORT}`);
});
In our case, we don't want Lambda to be listening all the time, so we need to change this to simply export the app:
export default app;
That's all we need to do here.
Create a file called lambda.ts
in the same directory as the previous 2 files and paste the following content:
import app from './server.lambda';
const awsServerlessExpress: any = require('aws-serverless-express');
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 server = awsServerlessExpress.createServer(app, null, binaryMimeTypes);
export const handler = (event: any, context: any) => awsServerlessExpress.proxy(server, event, context);
This uses the file we just created in the previous step and sets it as a proxy for our Serverless framework. You can tweak the binaryMimeTypes however you want.
Create a new file named webpack.lambda.config.js
in the same path as the already existing webpack.server.config.js
file and copy the contents of the original file inside the new one.
We are going to need to tweak a few things in this new configuration:
- Change the entry point from
server.ts
tolambda.ts
:
entry: { server: './lambda.ts' },
- Add
'commonjs2'
aslibraryTarget
in theoutput
object and change thefilename
:
output: {
path: path.join(__dirname, 'dist'),
filename: 'lambda.js',
libraryTarget: 'commonjs2'
},
Once everything is set up, we need an easy way to build the Lambda files. Add these lines to your package.json
file, under scripts
:
"build:lambda": "npm run build:client-and-server-bundles && npm run webpack:lambda",
"webpack:lambda": "webpack --config webpack.lambda.config.js --progress --colors"
Here's a preview of a working package.json
, just in case you need all the scripts:
"scripts": {
"ng": "ng",
"build": "ng build --prod",
"start": "ng serve",
"test": "ng test",
"lint": "tslint ./src/**/*.ts -t verbose",
"e2e": "ng e2e",
"build:ssr": "npm run build:client-and-server-bundles && npm run webpack:server",
"build:lambda": "npm run build:client-and-server-bundles && npm run webpack:lambda",
"serve:ssr": "node dist/server.js",
"build:client-and-server-bundles": "ng build --prod && ng build --prod --app 1 --output-hashing=false",
"webpack:server": "webpack --config webpack.server.config.js --progress --colors",
"webpack:lambda": "webpack --config webpack.lambda.config.js --progress --colors"
},
That's it! You should now have a working Serverless application when you run npm run build:lambda
.
You can find a working example here.