Привет !
Я пытаюсь запустить проект razzle (materialUI, Typescript, Apollo & After) без сервера.
Как лучше всего справиться с этим с помощью Serverless?
Если вы знаете какой-либо пример, я буду рад взглянуть. Спасибо !
Кто-то просто сделал это и написал об этом в Твиттере. Было бы круто
Не могу найти твит! У тебя есть это ?
Был ли мой твит - я просто заменил index.js (где происходит горячая загрузка) на
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)
}
Затем вы запускаете npm run build
, копируете node_modules/
в build/
, заархивируете server.js
вместе с папкой node_modules/
и загружаете это в AWS Lambda. Все в public/
затем загружается в S3 и отправляется через Cloudfront.
Для инфраструктуры шлюза Lambda -> API я использовал Terraform и следовал этому руководству: https://www.terraform.io/docs/providers/aws/guides/serverless-with-aws-lambda-and-api-gateway.html
Тем не менее, все еще не идеально - получение этой ошибки при загрузке из клиентского пакета (https://static.jobsok.io/):
Обновлять:
Я не дерьмо, удаление node_modules и переустановка дало мне:
File sizes after gzip:
210.38 KB (+8 B) build/static/js/bundle.1a960add.js
1.96 KB build/static/css/bundle.5865fae5.css
Без изменений кода - снова сделал клиентский пакет работоспособным
Мой handler.js (или index.js) такой же.
Затем я собираю все с помощью webpack (project + node_modules). (Для этого вам просто нужно изменить razzle.config.js)
Я работаю с бессерверным, а не с терраформом. В основном то же самое. Просто нужно импортировать относительный пакет для обработчика (по какой-то причине веб-пакет не упаковывает этот, возможно, потому что он находится в другом файле / пути, исправим позже).
Бессерверная закачка все это и все. Посмотреть проект можно здесь: https://github.com/CuistotduCoin/cuistot
Это далеко не идеально, да и вайп.
Кстати, @jaredpalmer , не могли бы вы мне помочь с конфигурацией razzle / webpack?
Я хочу включить в пакет все необходимое (включая node_modules) с максимальной производительностью. Есть примеры / советы? (С конфигурацией Typescript)
@rozenmd можешь поделиться своим razzle.config?
Шахта @romainquellec пуста - никаких дополнительных настроек, кроме тех, которые предоставляет razzle
Ну, я не знаю почему, но я не могу получить доступ к aws-serverless-express, определенному в зависимостях (может быть, больше).
И чтобы оптимизировать все это, я хочу исключить aws-sdk из окончательной сборки (он всегда доступен в лямбда-функции, хотя мы увидим это позже)
Я думаю, что это происходит из-за внешних факторов, но я не могу этого понять.
Да, у меня была такая же проблема. Моим единственным решением было заархивировать server.js со всеми node_modules.
Я не могу использовать лямбду. Официальный лимит - 50 месяцев.
Общий вопрос для всех: как связать node_modules с хорошей производительностью с razzle. Спасибо !
Мы не используем лямбда, но мы объединяем все наши node_modules, удаляя опцию externals по умолчанию в razzle.config.js. Это круто, потому что это означает, что папка сборки фактически является артефактом сборки. Затем мы помещаем его на s3, затем наша задача Jenkins загружает новую папку на каждый сервер и перезапускает pm2.
@jaredpalmer - есть ли шанс, что вы могли бы опубликовать суть с этим razzle.config.js
?
удалив опцию externals по умолчанию в razzle.config.js:
Как это ?
modify(config, { target, dev }) {
if (target === 'node' && !dev) {
config.externals = [];
}
return config;
}
@romainquellec, который работает !!
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
},
}
Работает. Хороший ! 👍 👍
Справедливо добавить пример! Я посмотрю на это в эти выходные. Вы не против принять участие в @rozenmd ?
К сожалению, в эти выходные у меня не будет свободного времени @romainquellec, но я буду рад пересмотреть / поработать над PR
Я закрываю это. Отправлю PR как можно скорее.
@romainquellec Вы когда-нибудь делали этот
@mbrochh В конце концов не увидел https://onlineornot.com для всего моего бессерверного рендеринга на стороне сервера.
Я также только что нашел это сообщение в блоге: https://medium.com/@RozenMD/build -your-own-app-with-react-graphql-and-serverless-architecture-part-1-server-side-rendering-f0d0144ff5f
Думаю, мне придется погрузиться в голову и попытаться следить за этим постом :)
Спасибо за сообщение!
https://maxrozen.com/2018/08/08/start-your-own-app-with-react-part-1 , вероятно, лучшая ссылка для форматирования кода.
и спасибо! :улыбка:
Кто-нибудь развернул Razzle на AWS lambda?
Я также ищу пример для Razzle на AWS lambda. Если бы кто-то сделал это и был бы рад поделиться с нами, был бы очень признателен.
Вот как я развертывал приложения Razzle в AWS Lambda с 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 об этой настройке razzletack. Не могли бы вы пошагово рассказать, как это использовать? Я хотел бы добавить его в документацию razzle.
https://razzle-git-canary.jared.vercel.app/deployment-options/aws
Мне нужна помощь в этом, может ли кто-нибудь помочь мне?
@fivethreeo, шаг за шагом нужно настроить CDK в учетной записи AWS, а затем запустить cdk deploy
с некоторыми дополнительными флагами, и он будет работать \ o /
Что еще не хватает в https://razzle-git-canary.jared.vercel.app/deployment-options/aws?
?
Я бы хотел сделать этап с доменом вместо пути. Возможно, сделайте полнофункциональный пример с rds, вращением клавиш, TypeOrm, typegraphql, Formik и jwt, но не в качестве примера в самом razzle.
В остальном ничего не упущено.
Самый полезный комментарий
Вот как я развертывал приложения Razzle в AWS Lambda с AWS CDK :
RazzleStack