你好 !
我正在尝试在无服务器上运行一个 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 :
虽然仍然不完美 - 从客户端包(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)
我正在使用无服务器,而不是 terraform。 基本一样。 只需要为处理程序导入相关包(由于某种原因,webpack 没有打包这个,可能是因为它在不同的文件/路径上,稍后会修复)。
无服务器上传所有这些,就是这样。 你可以在这里看到这个项目: https :
它远非完美,然后擦拭。
顺便说一句, @jaredpalmer ,你能帮我解决 razzle/webpack 配置吗?
我想以最佳性能包含捆绑包中所需的所有内容(包括 node_modules)。 任何例子/提示? (使用打字稿配置)
@rozenmd你能分享你的 razzle.config 吗?
@romainquellec我的是空的 - 除了 razzle 提供的之外没有额外的配置
好吧,我不知道为什么,但我无法访问依赖项中定义的 aws-serverless-express(可能更多)。
为了优化所有这些,我想从最终构建中排除 aws-sdk(它总是在 lambda 函数中可用,但稍后会看到)
我认为它来自外部,但我无法弄清楚。
是的,我有同样的问题。 我唯一的解决方案是使用所有node_modules 压缩 server.js
我不能在 lambda 上。 官方限制大小为 50 个月。
每个人的一般问题:如何将具有良好性能的 node_modules 与 razzle 捆绑在一起。 谢谢 !
我们不使用 lambda,但我们通过删除 razzle.config.js 中的默认 externals 选项来捆绑我们所有的 node_modules。 这很酷,因为这意味着构建文件夹实际上是一个构建工件。 然后我们将它放到 s3 上,然后我们的 Jenkins 任务将新文件夹拉到每个服务器上并重新启动 pm2。
@jaredpalmer - 你有没有可能用razzle.config.js
发布一个要点?
通过删除 razzle.config.js 中的默认 externals 选项:
像那样 ?
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但很高兴审查/合作 PRs
我正在关闭这个。 将尽快提交 PR。
@romainquellec你有没有绕过提出那个拉取请求? 您还在无服务器环境中运行 Razzle 项目吗? 我刚刚开始探索这种可能性并偶然发现了这个线程:)
@mbrochh 最后没有看到拉取请求,但我仍在https://onlineornot.com上使用 Razzle 进行我的所有无服务器服务器端渲染。
我也刚刚发现这篇博文: 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?
我也在寻找 AWS lambda 上的 Razzle 示例。 如果有人做过并乐于与我们分享,将不胜感激。
这是我使用AWS CDK将 Razzle 应用程序部署到 AWS Lambda 的方式:
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 文档中。
@fivethreeo一步一步是在 AWS 账户上设置 CDK,然后运行cdk deploy
并带有一些额外的标志,它是实时的 \o/
我想用域而不是路径来制作舞台。 也许用 rds、密钥轮换、TypeOrm、typegraphql、Formik 和 jwt 制作一个功能齐全的例子,但不是 razzle 本身的例子。
否则什么都没有。
最有用的评论
这是我使用AWS CDK将 Razzle 应用程序部署到 AWS Lambda 的方式:
RazzleStack