This commit is contained in:
Tommy Parnell
2022-04-07 10:01:20 -04:00
commit 6781fd5fdb
21 changed files with 17230 additions and 0 deletions

7
.env Normal file
View File

@@ -0,0 +1,7 @@
# Environment variables declared in this file are automatically made available to Prisma.
# See the documentation for more detail: https://pris.ly/d/prisma-schema#accessing-environment-variables-from-the-schema
# Prisma supports the native connection string format for PostgreSQL, MySQL, SQLite, SQL Server, MongoDB and CockroachDB (Preview).
# See the documentation for all the connection string options: https://pris.ly/d/connection-strings
DATABASE_URL="postgresql://admin:password@localhost:32760/app"

3
.eslintrc Normal file
View File

@@ -0,0 +1,3 @@
{
"extends": ["@remix-run/eslint-config", "@remix-run/eslint-config/node"]
}

7
.gitignore vendored Normal file
View File

@@ -0,0 +1,7 @@
node_modules
/.cache
/build
/public/build
*.env.*
!*.env

2
Procfile Normal file
View File

@@ -0,0 +1,2 @@
web: npm run start
release: npx prisma migrate deploy

15
README.md Normal file
View File

@@ -0,0 +1,15 @@
[![Deploy to Heroku](https://www.herokucdn.com/deploy/button.svg)](https://heroku.com/deploy?template=https://github.com/TerribleDev/remix-heroku)
# Remix stack for heroku
This is a very simple remix stack built for heroku. This includes:
* dotenv to load environment variables
* Postgres Sql for a datastore
* Prism ORM for database queries
## Developing
You can use `docker-compose up -d` to boot postgres locally, and the connection strings you need are in `.env`.
You should make an `.env.development` file to store all your local environment settings to keep out of git

28
app.json Normal file
View File

@@ -0,0 +1,28 @@
{
"name": "Remix on heroku",
"description": "A sample app showing remix on heroku with postgres",
"keywords": [
"react",
"remix",
"postgres"
],
"website": "https://github.com/TerribleDev/remix-heroku",
"repository": "https://github.com/TerribleDev/remix-heroku.git",
"success_url": "/",
"scripts": {},
"formation": {
"web": {
"quantity": 1,
"size": "hobby"
}
},
"addons": [
"heroku-postgresql"
],
"buildpacks": [
{
"url": "heroku/nodejs"
}
]
}

4
app/entry.client.tsx Normal file
View File

@@ -0,0 +1,4 @@
import { RemixBrowser } from "@remix-run/react";
import { hydrate } from "react-dom";
hydrate(<RemixBrowser />, document);

22
app/entry.server.tsx Normal file
View File

@@ -0,0 +1,22 @@
import 'dotenv/config'
import type { EntryContext } from "@remix-run/node";
import { RemixServer } from "@remix-run/react";
import { renderToString } from "react-dom/server";
export default function handleRequest(
request: Request,
responseStatusCode: number,
responseHeaders: Headers,
remixContext: EntryContext
) {
let markup = renderToString(
<RemixServer context={remixContext} url={request.url} />
);
responseHeaders.set("Content-Type", "text/html");
return new Response("<!DOCTYPE html>" + markup, {
status: responseStatusCode,
headers: responseHeaders,
});
}

32
app/root.tsx Normal file
View File

@@ -0,0 +1,32 @@
import type { MetaFunction } from "@remix-run/node";
import {
Links,
LiveReload,
Meta,
Outlet,
Scripts,
ScrollRestoration,
} from "@remix-run/react";
export const meta: MetaFunction = () => ({
charset: "utf-8",
title: "New Remix App",
viewport: "width=device-width,initial-scale=1",
});
export default function App() {
return (
<html lang="en">
<head>
<Meta />
<Links />
</head>
<body>
<Outlet />
<ScrollRestoration />
<Scripts />
<LiveReload />
</body>
</html>
);
}

30
app/routes/index.tsx Normal file
View File

@@ -0,0 +1,30 @@
import type { LoaderFunction } from "@remix-run/node";
import { json } from "@remix-run/node";
import { useLoaderData } from "@remix-run/react";
import type { Note } from "@prisma/client";
import { db } from "~/utils/db.server";
type LoaderData = { notes: Array<Note> };
export const loader: LoaderFunction = async () => {
const data: LoaderData = {
notes: await db.note.findMany(),
};
return json(data);
};
export default function Index() {
const data = useLoaderData<LoaderData>();
return (
<div style={{ fontFamily: "system-ui, sans-serif", lineHeight: "1.4" }}>
<h1>Welcome to Remix Heroku</h1>
<p> Notes: </p>
<ul>
{data.notes.map(({ id, name }) => ( <li key={name}>id: {id} name: {name}</li>))}
</ul>
</div>
);
}

21
app/utils/db.server.ts Normal file
View File

@@ -0,0 +1,21 @@
import { PrismaClient } from "@prisma/client";
let db: PrismaClient;
declare global {
var __db: PrismaClient | undefined;
}
// this is needed because in development we don't want to restart
// the server with every change, but we want to make sure we don't
// create a new connection to the DB with every change either.
if (process.env.NODE_ENV === "production") {
db = new PrismaClient();
} else {
if (!global.__db) {
global.__db = new PrismaClient();
}
db = global.__db;
}
export { db };

11
docker-compose.yml Normal file
View File

@@ -0,0 +1,11 @@
version: '3.1'
services:
db:
image: postgres
restart: always
ports:
- '32760:5432'
environment:
POSTGRES_PASSWORD: 'password'
POSTGRES_USER: 'admin'

16946
package-lock.json generated Normal file

File diff suppressed because it is too large Load Diff

37
package.json Normal file
View File

@@ -0,0 +1,37 @@
{
"name": "remix-template-remix",
"private": true,
"description": "",
"license": "",
"sideEffects": false,
"scripts": {
"build": "remix build",
"dev": "remix dev",
"start": "remix-serve build"
},
"dependencies": {
"@prisma/client": "^3.12.0",
"@remix-run/node": "^1.3.4",
"@remix-run/react": "^1.3.4",
"@remix-run/serve": "^1.3.4",
"dotenv": "^16.0.0",
"prisma": "^3.12.0",
"react": "^17.0.2",
"react-dom": "^17.0.2"
},
"devDependencies": {
"@remix-run/dev": "^1.3.4",
"@remix-run/eslint-config": "^1.3.4",
"@types/react": "^17.0.24",
"@types/react-dom": "^17.0.9",
"esbuild-register": "^3.3.2",
"eslint": "^8.11.0",
"typescript": "^4.5.5"
},
"prisma": {
"seed": "node --require esbuild-register prisma/seed.ts"
},
"engines": {
"node": ">=14"
}
}

View File

@@ -0,0 +1,7 @@
-- CreateTable
CREATE TABLE "Note" (
"id" SERIAL NOT NULL,
"name" TEXT NOT NULL,
CONSTRAINT "Note_pkey" PRIMARY KEY ("id")
);

View File

@@ -0,0 +1,3 @@
# Please do not edit this file manually
# It should be added in your version-control system (i.e. Git)
provider = "postgresql"

17
prisma/schema.prisma Normal file
View File

@@ -0,0 +1,17 @@
// This is your Prisma schema file,
// learn more about it in the docs: https://pris.ly/d/prisma-schema
generator client {
provider = "prisma-client-js"
}
datasource db {
provider = "postgresql"
url = env("DATABASE_URL")
}
model Note {
id Int @id @default(autoincrement())
name String
}

8
prisma/seed.ts Normal file
View File

@@ -0,0 +1,8 @@
import { PrismaClient } from "@prisma/client";
const db = new PrismaClient();
async function seed() {
return db.note.create({ data: { name: "Note from the databae" }});
}
seed();

BIN
public/favicon.ico Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 17 KiB

10
remix.config.js Normal file
View File

@@ -0,0 +1,10 @@
/**
* @type {import('@remix-run/dev').AppConfig}
*/
module.exports = {
ignoredRouteFiles: [".*"],
// appDirectory: "app",
// assetsBuildDirectory: "public/build",
// serverBuildPath: "build/index.js",
// publicPath: "/build/",
};

20
tsconfig.json Normal file
View File

@@ -0,0 +1,20 @@
{
"include": ["remix.env.d.ts", "**/*.ts", "**/*.tsx"],
"compilerOptions": {
"lib": ["DOM", "DOM.Iterable", "ES2019"],
"isolatedModules": true,
"esModuleInterop": true,
"jsx": "react-jsx",
"moduleResolution": "node",
"resolveJsonModule": true,
"target": "ES2019",
"strict": true,
"baseUrl": ".",
"paths": {
"~/*": ["./app/*"]
},
// Remix takes care of building everything in `remix build`.
"noEmit": true
}
}