Hola !
Estoy tratando de ejecutar un proyecto razzle (materialUI, Typecript, Apollo & After) sin servidor.
¿Cuál es la mejor manera de manejar esto con Serverless?
Si conoce algún ejemplo, me complace echarle un vistazo. Gracias !
Alguien acaba de hacer esto y tuiteó al respecto. Sería un ejemplo genial
¡No puedo encontrar el tweet! Lo tienes ?
¿Fue mi tweet? Acabo de reemplazar index.js (donde ocurre toda la carga en caliente) con
import awsServerlessExpress from 'aws-serverless-express'
import app from './server'
const binaryMimeTypes = [
'application/octet-stream',
'font/eot',
'font/opentype',
'font/otf',
'image/jpeg',
'image/png',
'image/svg+xml',
]
const server = awsServerlessExpress.createServer(app, null, binaryMimeTypes)
export const handler = (event, context, callback) => {
awsServerlessExpress.proxy(server, event, context)
}
A continuación, ejecute npm run build
, copie node_modules/
en build/
, comprima server.js
junto con la carpeta node_modules/
y cárguela en AWS Lambda. Todo en public/
luego se carga a S3 y se envía a través de Cloudfront.
Para Lambda -> infraestructura de puerta de enlace API, utilicé Terraform y seguí esta guía: https://www.terraform.io/docs/providers/aws/guides/serverless-with-aws-lambda-and-api-gateway.html
Sin embargo, todavía no es perfecto: aparece este error en la carga del paquete del lado del cliente (https://static.jobsok.io/):
Actualizar:
No te jodo, eliminar node_modules y reinstalar me dio:
File sizes after gzip:
210.38 KB (+8 B) build/static/js/bundle.1a960add.js
1.96 KB build/static/css/bundle.5865fae5.css
Sin cambios en el código: volvió a funcionar el paquete del lado del cliente
Mi handler.js (o index.js) es el mismo.
Luego, construyo todo con webpack (proyecto + node_modules). (Solo necesita modificar razzle.config.js para eso)
Estoy trabajando sin servidor, no con terraform. Básicamente lo mismo. Solo necesita importar el paquete relativo para el controlador (por alguna razón, el paquete web no empaqueta este, tal vez porque está en un archivo / ruta diferente, lo arreglará más adelante).
Carga todo esto sin servidor, y eso es todo. Puedes ver el proyecto aquí: https://github.com/CuistotduCoin/cuistot
Está lejos de ser perfecto y limpio.
Por cierto, @jaredpalmer , ¿puedes ayudarme con la configuración de razzle / webpack?
Quiero incluir todo lo necesario en el paquete (node_modules incluidos) con el mejor rendimiento. ¿Algún ejemplo / consejo? (Con la configuración de TypeScript)
@ Frozenmd ¿puedes compartir tu razzle.config?
@romainquellec el mío está vacío, no hay configuración adicional más allá de lo que proporciona razzle
Bueno, no sé por qué, pero no puedo acceder a aws-serverless-express definido en dependencias (tal vez más).
Y para optimizar todo eso, quiero excluir aws-sdk de la compilación final (siempre está disponible en una función lambda, aunque lo veré más adelante)
Creo que proviene de fuentes externas, pero no puedo entenderlo.
Sí, tuve el mismo problema. Mi única solución fue cerrar el archivo server.js con todos los node_modules
No puedo en lambda. El tamaño límite oficial es de 50 meses.
Pregunta general para todos: Cómo agrupar node_modules con buen rendimiento con razzle. Gracias !
No usamos lambda, pero agrupamos todos nuestros node_modules eliminando la opción externa predeterminada en razzle.config.js. Esto es genial porque significa que la carpeta de compilación es efectivamente un artefacto de compilación. Luego lo colocamos en s3, luego nuestra tarea de Jenkins extrae la nueva carpeta en cada servidor y reinicia pm2.
@jaredpalmer : ¿hay alguna posibilidad de que puedas publicar un resumen con ese razzle.config.js
?
eliminando la opción externa predeterminada en razzle.config.js:
Como eso ?
modify(config, { target, dev }) {
if (target === 'node' && !dev) {
config.externals = [];
}
return config;
}
@romainquellec eso funciona !!
module.exports = {
modify: (config, { target, dev }, webpack) => {
// do something to config
const appConfig = config // stay immutable here
if (target === 'node' && !dev) {
appConfig.externals = []
}
return appConfig
},
}
Esta funcionando. Bien ! 👍 👍
¡Es justo agregar un ejemplo! Lo veré este fin de semana. ¿Te importaría participar @ Frozenmd ?
Desafortunadamente, no tendré tiempo libre este fin de semana @romainquellec pero feliz de revisar / colaborar en relaciones públicas
Estoy cerrando esto. Enviará un PR lo antes posible.
@romainquellec , ¿alguna vez hiciste esa solicitud de extracción? ¿Sigue ejecutando su proyecto Razzle en un entorno sin servidor? Recién estoy comenzando a explorar esta posibilidad y me encontré con este hilo :)
@mbrochh No vi una solicitud de extracción al final, pero sigo usando Razzle en https://onlineornot.com para toda mi representación del lado del servidor sin servidor.
También encontré esta publicación de blog: https://medium.com/@RozenMD/build -your-own-app-with-react-graphql-and-serverless-architecture-part-1-server-side-rendering-f0d0144ff5f
Supongo que tendré que sumergirme de cabeza e intentar seguir esa publicación :)
¡Gracias por la publicacion!
https ://max
¡y gracias! :sonrisa:
¿Alguien implementó Razzle en AWS lambda?
También estoy buscando un ejemplo de Razzle en AWS lambda. Si alguien lo ha hecho y está feliz de compartir con nosotros, se lo agradecería mucho.
Así es como he estado implementando aplicaciones Razzle en AWS Lambda con AWS CDK :
import * as CDK from '@aws-cdk/core';
import * as S3 from '@aws-cdk/aws-s3';
import * as S3Deployment from '@aws-cdk/aws-s3-deployment';
import * as Lambda from '@aws-cdk/aws-lambda';
import * as APIGateway from '@aws-cdk/aws-apigateway';
import * as SSM from '@aws-cdk/aws-ssm';
import * as SecretsManager from '@aws-cdk/aws-secretsmanager';
import { ConfigProps, getParam, ModeStack } from '../helpers';
export class RazzleStack extends ModeStack {
constructor(app: CDK.App, id: string, props: ConfigProps) {
super(app, id, props);
/**
* S3 bucket to the /public folder
*/
const publicBucketName = `my-razzle-app-bucket-public-files-${this.mode}`;
const bucketPublicFiles = new S3.Bucket(this, publicBucketName, {
publicReadAccess: true,
bucketName: publicBucketName.toLowerCase(),
});
/**
* Store S3 bucket name
*/
new SSM.StringParameter(this, `MyRazzleAppBucketAssetsName${this.Mode}`, {
description: `My Razzle App S3 Bucket Name for Assets on ${this.Mode}`,
parameterName: `/${props.name}/S3/Assets/Name`,
stringValue: bucketPublicFiles.bucketName,
});
/**
* Store S3 domainName name
*/
new SSM.StringParameter(this, `MyRazzleAppBucketAssetsDomainName${this.Mode}`, {
description: `My Razzle App S3 Bucket DomainName for Assets on ${this.Mode}`,
parameterName: `/${props.name}/S3/Assets/DomainName`,
stringValue: bucketPublicFiles.bucketDomainName,
});
/**
* Deploy public folder of build to `my-razzle-app-bucket-public-files-${this.mode}` bucket
*/
new S3Deployment.BucketDeployment(this, `${publicBucketName}-deploy`, {
sources: [S3Deployment.Source.asset('./build/public')],
destinationBucket: bucketPublicFiles,
});
/**
* Environment Variables for SSR Function
*/
const environmentKeys = [
'NODE_ENV',
'RAZZLE_GRAPHQL_URL',
'RAZZLE_MAPBOX_ACCESS_TOKEN',
'RAZZLE_GOOGLE_RECAPTCHA_SITE',
'RAZZLE_GA_ID',
];
const environmentSecret = SecretsManager.Secret.fromSecretAttributes(
this,
`MyRazzleAppEnvironmentSecret${this.Mode}`,
{
secretArn: getParam(this, `MyRazzleAppSecretsArn${this.Mode}`),
},
);
let environment: { [key: string]: string } = {};
for (const key of environmentKeys) {
environment[key] = environmentSecret.secretValueFromJson(key).toString();
}
/**
* Razzle SSR Function
*/
const myRazzleAppSsrFunction = new Lambda.Function(this, `MyRazzleAppSSRFunction${this.Mode}`, {
description: `Lambda Function that runs My Razzle App SSR on ${this.Mode}`,
code: Lambda.Code.fromAsset('./build', {
exclude: ['public', 'static', '*.json'],
}),
handler: 'server.handler',
runtime: Lambda.Runtime.NODEJS_12_X,
memorySize: 512,
timeout: CDK.Duration.seconds(5),
environment,
tracing: Lambda.Tracing.ACTIVE,
});
/**
* Razzle ApiGateway
*/
const razzleSsrApiGatewayName = `MyRazzleAppSSRApiGateway${this.Mode}`;
const api = new APIGateway.RestApi(this, razzleSsrApiGatewayName, {
description: `ApiGateway that exposes My Razzle App SSR on ${this.Mode}`,
binaryMediaTypes: ['*/*'],
endpointTypes: [APIGateway.EndpointType.REGIONAL],
deployOptions: {
stageName: this.mode,
},
});
const integration = new APIGateway.LambdaIntegration(myRazzleAppSsrFunction);
const root = api.root;
const pathApi = api.root.addResource('{proxy+}');
root.addMethod('GET', integration);
pathApi.addMethod('ANY', integration);
/**
* Razzle ApiGateway ID
*/
new SSM.StringParameter(this, `MyRazzleAppAPIGatewayRestId${this.Mode}`, {
description: `My Razzle App ApiGateway ID on ${this.Mode}`,
parameterName: `/${props.name}/APIGateway/ApiId`,
stringValue: api.restApiId,
});
}
}
@jgcmarins sobre esa configuración de alboroto. ¿Podrías hacer un paso a paso sobre cómo usar esto? Me gustaría agregarlo a razzle docs.
https://razzle-git-canary.jared.vercel.app/deployment-options/aws
Necesito ayuda con esto, ¿alguien puede echarme una mano?
@fivethreeo, el paso a paso sería configurar CDK en una cuenta de AWS y luego ejecutar cdk deploy
con algunos indicadores adicionales y ya está \ o /
¿Falta algo más en https://razzle-git-canary.jared.vercel.app/deployment-options/aws?
?
Me gustaría hacer el escenario con un dominio en lugar de una ruta. Tal vez haga un ejemplo completo con rds, rotación de claves, TypeOrm, typegraphql, Formik y jwt, pero no como ejemplo en razzle en sí.
De lo contrario, no falta nada.
Comentario más útil
Así es como he estado implementando aplicaciones Razzle en AWS Lambda con AWS CDK :
RazzleStack