Skip to content

Instantly share code, notes, and snippets.

@y13i
Last active December 8, 2017 01:51
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save y13i/3c851995474bc8ca8810c2d074e26cff to your computer and use it in GitHub Desktop.
Save y13i/3c851995474bc8ca8810c2d074e26cff to your computer and use it in GitHub Desktop.
AWS Lambda で Angular アプリを Server Side Rendering してみる ref: https://qiita.com/y13i/items/9401f8aeab096a727417
// ...
"apps": [
{
"platform": "browser",
"root": "src",
"outDir": "dist/browser",
// ...
{
"platform": "server",
"root": "src",
"outDir": "dist/server",
"assets": [
"assets",
"favicon.ico"
],
"index": "index.html",
"main": "main.server.ts",
"test": "test.ts",
"tsconfig": "tsconfig.server.json",
"testTsconfig": "tsconfig.spec.json",
"prefix": "app",
"styles": [
"styles.css"
],
"scripts": [],
"environmentSource": "environments/environment.ts",
"environments": {
"dev": "environments/environment.ts",
"prod": "environments/environment.prod.ts"
}
}
import { NgModule } from '@angular/core';
import { CommonModule } from '@angular/common';
import { ServerModule } from '@angular/platform-server';
import { ModuleMapLoaderModule } from '@nguniversal/module-map-ngfactory-loader';
import { AppModule } from './app.module';
import { AppComponent } from './app.component';
@NgModule({
imports: [
CommonModule,
AppModule,
ServerModule,
ModuleMapLoaderModule,
],
declarations: [],
bootstrap: [AppComponent],
})
export class AppServerModule {}
import { NgModule, Inject, PLATFORM_ID, APP_ID } from '@angular/core';
import { isPlatformBrowser } from '@angular/common';
// ...
@NgModule({
imports: [
BrowserModule.withServerTransition({appId: 'toh-pt6-ssr-lambda'}),
// ...
export class AppModule {
constructor(
@Inject(PLATFORM_ID) private platformId: Object,
@Inject(APP_ID) private appId: string,
) {
const platform = isPlatformBrowser(platformId) ? 'browser' : 'server';
console.log({platform, appId});
}
}
curl -LO https://angular.io/generated/zips/toh-pt6/toh-pt6.zip
unzip toh-pt6 -d toh-pt6-ssr-lambda
cd toh-pt6-ssr-lambda
yarn
yarn run ng serve --open
yarn add --dev awesome-typescript-loader webpack copy-webpack-plugin concurrently
yarn run build:server
yarn run start:server
yarn add aws-serverless-express
yarn add --dev @types/aws-serverless-express serverless serverless-webpack
ERROR in [at-loader] ./node_modules/@types/graphql/subscription/subscribe.d.ts:17:4
TS2304: Cannot find name 'AsyncIterator'.
ERROR in [at-loader] ./node_modules/@types/graphql/subscription/subscribe.d.ts:29:4
TS2304: Cannot find name 'AsyncIterable'.
yarn add @angular/platform-server @nguniversal/express-engine @nguniversal/module-map-ngfactory-loader express
yarn add --dev @types/express
yarn run deploy
yarn run ng generate module app-server --flat true
import {createServer, proxy} from 'aws-serverless-express';
import {app} from '../server';
export default (event, context) => proxy(createServer(app), event, context);
export { AppServerModule } from './app/app.server.module';
"predeploy": "npm run build:prod",
"deploy": "serverless deploy"
service: toh-pt6-ssr-lambda
provider:
name: aws
runtime: nodejs6.10
region: ${env:AWS_REGION}
memorySize: 128
plugins:
- serverless-webpack
custom:
webpack: lambda/webpack.config.js
webpackIncludeModules: true
functions:
main:
handler: lambda/index.default
events:
- http:
path: /
method: get
- http:
path: "{proxy+}"
method: get
import {app} from '.';
const PORT = process.env.PORT || 4000;
app.listen(PORT, () => {
console.log(`Node server listening on http://localhost:${PORT}`);
});
"lib": [
"es2017",
"dom",
"esnext.asynciterable"
]
{
"extends": "../tsconfig.json",
"compilerOptions": {
"outDir": "../out-tsc/app",
"baseUrl": "./",
"module": "commonjs",
"types": []
},
"exclude": [
"test.ts",
"**/*.spec.ts"
],
"angularCompilerOptions": {
"entryModule": "app/app-server.module#AppServerModule"
}
}
const {join} = require('path');
const {ContextReplacementPlugin} = require('webpack');
const CopyWebpackPlugin = require("copy-webpack-plugin");
const slsw = require('serverless-webpack');
module.exports = {
entry: slsw.lib.entries,
resolve: { extensions: ['.js', '.ts'] },
target: 'node',
externals: [/(node_modules|main\..*\.js)/],
output: {
libraryTarget: "commonjs",
path: join(__dirname, '..', 'dist', 'lambda'),
filename: '[name].js'
},
module: {
rules: [{ test: /\.ts$/, loader: 'awesome-typescript-loader' }]
},
plugins: [
new CopyWebpackPlugin([
{from: "dist/browserApp/**/*"},
{from: "dist/serverApp/**/*"},
]),
// Temporary Fix for issue: https://github.com/angular/angular/issues/11580
// for 'WARNING Critical dependency: the request of a dependency is an expression'
new ContextReplacementPlugin(
/(.+)?angular(\\|\/)core(.+)?/,
join(__dirname, '..', 'src'), // location of your src
{} // a map of your routes
),
new ContextReplacementPlugin(
/(.+)?express(\\|\/)(.+)?/,
join(__dirname, '..', 'src'),
{}
)
]
};
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment