Razzle: Razzleとサーバーレス

作成日 2018年05月30日  ·  30コメント  ·  ソース: jaredpalmer/razzle

こんにちは !
サーバーレスでrazzleプロジェクト(materialUI、Typescript、Apollo&After)を実行しようとしています。
サーバーレスでこれを処理するための最良の方法は何ですか?

例をご存知でしたら、喜んでご覧させていただきます。 ありがとう !

最も参考になるコメント

これは私がしてAWSラムダにばか騒ぎのアプリを展開してきた方法であるAWS CDK

RazzleStack

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,
    });
  }
}

全てのコメント30件

誰かがこれをして、それについてツイートしました。 かっこいい例になります

ツイートが見つかりません! あなたはそれを手に入れましたか ?

私のツイートでした-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 buildnode_modules/build/ npm run buildにコピーし、 server.jsnode_modules/フォルダーと一緒に圧縮して、AWSLambdaにアップロードします。 public/内のすべてがS3にアップロードされ、Cloudfront経由で送信されます。

Lambda-> APIゲートウェイインフラストラクチャの場合、Terraformを使用し、次のガイドに従いました: https

ただし、まだ完全ではありません-クライアント側バンドル(https://static.jobsok.io/)からのロード時にこのエラーが発生します:

image


アップデート:
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を変更する必要があります)

テラフォームではなく、サーバーレスで作業しています。 基本的に同じです。 ハンドラーの相対パッケージをインポートする必要があります(何らかの理由で、webpackはこれをパックしません。おそらく、別のファイル/パスにあるため、後で修正されます)。

サーバーレスでこれをすべてアップロードすれば、それだけです。 ここでプロジェクトを見ることができます: https

それは完璧にはほど遠いです、そしてワイプ。

ちなみに、 @ jaredpalmer 、razzle / webpackの設定を手伝ってくれませんか?
バンドルに必要なすべてのもの(node_modulesを含む)を最高のパフォーマンスで含めたいと思います。 例/ヒントはありますか? (Typescript設定を使用)

@rozenmdあなたはあなたのrazzle.configを共有できますか?

@romainquellecmineは空

理由はわかりませんが、依存関係で定義されているaws-serverless-expressにアクセスできません(多分それ以上)。
そして、それらすべてを最適化するために、最終ビルドからaws-sdkを除外したいと思います(ラムダ関数で常に利用可能ですが、後でそれを確認します)

外から来ていると思いますが、わかりません。

はい、同じ問題がありました。 私の唯一の解決策は、server.jsをすべてのnode_modulesで圧縮することでした

ラムダは使えません。 公式の制限サイズは50moです。
すべての人への一般的な質問:node_modulesを優れたパフォーマンスとrazzleでバンドルする方法。 ありがとう !

ラムダは使用しませんが、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に自由な時間がありませんが、PRのレビュー/コラボレーションは喜んでいます。

これを閉じます。 できるだけ早く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ラムダにデプロイした人はいますか?

AWSラムダでのRazzleの例も探しています。 誰かがそれをして、私たちと共有して幸せなら、本当に感謝します。

これは私がしてAWSラムダにばか騒ぎのアプリを展開してきた方法であるAWS CDK

RazzleStack

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,
    });
  }
}

そのrazzletackのセットアップについて@jgcmarins。 これを使用する方法を段階的に実行できますか? それをrazzleドキュメントに追加したいと思います。

https://razzle-git-canary.jared.vercel.app/deployment-options/aws

私はこれについていくつかの助けが必要です、誰かが私に手を差し伸べることができますか?

@ fivethreeoステップバイステップでは、AWSアカウントでCDKをセットアップし、いくつかの追加フラグを指定してcdk deployを実行すると、ライブになります\ o /

https://razzle-git-canary.jared.vercel.app/deployment-options/awsから他に不足しているものはあり

パスではなくドメインでステージをやりたいです。 おそらく、rds、キー回転、TypeOrm、typegraphql、Formik、jwtを使用してフル機能の例を作成しますが、razzle自体の例としては作成しません。

それ以外に欠けているものはありません。

このページは役に立ちましたか?
0 / 5 - 0 評価