Skip to content

Commit

Permalink
Add README
Browse files Browse the repository at this point in the history
  • Loading branch information
hoshinotsuyoshi committed Oct 19, 2024
1 parent bfe3f7a commit c1089f0
Showing 1 changed file with 166 additions and 0 deletions.
166 changes: 166 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,166 @@
# Monorepo for Rails GraphQL API and Vite + React SPA

This monorepo hosts two main applications:
- A **Rails GraphQL API** running in API mode located in `./backend`
- A **Vite + React Single Page Application (SPA)** located in `./frontend`

## Project Structure

```bash
$ tree -L 2
.
├── backend # Rails GraphQL API (API mode)
│   ├── Dockerfile # Dockerfile for the Rails backend
│   ├── Gemfile # Gem dependencies
│   ├── Gemfile.lock
│   ├── README.md
│   ├── app # Rails application code
│   ├── config # Rails configuration
│   ├── public # Contains compiled frontend assets
│   ├── spec # RSpec tests
│   └── ...
├── frontend # Vite + React SPA
│   ├── README.md
│   ├── package.json # Frontend dependencies and scripts
│   ├── src # React source code
│   ├── dist # Build output for the frontend app
│   └── ...
└── graphql-schema # GraphQL schema files
└── backend_schema.graphql
```

## Deployment Process

The deployment process involves building the frontend, syncing the build artifacts to the Rails `public/` directory using `rsync`, and building the Docker image for the Rails API.

### Steps:

1. **Build the frontend**
Navigate to the `frontend` directory and run the build command using Bun. This compiles the React app and outputs the assets to `frontend/dist/`:
```bash
cd frontend && bun run build
```

2. **Move frontend build artifacts to Rails**
After the frontend build is complete, the compiled assets are moved into the Rails public directory using `rsync` for efficient file synchronization:
```bash
rsync -av --delete dist/index.html ../backend/public/
rsync -av --delete dist/assets/ ../backend/public/assets/
touch ../backend/public/assets/.keep
```

This ensures that the frontend's `index.html` and `assets/` files are correctly placed in the `backend/public/` directory. The `.keep` file ensures that the `assets/` directory is maintained even if it is empty.

3. **Build the Docker image**
After the assets are moved, the Rails backend can be built into a Docker image:
```bash
cd backend && docker build -t my-spa .
```

### Example Script

Here’s a simple shell script that combines the above steps:

```bash
#!/bin/bash

# 1. Build the frontend
cd frontend && bun run build

# 2. Move build artifacts to Rails public directory
rsync -av --delete dist/index.html ../backend/public/
rsync -av --delete dist/assets/ ../backend/public/assets/
touch ../backend/public/assets/.keep

# 3. Build the Docker image for Rails API
cd ../backend && docker build -t my-spa .
```

## Rails Setup (API Mode)

The Rails application serves the frontend SPA's assets for specific routes listed in `config/routes.rb`. These routes point to a static controller, which renders the `index.html` file served by the frontend.

```ruby
# config/routes.rb
to = "static#index"
[
"/login",
"/me",
"/onboarding/verify_email_address",
"/set_password",
"/signup",
].each { get _1, to: }
```

The `StaticController` reads the `index.html` from the `public` directory and serves it as the response for these routes:

```ruby
# app/controllers/static_controller.rb
class StaticController < ApplicationController
def index
response.headers['Content-Type'] = 'text/html'
render plain: Rails.public_path.join('index.html').read, layout: false
end
end
```

### Cookies Support

To manage cookies, the Rails API is configured to include `ActionController::Cookies`:

```ruby
class ApplicationController < ActionController::API
include ActionController::Cookies
end
```

This allows cookies to be used even though Rails is running in API mode.

## Frontend Development

The frontend is a Vite-powered React SPA, and Bun is used as the package manager. The primary build scripts are defined in `frontend/package.json`:

```json
{
"name": "my-spa",
"packageManager": "[email protected]",
"private": true,
"scripts": {
"prepare": "panda codegen",
"dev": "vite",
"build": "tsc -b && vite build",
"build:move": "bun run build && bun run move-assets",
"move-assets": "rsync -av --delete dist/index.html ../backend/public/ && rsync -av --delete dist/assets/ ../backend/public/assets/ && touch ../backend/public/assets/.keep",
"preview": "vite preview",
"graphql-codegen": "graphql-codegen"
}
}
```

Key commands include:
- `bun run dev`: Starts the Vite development server for live preview.
- `bun run build`: Builds the production assets for deployment.
- `bun run build:move`: Combines the build process and moves the build artifacts into the Rails public directory.

## Running Locally

1. **Install dependencies**
Make sure you have `bun` installed and run the following command from the root of the monorepo:
```bash
bun install
```

2. **Build the frontend**
Build the frontend and move the assets to the backend's public directory:
```bash
bun run build:move
```

3. **Build the Docker image for the Rails API**
Navigate to the `backend` directory and build the Docker image:
```bash
cd backend && docker build -t my-spa .
```

4. **Run the Rails server**
After the Docker image is built, you can run the server and test the integration locally.

0 comments on commit c1089f0

Please sign in to comment.