Giter VIP home page Giter VIP logo

tonyfromundefined / next-starter Goto Github PK

View Code? Open in Web Editor NEW
95.0 4.0 15.0 1.67 MB

Next.js Starter using GraphQL, MobX (Next.js, TypeScript, Babel, Express.js, Apollo Client, React Apollo, React Apollo Hooks, GraphQL Codegen, MobX, mobx-state-tree, styled-components, next-optimized-images, Serverless Framework, AWS Lambda, Dotenv)

JavaScript 6.51% TypeScript 93.49%
nextjs nextjs-template typescript apollo react mobx mobx-state-tree styled-components serverless lambda dotenv

next-starter's Introduction

🔥 Next.js Starter using GraphQL, MobX 🔥

Production-ready Next.js boilerplate, GraphQL and MobX based. Erion Classroom uses this boilerplate in production. Authentication status can be stored in cookie with Secure,HttpOnly options.

Translations

Pre-Installed

The following libraries / Framework are pre-installed.

React.js and core framework

GraphQL

State Management

Styling

Asset Management

Deployment

1. Getting Started

# Clone the repository
$ git clone https://github.com/tonyfromundefined/next-starter
$ cd next-starter

# Flush git project
$ rm -rf .git

# Initialize your own git project
$ git init

# Install dependencies
$ yarn

# Start development server
$ yarn dev

2. Folder Structure

1. /src/services

divide big application into several abstract services and store in a folder. (/home, /auth, ...)

Recommendation👏: Isolate components, and also business logic in service unit folder

  • ~/services/{service}/components/**.tsx
  • ~/services/{service}/queries/**.graphql
  • ~/services/{service}/helpers/**.ts
  • ~/services/{service}/assets/**.png
  • ~/services/{service}/types/**.ts
  • ...

2. /src/services/index/apollo

Apollo Client settings. injects accessToken in the Authorization Header in the GraphQL request.

  • Implementation about refreshing the accessToken is required

3. /src/services/index/store

One store that is globally used based on mobx-state-tree. Because most of the cache processing is handled by the Apollo Client, the Store is only used for global status management, such as maintaining a authentication (storing jsonwebtoken).

4. /src/generated

Codes automatically generated by GraphQL Code Generator is saved.

5. /src/pages

File-based page routing. All the aliases are handled through export {default}, but all implementations are done inside /services.

export { default } from '~/services/home/pages/index'

I've separated the code with service module for future scalability. Separate common elements used in page implementations such as /queries, /helpers, /components by service name https://softwareengineering.stackexchange.com/questions/338597/folder-by-type-or-folder-by-feature

If you set generatePageAliases to true in options.json, this boilerplate traverse all /services/**/pages/**.tsx and generate page aliases in /pages automatically when yarn dev.

6. /src/styled

Implementation of themes, global css styles

7. /src/api

You can create a sub-API based on Express.js. You can dynamically Set-Cookie by ajax call.

Recommendation👏: Let the URL be a * .json to distinguish it from the REST API that returns JSON.

8. /src/types

Type declarations. (.d.ts)

Recommendation👏: The type used in each service unit should be stored in ~/services/{service}/types in each service.

9. /serverless

Entry TypeScript files for a serverless deployment.

Recommendation👏: Separate entry files into service units

3. Development

# Start development server
$ yarn dev

Use MobX store in Components

with Hooks API

~/services/home/pages/index.tsx
import { useStore } from '~/store'

export default function PageIndex() {
  const store = useStore()

  /* ... */
}

GraphQL Query, Mutation with GraphQL Code Generator and react-apollo-hooks in Components

  • Edit GraphQL Endpoint (NEXT_APP_GRAPHQL_ENDPOINT) in .env.development, .env.production

    .env.development
    NEXT_APP_STAGE = "development"
    NEXT_APP_GRAPHQL_ENDPOINT = "https://graphql-pokemon.now.sh/"
    NEXT_APP_VERSION = "0.0.1"
    
  • create a .graphql file in service unit folder (~/services/{service}/queries/**.graphql)

    ~/services/home/queries/getPikachu.graphql
    query getPikachu {
      pokemon(name: "Pikachu") {
        id
        number
        name
      }
    }
  • read all .graphql files in project and generate HOCs, hooks, components

    $ yarn generate
  • Import the created hook, and utilize

    ~/services/home/components/Pikachu.tsx
    import { useGetPikachuQuery } from '~/generated/graphql'
    
    export default function Pikachu() {
      const { data, loading, error } = useGetPikachuQuery()
    
      /* ... */
    }

