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