-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
1 parent
bfe3f7a
commit c1089f0
Showing
1 changed file
with
166 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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. |