Razzle: Razzle dan Tanpa Server

Dibuat pada 30 Mei 2018  ·  30Komentar  ·  Sumber: jaredpalmer/razzle

Halo !
Saya mencoba menjalankan proyek razzle (materialUI, TypeScript, Apollo & After) di serverless.
Apa cara terbaik untuk menangani ini dengan Tanpa Server ?

Jika Anda tahu contoh apa pun di luar sana, saya senang melihatnya. Terima kasih !

Komentar yang paling membantu

Inilah cara saya menerapkan aplikasi Razzle ke AWS Lambda dengan 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,
    });
  }
}

Semua 30 komentar

Seseorang baru saja melakukan ini dan men-tweet tentang hal itu. Akan menjadi contoh yang keren

Tidak dapat menemukan tweet! Apakah kamu memilikinya ?

Apakah tweet saya - saya baru saja mengganti index.js (di mana semua hotloading terjadi) dengan

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

Anda kemudian menjalankan npm run build , salin node_modules/ ke build/ , zip server.js bersama dengan folder node_modules/ , dan unggah ke AWS Lambda. Semua yang ada di public/ kemudian diunggah ke S3 dan dikirim melalui Cloudfront.

Untuk Lambda -> infrastruktur gateway API saya menggunakan Terraform dan mengikuti panduan ini: https://www.terraform.io/docs/providers/aws/guides/serverless-with-aws-lambda-and-api-gateway.html

Masih belum sempurna - mendapatkan kesalahan ini saat memuat dari bundel sisi klien (https://static.jobsok.io/):

image


Memperbarui:
Saya tidak peduli, menghapus node_modules & menginstal ulang memberi saya:

File sizes after gzip:

  210.38 KB (+8 B)  build/static/js/bundle.1a960add.js
  1.96 KB           build/static/css/bundle.5865fae5.css

Tanpa perubahan kode - buat bundel sisi klien berfungsi kembali

Handler.js saya (atau index.js) adalah sama.
Kemudian, saya membangun semuanya dengan webpack (project + node_modules). (Anda hanya perlu memodifikasi razzle.config.js untuk itu)

Saya bekerja dengan tanpa server, bukan terraform. Pada dasarnya sama. Hanya perlu mengimpor paket relatif untuk handler (Untuk beberapa alasan, webpack tidak mengemas yang ini, mungkin karena ini pada file/jalur yang berbeda, akan diperbaiki nanti).

Unggah tanpa server semua ini, dan hanya itu. Anda dapat melihat proyeknya di sini: https://github.com/CuistotduCoin/cuistot

Ini jauh dari sempurna, dan lap.

Omong-omong, @jaredpalmer , dapatkah Anda membantu saya dalam konfigurasi razzle/webpack?
Saya ingin memasukkan semua yang diperlukan pada bundel, (termasuk node_modules) dengan kinerja terbaik. Ada contoh/tips? (Dengan konfigurasi TypeScript)

@rozenmd dapatkah Anda membagikan razzle.config Anda?

@romainquellec milik saya kosong - tidak ada konfigurasi tambahan di luar apa yang disediakan razzle

Yah, saya tidak tahu mengapa, tetapi saya tidak dapat mengakses aws-serverless-express yang didefinisikan dalam dependensi (mungkin lebih).
Dan untuk mengoptimalkan semua itu, saya ingin mengecualikan aws-sdk dari final build (selalu tersedia dalam fungsi lambda, akan melihatnya nanti)

Saya pikir itu berasal dari eksternal, tetapi saya tidak dapat menemukannya.

Ya, saya memiliki masalah yang sama. Satu-satunya solusi saya adalah meng-zip server.js dengan semua node_modules

Saya tidak bisa di lambda. Ukuran batas resmi adalah 50 bulan.
Pertanyaan umum untuk semua orang: Bagaimana cara menggabungkan node_modules dengan kinerja yang baik dengan razzle. Terima kasih !

Kami tidak menggunakan lambda, tetapi kami menggabungkan semua node_modules kami dengan menghapus opsi eksternal default di razzle.config.js. Ini keren karena itu berarti folder build secara efektif merupakan artefak build. Kami kemudian meletakkannya di s3 lalu tugas Jenkins kami menarik folder baru ke setiap server dan memulai ulang pm2.

@jaredpalmer - razzle.config.js ?

dengan menghapus opsi eksternal default di razzle.config.js:

Seperti itu ?
modify(config, { target, dev }) { if (target === 'node' && !dev) { config.externals = []; } return config; }

@romainquellec yang bekerja!!

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

Bekerja. Bagus ! 👍 👍
Itu adil untuk menambahkan contoh! Saya akan melihat itu akhir pekan ini. Apakah Anda keberatan berpartisipasi @rozenmd ?

Sayangnya saya tidak akan punya waktu luang akhir pekan ini @romainquellec tetapi senang untuk meninjau / berkolaborasi dalam PR

Aku menutup ini. Akan mengirimkan PR sesegera mungkin.

@romainquellec apakah Anda pernah membuat permintaan tarik itu? Apakah Anda masih menjalankan proyek Razzle di lingkungan tanpa server? Saya baru mulai mengeksplorasi kemungkinan ini dan menemukan utas ini :)

@mbrochh Tidak melihat permintaan tarik pada akhirnya, tetapi saya masih menggunakan Razzle di https://onlineornot.com untuk semua rendering sisi server tanpa server saya.

Saya juga baru saja menemukan posting blog ini: https://medium.com/@RozenMD/build -your-own-app-with-react-graphql-and-serverless-architecture-part-1-server-side-rendering-f0d0144ff5f

Saya kira saya harus menyelam lebih dulu dan mencoba mengikuti posting itu :)

Terima kasih atas kirimannya!

https://maxrozen.com/2018/08/08/start-your-own-app-with-react-part-1 mungkin merupakan tautan yang lebih baik untuk pemformatan kode.

dan terimakasih! :senyum:

Apakah ada yang menggunakan Razzle ke lambda AWS?

Saya juga mencari contoh untuk Razzle di lambda AWS. Jika ada yang melakukannya dan senang berbagi dengan kami, akan sangat menghargai.

Inilah cara saya menerapkan aplikasi Razzle ke AWS Lambda dengan 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,
    });
  }
}

@jgcmarins tentang pengaturan razzletack itu. Bisakah Anda melakukan langkah demi langkah cara menggunakan ini? Saya ingin menambahkannya ke dokumen razzle.

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

Saya butuh bantuan dalam hal ini, adakah yang bisa membantu saya?

@fivethreeo langkah demi langkah adalah mengatur CDK di akun AWS dan kemudian menjalankan cdk deploy dengan beberapa flag tambahan dan langsung \o/

Saya ingin melakukan panggung dengan domain alih-alih jalur. Mungkin membuat contoh fitur lengkap dengan rds, rotasi kunci, TypeOrm, typegraphql, Formik dan jwt tetapi tidak seperti contoh di razzle itu sendiri.

Tidak ada yang hilang sebaliknya.

Apakah halaman ini membantu?
0 / 5 - 0 peringkat

Masalah terkait

dizzyn picture dizzyn  ·  3Komentar

charlie632 picture charlie632  ·  4Komentar

JacopKane picture JacopKane  ·  3Komentar

knipferrc picture knipferrc  ·  5Komentar

MaxGoh picture MaxGoh  ·  4Komentar