Styled Components with Theme Injections

  • Inject variables that used globally

    ./styled/themes/base.ts
    import openColor from 'open-color'
    
    const theme = {
      ...openColor,
    }
  • Use the variables in styled statements with props.theme.

    const Title = styled.h3`
      font-size: 1.5rem;
      background-color: ${(props) => props.theme.yellow[4]};
      margin: .5rem 0 1rem;
      border-radius: .25rem;
      padding: .25rem;
    `

Inject Environment variables with MobX store hydration

To deploy multiple stage in a single build, it doesn't use dotenv-webpack. (Include environment variable in webpack bundle) Instead of including variables in webpack, it inject server's environment variables in MobX state. So, server and client can use variables in server and client both.

  • To use environment variables in client and server both, append NEXT_APP in variable name
    .env.**
    NEXT_APP_VERSION = "1.0.0"
    
  • To use environment variables in server only by security reason, do not append NEXT_APP in variable name
    .env.**
    SECRET_KEY = "dc35abc5-80e1-5725-8a7b-7a6ce1a21c24"
    

4. Build

# Build server and client bundles
$ yarn build

5-a. Deployment on Server (EC2, Elastic Beanstalk, Docker, ...)

# Run server with bundled assets in 80 port
$ yarn start

5-b. Deployment on Serverless (AWS Lambda + API Gateway + S3)

Pre-requisites

  • 🔑 IAM Account for Serverless framework (Requires pre-configuration using aws configure)

    $ aws configure

Configuration

Edit serverless.yml

service: next-starter  # 1. Edit service name

plugins:
  - serverless-s3-sync
  - serverless-apigw-binary
  - serverless-dotenv-plugin

package:
  individually: true
  excludeDevDependencies: false

provider:
  name: aws
  runtime: nodejs10.x
  stage: ${opt:stage, 'dev'}
  region: us-east-1  # 2. Edit AWS region name

custom:
  #######################################
  # Unique ID included in resource names.
  # Replace it with a random value for every first distribution.
  # https://www.random.org/strings/?num=1&len=6&digits=on&loweralpha=on&unique=on&format=html&rnd=new
  stackId: '0uelbz'  # 3. Update Random Stack ID
  #######################################

  buckets:
    ASSETS_BUCKET_NAME: ${self:service}-${self:custom.stackId}-${self:provider.stage}-assets
  s3Sync:
    - bucketName: ${self:custom.buckets.ASSETS_BUCKET_NAME}
      localDir: dist
  apigwBinary:
    types:
      - '*/*'

functions:
  main:
    name: ${self:service}-${self:custom.stackId}-${self:provider.stage}-main
    handler: dist/serverless/bundles/main.handler
    memorySize: 2048
    timeout: 10
    environment:
      NODE_ENV: production
    package:
      include:
        - dist/serverless/bundles/main.js
      exclude:
        - '**'
    events:
      - http:
          path: /
          method: any
      - http:
          path: /{proxy+}
          method: any
      - http:
          path: /_next/{proxy+}
          method: any
          integration: http-proxy
          request:
            uri: https://${self:custom.buckets.ASSETS_BUCKET_NAME}.s3.${self:provider.region}.amazonaws.com/{proxy}
            parameters:
              paths:
                proxy: true

  # 4. If you implement more than 1 entry, add entries.
  # hello:
  #   name: ${self:service}-${self:custom.stackId}-${self:provider.stage}-hello
  #   handler: dist/serverless/bundles/hello.handler
  #   memorySize: 2048
  #   timeout: 10
  #   environment:
  #     NODE_ENV: production
  #   package:
  #     include:
  #       - dist/serverless/bundles/hello.js
  #     exclude:
  #       - '**'
  #   events:
  #     - http:
  #         path: /
  #         method: any
  #     - http:
  #         path: /{proxy+}
  #         method: any

Run deployment by serverless framework

# development stage
$ yarn deploy:dev

# staging stage
$ yarn deploy:stage

# production stage
$ yarn deploy:prod

6. To-do

  • Refactoring JS files to TypeScript
  • I18n Support

If you have a feature request, please create a new issue. And also, pull requests are always welcome🙏

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.