feat: updated

Signed-off-by: Avior <f.bouillon@aptatio.com>
This commit is contained in:
Florian Bouillon 2022-11-24 12:07:30 +01:00
parent c467bccbe6
commit e19db6ee5c
Signed by: Florian Bouillon
GPG Key ID: E05B3A94178D3A7C
18 changed files with 2748 additions and 2659 deletions

1
.env Normal file
View File

@ -0,0 +1 @@
#NODE_ENV=production

1
.env.prod Normal file
View File

@ -0,0 +1 @@
NODE_ENV=production

View File

@ -1,5 +0,0 @@
import ReactDOM from 'react-dom/client'
document.addEventListener('load', async () => {
ReactDOM.hydrateRoot(document.body, )
})

View File

@ -8,6 +8,6 @@
</head>
<body>
<div id="app"><!--ssr-outlet--></div>
<script type="module" src="/src/entry-client.ts"></script>
<script type="module" src="/src/entry-client.tsx"></script>
</body>
</html>

49
main.ts
View File

@ -1,17 +1,29 @@
import express, { Request } from 'express'
import { createServer } from 'vite'
import { createServer, ViteDevServer } from 'vite'
import fs from 'fs/promises'
// const isProd = process.env.NODE_ENV === 'production'
const isProd = true
const isProd = process.env.NODE_ENV === 'production'
// const isProd = false //true
// if (isProd) {
// process.env.NODE_ENV = 'production'
// } else {
// process.env.NODE_ENV = 'development'
// }
let vite: ViteDevServer | null = null
;(async () => {
const server = express()
const vite = await createServer({
if (!isProd) {
vite = await createServer({
server: {middlewareMode: true},
appType: 'custom'
})
server.use(vite.middlewares)
}
let index = await fs.readFile('./dist/client/index.html', 'utf-8')
@ -20,33 +32,40 @@ const isProd = true
index = await fs.readFile('./index.html', 'utf-8')
}
server.use(vite.middlewares)
if (isProd) {
server.use('/assets', express.static('./dist/client/assets'))
}
server.use('/', express.static('public'))
server.use(async (req, res) => {
const url = req.originalUrl
const template = await vite.transformIndexHtml(url, index)
let render: ((url: Request) => Promise<string>) | null = null
if (isProd) {
/** @ts-expect-error why not m*therfucker */
const route: any = await import('./server/entry-server.js')
render = route.render as any
} else {
} else if (vite) {
const route = await vite.ssrLoadModule('/src/entry-server.tsx')
render = route.render
}
if (!render) {
return res.status(500).end('Error')
throw new Error('Renderer not found :O')
process.exit(1)
}
server.use(async (req, res) => {
const url = req.originalUrl
let template: string = index
if (vite) {
template = await vite.transformIndexHtml(url, index)
}
if (!render) {
throw new Error('Renderer not found :O')
}
const appHtml = await render(req)

14
package-lock.json generated
View File

@ -10,6 +10,7 @@
"dependencies": {
"@dzeio/config": "^1.1.8",
"@tcgdex/sdk": "^2.4.7",
"dotenv": "^16.0.3",
"express": "^4.18.2",
"react": "^18.2.0",
"react-dom": "^18.2.0",
@ -416,6 +417,14 @@
"node": ">=0.3.1"
}
},
"node_modules/dotenv": {
"version": "16.0.3",
"resolved": "https://registry.npmjs.org/dotenv/-/dotenv-16.0.3.tgz",
"integrity": "sha512-7GO6HghkA5fYG9TYnNxi14/7K9f5occMlp3zXAuSxn7CKCxt9xbNWG7yF8hTCSUchlfWSe3uLmlPfigevRItzQ==",
"engines": {
"node": ">=12"
}
},
"node_modules/ee-first": {
"version": "1.1.1",
"resolved": "https://registry.npmjs.org/ee-first/-/ee-first-1.1.1.tgz",
@ -1885,6 +1894,11 @@
"resolved": "https://registry.npmjs.org/diff/-/diff-4.0.2.tgz",
"integrity": "sha512-58lmxKSA4BNyLz+HHMUzlOEpg09FV+ev6ZMe3vJihgdxzgcwZ8VoEEPmALCZG9LmqfVoNMMKpttIYTVG6uDY7A=="
},
"dotenv": {
"version": "16.0.3",
"resolved": "https://registry.npmjs.org/dotenv/-/dotenv-16.0.3.tgz",
"integrity": "sha512-7GO6HghkA5fYG9TYnNxi14/7K9f5occMlp3zXAuSxn7CKCxt9xbNWG7yF8hTCSUchlfWSe3uLmlPfigevRItzQ=="
},
"ee-first": {
"version": "1.1.1",
"resolved": "https://registry.npmjs.org/ee-first/-/ee-first-1.1.1.tgz",

View File

@ -3,14 +3,16 @@
"version": "1.0.0",
"type": "module",
"scripts": {
"dev": "ts-node -T --project tsconfig.json main.tsx",
"dev": "NODE_ENV=\"development\" ts-node-esm -T --project tsconfig.json main.ts",
"build": "npm run build:client && npm run build:server",
"build:client": "vite build --outDir dist/client --ssrManifest",
"build:server": "vite build --outDir dist/server --ssr src/entry-server.tsx && tsc --project tsconfig.json"
"build:server": "vite build --outDir dist/server --ssr src/entry-server.tsx && tsc --project tsconfig.pages.json && tsc --project tsconfig.json",
"start": "NODE_ENV=\"production\" node dist/main.js"
},
"dependencies": {
"@dzeio/config": "^1.1.8",
"@tcgdex/sdk": "^2.4.7",
"dotenv": "^16.0.3",
"express": "^4.18.2",
"react": "^18.2.0",
"react-dom": "^18.2.0",

View File

@ -2,7 +2,7 @@ import fs from 'fs/promises'
export async function exists(path: string): Promise<boolean> {
try {
await fs.access(path + `.tsx`)
await fs.access(path)
return true
} catch {
return false

View File

11
src/entry-client.tsx Normal file
View File

@ -0,0 +1,11 @@
import React from 'react'
import App from './pages/_app'
import Path from './pages/path'
import { hydrateRoot } from 'react-dom/client'
import type { CommProps } from './interfaces'
(async () => {
const __PROPS: CommProps = JSON.parse((window as any).__PROPS.innerText)
console.log(__PROPS)
hydrateRoot(document.getElementById('app') as HTMLDivElement, <App component={Path} path={__PROPS.path} pageProps={__PROPS.pageProps} />)
})()

View File

@ -7,15 +7,17 @@ import path from 'path'
import { fileURLToPath } from 'url'
const __dirname = path.dirname(fileURLToPath(import.meta.url))
const ext = process.env.NODE_ENV === 'production' ? '.js' : '.tsx'
export const render = async (req: Request) => {
const path = `${__dirname}/pages${req.path}`
console.log(req.path, __dirname)
const path = `${__dirname}/pages${req.path}${ext}`
const is404 = !(await exists(path))
console.log(req.path, path, is404)
if (is404) {
return '404'
}
const route = await import(`${__dirname}/pages${req.path}.tsx`)
/* @vite-ignore */
const route = await import(path)
const props = await route.getServerProps()
return (`<!DOCTYPE html>` + renderToString(<App><route.default {...props} /></App>))
return renderToString(<App component={route.default} path={req.path} pageProps={props} />)
}

4
src/interfaces.d.ts vendored Normal file
View File

@ -0,0 +1,4 @@
export interface CommProps {
pageProps: any
path: string
}

View File

@ -1,22 +1,24 @@
import React from 'react'
import type { CommProps } from '../interfaces'
interface AppProps {
children: React.ReactNode
component: any
path: string
pageProps: any
}
export default class App extends React.Component<AppProps> {
public render = () => (
<>
<html>
<head>
<script
type='application/json'
id="__PROPS"
dangerouslySetInnerHTML={{__html: JSON.stringify(this.props)}}
dangerouslySetInnerHTML={{__html: JSON.stringify({
pageProps: this.props.pageProps,
path: this.props.path
} as CommProps)}}
></script>
</head>
<body>{this.props.children}</body>
</html>
<this.props.component {...this.props.pageProps} />
</>
)
}

View File

@ -1,16 +1,20 @@
import React from 'react'
import TCGdex, { Card } from '@tcgdex/sdk'
import TCGdex from '@tcgdex/sdk'
import type { Card } from '@tcgdex/sdk'
export default class Component extends React.Component<{card: Card}> {
public componentDidMount(): void {
console.log('YaY')
}
public render = () => (
<div>{this.props.card.name}</div>
)
}
export const getServerProps = async () => {
const tcgdex = new TCGdex()
const tcgdex = new TCGdex.default()
return {
card: await tcgdex.fetchCard('bw1-1')
}

View File

@ -1,5 +1,6 @@
import React from 'react'
import TCGdex, { Card, Set } from '@tcgdex/sdk'
import type { Set } from '@tcgdex/sdk'
import TCGdex from '@tcgdex/sdk'
export default class Component extends React.Component<{card: Set}> {

View File

@ -5,7 +5,32 @@
"outDir": "dist",
"target": "ES2022",
"module": "NodeNext",
"skipLibCheck": true
"skipLibCheck": true,
"moduleResolution": "NodeNext",
"esModuleInterop": true,
"experimentalDecorators": true,
"emitDecoratorMetadata": true,
"allowJs": true,
"pretty": true,
"allowSyntheticDefaultImports": true,
// Type Checking
"forceConsistentCasingInFileNames": true,
"alwaysStrict": true,
"strict": true,
"strictNullChecks": true,
"strictFunctionTypes": true,
"strictBindCallApply": true,
"strictPropertyInitialization": true,
"noImplicitAny": true,
"noImplicitThis": true,
"noUnusedLocals": true,
"noUnusedParameters": true,
"noImplicitReturns": true,
"noFallthroughCasesInSwitch": true
},
"files": [
"main.ts"

11
tsconfig.pages.json Normal file
View File

@ -0,0 +1,11 @@
{
"extends": "./tsconfig.json",
"files": [],
"include": [
"src/pages"
],
"compilerOptions": {
"baseUrl": "src",
"outDir": "dist/server/pages",
}
}

View File

@ -1,3 +0,0 @@
{
"extends": "./node_modules/@dzeio/config/tsconfig.esm.json"
}