mirror of
https://github.com/Aviortheking/nextjs-clone.git
synced 2025-04-22 02:42:10 +00:00
feat: Initial Commit
Signed-off-by: Avior <github@avior.me>
This commit is contained in:
commit
c467bccbe6
2
.gitignore
vendored
Normal file
2
.gitignore
vendored
Normal file
@ -0,0 +1,2 @@
|
||||
dist/
|
||||
node_modules
|
5
client.ts
Normal file
5
client.ts
Normal file
@ -0,0 +1,5 @@
|
||||
import ReactDOM from 'react-dom/client'
|
||||
|
||||
document.addEventListener('load', async () => {
|
||||
ReactDOM.hydrateRoot(document.body, )
|
||||
})
|
13
index.html
Normal file
13
index.html
Normal file
@ -0,0 +1,13 @@
|
||||
<!DOCTYPE html>
|
||||
<html lang="en">
|
||||
<head>
|
||||
<meta charset="UTF-8">
|
||||
<meta http-equiv="X-UA-Compatible" content="IE=edge">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||||
<title>Document</title>
|
||||
</head>
|
||||
<body>
|
||||
<div id="app"><!--ssr-outlet--></div>
|
||||
<script type="module" src="/src/entry-client.ts"></script>
|
||||
</body>
|
||||
</html>
|
72
main.ts
Normal file
72
main.ts
Normal file
@ -0,0 +1,72 @@
|
||||
import express, { Request } from 'express'
|
||||
import { createServer } from 'vite'
|
||||
import fs from 'fs/promises'
|
||||
|
||||
// const isProd = process.env.NODE_ENV === 'production'
|
||||
const isProd = true
|
||||
|
||||
;(async () => {
|
||||
const server = express()
|
||||
|
||||
const vite = await createServer({
|
||||
server: {middlewareMode: true},
|
||||
appType: 'custom'
|
||||
})
|
||||
|
||||
let index = await fs.readFile('./dist/client/index.html', 'utf-8')
|
||||
|
||||
console.log(process.env)
|
||||
if (!isProd) {
|
||||
index = await fs.readFile('./index.html', 'utf-8')
|
||||
}
|
||||
|
||||
server.use(vite.middlewares)
|
||||
|
||||
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 {
|
||||
const route = await vite.ssrLoadModule('/src/entry-server.tsx')
|
||||
render = route.render
|
||||
}
|
||||
|
||||
if (!render) {
|
||||
return res.status(500).end('Error')
|
||||
}
|
||||
|
||||
|
||||
const appHtml = await render(req)
|
||||
|
||||
const html = template.replace('<!--ssr-outlet-->', appHtml)
|
||||
|
||||
return res.status(200).set({'Content-Type': 'text/html'}).end(html)
|
||||
|
||||
// const url = req.path
|
||||
// const path = `./pages${url}`
|
||||
// const is404 = !(await exists(path))
|
||||
// if (is404) {
|
||||
// return res.status(404).send('404')
|
||||
// }
|
||||
// console.log(url)
|
||||
// const route = await import(path)
|
||||
// const props = await route.getServerProps()
|
||||
// res.send(`<!DOCTYPE html>` + renderToString(<App><route.default {...props} /></App>))
|
||||
})
|
||||
|
||||
server.listen(8080, () => {
|
||||
console.log('Server Started!')
|
||||
})
|
||||
})()
|
2604
package-lock.json
generated
Normal file
2604
package-lock.json
generated
Normal file
File diff suppressed because it is too large
Load Diff
27
package.json
Normal file
27
package.json
Normal file
@ -0,0 +1,27 @@
|
||||
{
|
||||
"name": "test",
|
||||
"version": "1.0.0",
|
||||
"type": "module",
|
||||
"scripts": {
|
||||
"dev": "ts-node -T --project tsconfig.json main.tsx",
|
||||
"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"
|
||||
},
|
||||
"dependencies": {
|
||||
"@dzeio/config": "^1.1.8",
|
||||
"@tcgdex/sdk": "^2.4.7",
|
||||
"express": "^4.18.2",
|
||||
"react": "^18.2.0",
|
||||
"react-dom": "^18.2.0",
|
||||
"ts-node": "^10.9.1",
|
||||
"typescript": "^4.8.4"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@types/express": "^4.17.14",
|
||||
"@types/node": "^18.11.9",
|
||||
"@types/react": "^18.0.24",
|
||||
"@types/react-dom": "^18.0.8",
|
||||
"vite": "^3.2.2"
|
||||
}
|
||||
}
|
1
public/test.json
Normal file
1
public/test.json
Normal file
@ -0,0 +1 @@
|
||||
{"pouet": true}
|
10
src/Utils.ts
Normal file
10
src/Utils.ts
Normal file
@ -0,0 +1,10 @@
|
||||
import fs from 'fs/promises'
|
||||
|
||||
export async function exists(path: string): Promise<boolean> {
|
||||
try {
|
||||
await fs.access(path + `.tsx`)
|
||||
return true
|
||||
} catch {
|
||||
return false
|
||||
}
|
||||
}
|
0
src/entry-client.ts
Normal file
0
src/entry-client.ts
Normal file
21
src/entry-server.tsx
Normal file
21
src/entry-server.tsx
Normal file
@ -0,0 +1,21 @@
|
||||
import { exists } from './Utils'
|
||||
import { renderToString } from 'react-dom/server'
|
||||
import App from './pages/_app'
|
||||
import React from 'react'
|
||||
import { Request } from 'express'
|
||||
import path from 'path'
|
||||
import { fileURLToPath } from 'url'
|
||||
|
||||
const __dirname = path.dirname(fileURLToPath(import.meta.url))
|
||||
|
||||
export const render = async (req: Request) => {
|
||||
const path = `${__dirname}/pages${req.path}`
|
||||
console.log(req.path, __dirname)
|
||||
const is404 = !(await exists(path))
|
||||
if (is404) {
|
||||
return '404'
|
||||
}
|
||||
const route = await import(`${__dirname}/pages${req.path}.tsx`)
|
||||
const props = await route.getServerProps()
|
||||
return (`<!DOCTYPE html>` + renderToString(<App><route.default {...props} /></App>))
|
||||
}
|
22
src/pages/_app.tsx
Normal file
22
src/pages/_app.tsx
Normal file
@ -0,0 +1,22 @@
|
||||
import React from 'react'
|
||||
|
||||
interface AppProps {
|
||||
children: React.ReactNode
|
||||
}
|
||||
|
||||
export default class App extends React.Component<AppProps> {
|
||||
public render = () => (
|
||||
<>
|
||||
<html>
|
||||
<head>
|
||||
<script
|
||||
type='application/json'
|
||||
id="__PROPS"
|
||||
dangerouslySetInnerHTML={{__html: JSON.stringify(this.props)}}
|
||||
></script>
|
||||
</head>
|
||||
<body>{this.props.children}</body>
|
||||
</html>
|
||||
</>
|
||||
)
|
||||
}
|
17
src/pages/path.tsx
Normal file
17
src/pages/path.tsx
Normal file
@ -0,0 +1,17 @@
|
||||
import React from 'react'
|
||||
import TCGdex, { Card } from '@tcgdex/sdk'
|
||||
|
||||
export default class Component extends React.Component<{card: Card}> {
|
||||
|
||||
public render = () => (
|
||||
<div>{this.props.card.name}</div>
|
||||
)
|
||||
}
|
||||
|
||||
|
||||
export const getServerProps = async () => {
|
||||
const tcgdex = new TCGdex()
|
||||
return {
|
||||
card: await tcgdex.fetchCard('bw1-1')
|
||||
}
|
||||
}
|
17
src/pages/set.tsx
Normal file
17
src/pages/set.tsx
Normal file
@ -0,0 +1,17 @@
|
||||
import React from 'react'
|
||||
import TCGdex, { Card, Set } from '@tcgdex/sdk'
|
||||
|
||||
export default class Component extends React.Component<{card: Set}> {
|
||||
|
||||
public render = () => (
|
||||
<div onClick={() => console.log('YOLO')}>{this.props.card.name}</div>
|
||||
)
|
||||
}
|
||||
|
||||
|
||||
export const getServerProps = async () => {
|
||||
const tcgdex = new TCGdex()
|
||||
return {
|
||||
card: await tcgdex.fetchSet('bw1')
|
||||
}
|
||||
}
|
16
tsconfig.json
Normal file
16
tsconfig.json
Normal file
@ -0,0 +1,16 @@
|
||||
{
|
||||
//"extends": "./node_modules/@dzeio/config/tsconfig.base.json",
|
||||
"compilerOptions": {
|
||||
"jsx": "react-jsx",
|
||||
"outDir": "dist",
|
||||
"target": "ES2022",
|
||||
"module": "NodeNext",
|
||||
"skipLibCheck": true
|
||||
},
|
||||
"files": [
|
||||
"main.ts"
|
||||
],
|
||||
"exclude": [
|
||||
"node_modules"
|
||||
]
|
||||
}
|
3
tsconfig.prod.json
Normal file
3
tsconfig.prod.json
Normal file
@ -0,0 +1,3 @@
|
||||
{
|
||||
"extends": "./node_modules/@dzeio/config/tsconfig.esm.json"
|
||||
}
|
Loading…
x
Reference in New Issue
Block a user