@zikojs/server 0.1.0 → 0.3.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/package.json +47 -63
- package/src/index.js +1 -4
- package/src/middlewares/index.js +2 -0
- package/src/middlewares/setupEnvironmentMiddleware.js +37 -0
- package/src/middlewares/trailingSlashMiddleware.js +103 -0
- package/src/server/index.js +87 -105
- package/src/server-only-utils/globImports.d.ts +73 -0
- package/src/server-only-utils/globImports.js +50 -0
- package/src/server-only-utils/index.js +1 -9
- package/README.md +0 -72
- package/src/code-splitter/directives.js +0 -5
- package/src/code-splitter/index.js +0 -1
- package/src/config/index.js +0 -13
- package/src/count.sh +0 -9
- package/src/entry-client/index.js +0 -45
- package/src/entry-server/index.js +0 -39
- package/src/prerender/index.js +0 -63
- package/src/server/api-handler.js +0 -22
- package/src/server/dev-server.js +0 -21
- package/src/server/response.js +0 -6
- package/src/server/setup-middleware.js +0 -21
- package/src/server-only-utils/glob-imports.js +0 -47
- package/src/server-only-utils/import-middlwares.js +0 -29
- package/src/server-only-utils/import-prerendered-routes.js +0 -11
- package/src/server-only-utils/index.d.ts.txt +0 -3
- package/src/server-only-utils/manifest-parser.js +0 -22
- package/src/server-only-utils/read-files.js +0 -20
- package/src/server-only-utils/renderDomToString.js +0 -8
- package/src/server-only-utils/renderToString.js +0 -8
- package/src/server-only-utils/resolve-static-routes.js +0 -64
- package/src/server-only-utils/write-to-dist.js +0 -24
- package/src/setup/files-content.js +0 -53
- package/src/setup/generate-hydration-map.js +0 -3
- package/src/setup/generate-routes.js +0 -22
- package/src/setup/index.js +0 -3
- package/src/setup/setup-ziko-folder.js +0 -16
- package/src/template.js +0 -14
- package/src/utils/api.js +0 -7
- package/src/utils/html-template.js +0 -19
- package/src/utils/index.js +0 -4
- package/src/utils/isAsync.js +0 -3
- package/src/utils/normalize-path.js +0 -21
- package/src/utils/routes-matcher.js +0 -216
- package/src/vite/index.js +0 -1
- package/src/vite/vite_setup.js +0 -37
- package/types/global.d.ts +0 -11
package/package.json
CHANGED
|
@@ -1,63 +1,47 @@
|
|
|
1
|
-
{
|
|
2
|
-
"name": "@zikojs/server",
|
|
3
|
-
"version": "0.
|
|
4
|
-
"description": "
|
|
5
|
-
"
|
|
6
|
-
"
|
|
7
|
-
|
|
8
|
-
"
|
|
9
|
-
"
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
"
|
|
19
|
-
},
|
|
20
|
-
"
|
|
21
|
-
"
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
"
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
"
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
"
|
|
38
|
-
"
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
"@rollup/plugin-node-resolve": "^16.0.3",
|
|
49
|
-
"@rollup/plugin-terser": "^1.0.0",
|
|
50
|
-
"rollup": "^4.62.4"
|
|
51
|
-
},
|
|
52
|
-
"dependencies": {
|
|
53
|
-
"compression": "^1.8.1",
|
|
54
|
-
"cross-env": "^10.1.0",
|
|
55
|
-
"express": "^5.2.1",
|
|
56
|
-
"extendom": "^0.0.0",
|
|
57
|
-
"fast-glob": "^3.3.3",
|
|
58
|
-
"jsdom": "^30.0.1",
|
|
59
|
-
"sirv": "^3.0.2",
|
|
60
|
-
"vite": "^8.2.1",
|
|
61
|
-
"ziko": "^1.8.0"
|
|
62
|
-
}
|
|
63
|
-
}
|
|
1
|
+
{
|
|
2
|
+
"name": "@zikojs/server",
|
|
3
|
+
"version": "0.3.0",
|
|
4
|
+
"description": "",
|
|
5
|
+
"main": "index.js",
|
|
6
|
+
"keywords": [
|
|
7
|
+
"zikojs",
|
|
8
|
+
"server",
|
|
9
|
+
"express"
|
|
10
|
+
],
|
|
11
|
+
"homepage": "https://github.com/zikojs/ziko#readme",
|
|
12
|
+
"bugs": {
|
|
13
|
+
"url": "https://github.com/zikojs/ziko/issues"
|
|
14
|
+
},
|
|
15
|
+
"repository": {
|
|
16
|
+
"type": "git",
|
|
17
|
+
"url": "git+https://github.com/zikojs/ziko.git",
|
|
18
|
+
"directory": "packages/adapters/express"
|
|
19
|
+
},
|
|
20
|
+
"publishConfig": {
|
|
21
|
+
"access": "public"
|
|
22
|
+
},
|
|
23
|
+
"exports": {
|
|
24
|
+
".": {
|
|
25
|
+
"import": "./src/index.js"
|
|
26
|
+
},
|
|
27
|
+
"./*": {
|
|
28
|
+
"import": "./src/*/index.js"
|
|
29
|
+
}
|
|
30
|
+
},
|
|
31
|
+
"author": "zakaria elalaoui",
|
|
32
|
+
"license": "MIT",
|
|
33
|
+
"type": "module",
|
|
34
|
+
"dependencies": {
|
|
35
|
+
"@zikojs/server-express": "0.1.0",
|
|
36
|
+
"@zikojs/server-http": "0.1.0",
|
|
37
|
+
"compression": "^1.8.1",
|
|
38
|
+
"express": "^5.2.1",
|
|
39
|
+
"fast-glob": "^3.3.3",
|
|
40
|
+
"sirv": "^3.0.2",
|
|
41
|
+
"vite": "^8.2.2",
|
|
42
|
+
"ziko": "^2.0.0-beta.7"
|
|
43
|
+
},
|
|
44
|
+
"scripts": {
|
|
45
|
+
"test": "echo \"Error: no test specified\" && exit 1"
|
|
46
|
+
}
|
|
47
|
+
}
|
package/src/index.js
CHANGED
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
const isProduction = process.env.NODE_ENV === 'production'
|
|
2
|
+
/**
|
|
3
|
+
* Sets up environment-specific middleware.
|
|
4
|
+
*/
|
|
5
|
+
export async function setupEnvironmentMiddleware({ adapterInstance, rootDir, urlBase, clientDistPath }) {
|
|
6
|
+
if (process.env.NODE_ENV !== 'production') {
|
|
7
|
+
const { createServer: createViteServer } = await import('vite')
|
|
8
|
+
const vite = await createViteServer({
|
|
9
|
+
root: rootDir,
|
|
10
|
+
server: { middlewareMode: true },
|
|
11
|
+
appType: 'custom',
|
|
12
|
+
base: urlBase,
|
|
13
|
+
})
|
|
14
|
+
|
|
15
|
+
// Vite handles all dev transformation and /@vite/client asset requests
|
|
16
|
+
adapterInstance.use(vite.middlewares)
|
|
17
|
+
return vite
|
|
18
|
+
}
|
|
19
|
+
|
|
20
|
+
// PRODUCTION MODE: Serve static client assets from dist/client
|
|
21
|
+
const compression = (await import('compression')).default
|
|
22
|
+
const sirv = (await import('sirv')).default
|
|
23
|
+
|
|
24
|
+
adapterInstance.use(compression())
|
|
25
|
+
|
|
26
|
+
// Serve all built assets (JS, CSS, images, favicon) from dist/client
|
|
27
|
+
adapterInstance.usePath(
|
|
28
|
+
urlBase,
|
|
29
|
+
sirv(clientDistPath, {
|
|
30
|
+
dev: false,
|
|
31
|
+
single: false, // Allows static assets to return 404 rather than falling back to HTML
|
|
32
|
+
extensions: []
|
|
33
|
+
})
|
|
34
|
+
)
|
|
35
|
+
|
|
36
|
+
return undefined
|
|
37
|
+
}
|
|
@@ -0,0 +1,103 @@
|
|
|
1
|
+
const isProduction = process.env.NODE_ENV === 'production'
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* Handles trailing slashes based on the specified behavior strategy.
|
|
5
|
+
*
|
|
6
|
+
* @param {'ignore' | 'always' | 'never'} behavior
|
|
7
|
+
* @param {import('http').IncomingMessage} req
|
|
8
|
+
* @param {import('http').ServerResponse} res
|
|
9
|
+
* @param {Function} next
|
|
10
|
+
*/
|
|
11
|
+
export function trailingSlashMiddleware(behavior, req, res, next) {
|
|
12
|
+
// 1. Skip middleware if behavior is 'ignore'
|
|
13
|
+
if (!behavior || behavior === 'ignore') {
|
|
14
|
+
return next()
|
|
15
|
+
}
|
|
16
|
+
|
|
17
|
+
const rawUrl = req.originalUrl || req.url
|
|
18
|
+
const [pathname, search] = rawUrl.split('?')
|
|
19
|
+
const queryString = search ? `?${search}` : ''
|
|
20
|
+
|
|
21
|
+
// Don't redirect the root path '/' or URLs pointing to static files (e.g. assets)
|
|
22
|
+
const isRoot = pathname === '/'
|
|
23
|
+
const isFile = /\.[a-zA-Z0-9]+$/.test(pathname)
|
|
24
|
+
|
|
25
|
+
if (isRoot || isFile) {
|
|
26
|
+
return next()
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
const hasTrailingSlash = pathname.endsWith('/')
|
|
30
|
+
|
|
31
|
+
// ---------------------------------------------------------------------------
|
|
32
|
+
// Case A: Behavior 'never' -> Require NO trailing slash (e.g. /about)
|
|
33
|
+
// ---------------------------------------------------------------------------
|
|
34
|
+
if (behavior === 'never' && hasTrailingSlash) {
|
|
35
|
+
const targetPath = pathname.replace(/\/+$/, '')
|
|
36
|
+
const targetUrl = targetPath + queryString
|
|
37
|
+
|
|
38
|
+
if (!isProduction) {
|
|
39
|
+
const warningHtml = `
|
|
40
|
+
<!DOCTYPE html>
|
|
41
|
+
<html>
|
|
42
|
+
<head>
|
|
43
|
+
<title>Trailing Slash Warning</title>
|
|
44
|
+
<style>
|
|
45
|
+
body { font-family: system-ui, sans-serif; padding: 2rem; background: #1a1a1a; color: #fff; line-height: 1.6; }
|
|
46
|
+
.card { background: #2a2a2a; border-left: 4px solid #f39c12; padding: 1.5rem; border-radius: 6px; max-width: 600px; }
|
|
47
|
+
code { background: #333; padding: 0.2rem 0.4rem; border-radius: 4px; color: #e74c3c; }
|
|
48
|
+
a { color: #3498db; }
|
|
49
|
+
</style>
|
|
50
|
+
</head>
|
|
51
|
+
<body>
|
|
52
|
+
<div class="card">
|
|
53
|
+
<h2>[ZikoJS Dev Warning] Trailing Slash Mismatch</h2>
|
|
54
|
+
<p>Requested URL: <code>${rawUrl}</code></p>
|
|
55
|
+
<p>Your trailing slash strategy is configured to <strong>'never'</strong>, but this request includes a trailing slash.</p>
|
|
56
|
+
<p>In production, this request will automatically redirect (301) to: <a href="${targetUrl}"><code>${targetUrl}</code></a></p>
|
|
57
|
+
</div>
|
|
58
|
+
</body>
|
|
59
|
+
</html>
|
|
60
|
+
`
|
|
61
|
+
return res.status(200).set({ 'Content-Type': 'text/html' }).send(warningHtml)
|
|
62
|
+
}
|
|
63
|
+
|
|
64
|
+
return res.status(301).set({ Location: targetUrl }).send()
|
|
65
|
+
}
|
|
66
|
+
|
|
67
|
+
// ---------------------------------------------------------------------------
|
|
68
|
+
// Case B: Behavior 'always' -> Require trailing slash (e.g. /about/)
|
|
69
|
+
// ---------------------------------------------------------------------------
|
|
70
|
+
if (behavior === 'always' && !hasTrailingSlash) {
|
|
71
|
+
const targetUrl = `${pathname}/${queryString}`
|
|
72
|
+
|
|
73
|
+
if (!isProduction) {
|
|
74
|
+
const warningHtml = `
|
|
75
|
+
<!DOCTYPE html>
|
|
76
|
+
<html>
|
|
77
|
+
<head>
|
|
78
|
+
<title>Trailing Slash Warning</title>
|
|
79
|
+
<style>
|
|
80
|
+
body { font-family: system-ui, sans-serif; padding: 2rem; background: #1a1a1a; color: #fff; line-height: 1.6; }
|
|
81
|
+
.card { background: #2a2a2a; border-left: 4px solid #f39c12; padding: 1.5rem; border-radius: 6px; max-width: 600px; }
|
|
82
|
+
code { background: #333; padding: 0.2rem 0.4rem; border-radius: 4px; color: #e74c3c; }
|
|
83
|
+
a { color: #3498db; }
|
|
84
|
+
</style>
|
|
85
|
+
</head>
|
|
86
|
+
<body>
|
|
87
|
+
<div class="card">
|
|
88
|
+
<h2>[ZikoJS Dev Warning] Trailing Slash Mismatch</h2>
|
|
89
|
+
<p>Requested URL: <code>${rawUrl}</code></p>
|
|
90
|
+
<p>Your trailing slash strategy is configured to <strong>'always'</strong>, but this request is missing a trailing slash.</p>
|
|
91
|
+
<p>In production, this request will automatically redirect (301) to: <a href="${targetUrl}"><code>${targetUrl}</code></a></p>
|
|
92
|
+
</div>
|
|
93
|
+
</body>
|
|
94
|
+
</html>
|
|
95
|
+
`
|
|
96
|
+
return res.status(200).set({ 'Content-Type': 'text/html' }).send(warningHtml)
|
|
97
|
+
}
|
|
98
|
+
|
|
99
|
+
return res.status(301).set({ Location: targetUrl }).send()
|
|
100
|
+
}
|
|
101
|
+
|
|
102
|
+
next()
|
|
103
|
+
}
|
package/src/server/index.js
CHANGED
|
@@ -1,105 +1,87 @@
|
|
|
1
|
-
import
|
|
2
|
-
import
|
|
3
|
-
import
|
|
4
|
-
import {
|
|
5
|
-
import {
|
|
6
|
-
import
|
|
7
|
-
import {
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
} from '../
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
//
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
let
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
template = await
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
const
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
.replace(`<!--app-html-->`, page.ui ?? "")
|
|
89
|
-
|
|
90
|
-
res.status(200).set({ "Content-Type": "text/html" }).send(html);
|
|
91
|
-
}
|
|
92
|
-
catch (e) {
|
|
93
|
-
vite?.ssrFixStacktrace(e);
|
|
94
|
-
res.status(500).end(e.stack);
|
|
95
|
-
}
|
|
96
|
-
});
|
|
97
|
-
|
|
98
|
-
app.listen(port, () => {
|
|
99
|
-
console.log(`Server started at http://localhost:${port}`);
|
|
100
|
-
});
|
|
101
|
-
|
|
102
|
-
return app;
|
|
103
|
-
}
|
|
104
|
-
|
|
105
|
-
|
|
1
|
+
import fs from 'node:fs/promises'
|
|
2
|
+
import path from 'node:path'
|
|
3
|
+
import { pathToFileURL } from 'node:url' // <--- 1. Import pathToFileURL
|
|
4
|
+
import { httpAdapter } from '@zikojs/server-http'
|
|
5
|
+
import { expressAdapter } from '@zikojs/server-express'
|
|
6
|
+
import express from 'express'
|
|
7
|
+
import {
|
|
8
|
+
setupEnvironmentMiddleware,
|
|
9
|
+
trailingSlashMiddleware
|
|
10
|
+
} from '../middlewares/index.js'
|
|
11
|
+
|
|
12
|
+
const isProduction = process.env.NODE_ENV === 'production'
|
|
13
|
+
|
|
14
|
+
export async function createServer({
|
|
15
|
+
adapter = expressAdapter,
|
|
16
|
+
port = process.env.PORT || 5173,
|
|
17
|
+
base = process.env.BASE || '/',
|
|
18
|
+
trailingSlash = 'never',
|
|
19
|
+
cwd = process.cwd()
|
|
20
|
+
} = {}) {
|
|
21
|
+
const rootDir = cwd
|
|
22
|
+
|
|
23
|
+
// 1. Resolve adapter
|
|
24
|
+
const adapterInstance = typeof adapter === 'function' ? adapter() : adapter
|
|
25
|
+
|
|
26
|
+
// 2. Normalize Base URL
|
|
27
|
+
const normalizedBase = base.startsWith('/') ? base : `/${base}`
|
|
28
|
+
const urlBase = normalizedBase.endsWith('/') ? normalizedBase : `${normalizedBase}/`
|
|
29
|
+
|
|
30
|
+
// 3. Resolve absolute filesystem paths relative to rootDir
|
|
31
|
+
const clientDistPath = path.resolve(rootDir, './dist/client')
|
|
32
|
+
const serverDistPath = path.resolve(rootDir, './dist/server/entry-server.js')
|
|
33
|
+
const indexHtmlPath = path.resolve(rootDir, './index.html')
|
|
34
|
+
|
|
35
|
+
// 4. Attach Trailing Slash Middleware
|
|
36
|
+
adapterInstance.use((req, res, next) => {
|
|
37
|
+
trailingSlashMiddleware(trailingSlash, req, res, next)
|
|
38
|
+
})
|
|
39
|
+
|
|
40
|
+
// 5. Setup environment middleware
|
|
41
|
+
const vite = await setupEnvironmentMiddleware({
|
|
42
|
+
adapterInstance,
|
|
43
|
+
rootDir,
|
|
44
|
+
urlBase,
|
|
45
|
+
clientDistPath
|
|
46
|
+
})
|
|
47
|
+
|
|
48
|
+
// Cached production assets
|
|
49
|
+
const templateHtml = isProduction
|
|
50
|
+
? await fs.readFile(path.join(clientDistPath, 'index.html'), 'utf-8')
|
|
51
|
+
: ''
|
|
52
|
+
|
|
53
|
+
// 6. SSR Route Handler
|
|
54
|
+
adapterInstance.handleRoute('*', async (req, res) => {
|
|
55
|
+
try {
|
|
56
|
+
const url = req.originalUrl.replace(urlBase, '')
|
|
57
|
+
|
|
58
|
+
let template
|
|
59
|
+
let render
|
|
60
|
+
if (!isProduction) {
|
|
61
|
+
template = await fs.readFile(indexHtmlPath, 'utf-8')
|
|
62
|
+
template = await vite.transformIndexHtml(url, template)
|
|
63
|
+
render = (await vite.ssrLoadModule('/.ziko/entry-server.js')).render
|
|
64
|
+
} else {
|
|
65
|
+
template = templateHtml
|
|
66
|
+
// 2. Wrap serverDistPath with pathToFileURL().href for Windows ESM compatibility
|
|
67
|
+
render = (await import(pathToFileURL(serverDistPath).href)).render
|
|
68
|
+
}
|
|
69
|
+
|
|
70
|
+
const rendered = await render(url)
|
|
71
|
+
|
|
72
|
+
const html = template
|
|
73
|
+
.replace(`<!--app-head-->`, rendered.head ?? '')
|
|
74
|
+
.replace(`<!--app-html-->`, rendered.html ?? '')
|
|
75
|
+
|
|
76
|
+
res.status(200).set({ 'Content-Type': 'text/html' }).send(html)
|
|
77
|
+
} catch (e) {
|
|
78
|
+
vite?.ssrFixStacktrace(e)
|
|
79
|
+
console.error(e.stack)
|
|
80
|
+
res.status(500).send(e.stack)
|
|
81
|
+
}
|
|
82
|
+
})
|
|
83
|
+
|
|
84
|
+
return adapterInstance.listen(port, () => {
|
|
85
|
+
console.log(`Server started at http://localhost:${port}${urlBase}`)
|
|
86
|
+
})
|
|
87
|
+
}
|
|
@@ -0,0 +1,73 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Server-side replica of Vite's `import.meta.glob()`.
|
|
3
|
+
*
|
|
4
|
+
* @param pattern - Fast-glob pattern(s).
|
|
5
|
+
* @param options - Configuration options.
|
|
6
|
+
* @param options.cwd - Working directory. Defaults to `process.cwd()`.
|
|
7
|
+
* @param options.eager - Return evaluated exports instead of functions.
|
|
8
|
+
* @param options.keyType - Key formatting style.
|
|
9
|
+
*
|
|
10
|
+
* @returns A promise resolving to a record of module loaders or evaluated
|
|
11
|
+
* module exports.
|
|
12
|
+
*/
|
|
13
|
+
export function globImports<T = any>(
|
|
14
|
+
pattern?: string | string[],
|
|
15
|
+
options?: GlobImportsOptions
|
|
16
|
+
): Promise<GlobImportsResult<T>>;
|
|
17
|
+
|
|
18
|
+
/**
|
|
19
|
+
* Options for `globImports()`.
|
|
20
|
+
*/
|
|
21
|
+
export interface GlobImportsOptions {
|
|
22
|
+
/**
|
|
23
|
+
* Working directory used as the base for resolving glob patterns.
|
|
24
|
+
*
|
|
25
|
+
* @default process.cwd()
|
|
26
|
+
*/
|
|
27
|
+
cwd?: string;
|
|
28
|
+
|
|
29
|
+
/**
|
|
30
|
+
* Whether to eagerly import and evaluate all matched modules.
|
|
31
|
+
*
|
|
32
|
+
* When `false`, each value is a function that lazily imports the module.
|
|
33
|
+
*
|
|
34
|
+
* @default false
|
|
35
|
+
*/
|
|
36
|
+
eager?: boolean;
|
|
37
|
+
|
|
38
|
+
/**
|
|
39
|
+
* Key formatting style for matched module paths.
|
|
40
|
+
*
|
|
41
|
+
* - `relative` - Relative paths, matching Vite's default behavior.
|
|
42
|
+
* - `absolute` - Absolute filesystem paths.
|
|
43
|
+
* - `fileUrl` - `file://` URLs.
|
|
44
|
+
*
|
|
45
|
+
* @default 'relative'
|
|
46
|
+
*/
|
|
47
|
+
keyType?: GlobImportsKeyType;
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
/**
|
|
51
|
+
* Supported key formatting styles for `globImports()`.
|
|
52
|
+
*/
|
|
53
|
+
export type GlobImportsKeyType =
|
|
54
|
+
| 'relative'
|
|
55
|
+
| 'absolute'
|
|
56
|
+
| 'fileUrl';
|
|
57
|
+
|
|
58
|
+
/**
|
|
59
|
+
* A lazy module importer returned by `globImports()`
|
|
60
|
+
* when `eager` is `false`.
|
|
61
|
+
*/
|
|
62
|
+
export type GlobImportLoader<T = any> = () => Promise<T>;
|
|
63
|
+
|
|
64
|
+
/**
|
|
65
|
+
* Result returned by `globImports()`.
|
|
66
|
+
*
|
|
67
|
+
* When `eager` is `false`, values are lazy module loaders.
|
|
68
|
+
* When `eager` is `true`, values are the evaluated module exports.
|
|
69
|
+
*/
|
|
70
|
+
export type GlobImportsResult<T = any> = Record<
|
|
71
|
+
string,
|
|
72
|
+
GlobImportLoader<T> | T
|
|
73
|
+
>;
|
|
@@ -0,0 +1,50 @@
|
|
|
1
|
+
import fg from 'fast-glob'
|
|
2
|
+
import path from 'node:path'
|
|
3
|
+
import { pathToFileURL } from 'node:url'
|
|
4
|
+
|
|
5
|
+
/**
|
|
6
|
+
* Server-side replica of Vite's import.meta.glob().
|
|
7
|
+
*
|
|
8
|
+
* @param {string | string[]} pattern - Fast-glob pattern(s)
|
|
9
|
+
* @param {Object} options
|
|
10
|
+
* @param {string} [options.cwd=process.cwd()] - Working directory
|
|
11
|
+
* @param {boolean} [options.eager=false] - Return evaluated exports instead of functions
|
|
12
|
+
* @param {'relative' | 'absolute' | 'fileUrl'} [options.keyType='relative'] - Key formatting style
|
|
13
|
+
* @returns {Promise<Record<string, Function | Promise<any>>>}
|
|
14
|
+
*/
|
|
15
|
+
export async function globImports(
|
|
16
|
+
pattern = './src/pages/**/*.{js,ts,jsx,tsx}',
|
|
17
|
+
{ cwd = process.cwd(), eager = false, keyType = 'relative' } = {}
|
|
18
|
+
) {
|
|
19
|
+
const relativePaths = await fg(pattern, { cwd, dot: false })
|
|
20
|
+
/** @type {Record<string, Function | Promise<any>>} */
|
|
21
|
+
const modules = {}
|
|
22
|
+
|
|
23
|
+
for (const relativePath of relativePaths) {
|
|
24
|
+
const absolutePath = path.resolve(cwd, relativePath)
|
|
25
|
+
const fileUrl = pathToFileURL(absolutePath).href
|
|
26
|
+
|
|
27
|
+
// Determine Key Format
|
|
28
|
+
let key
|
|
29
|
+
if (keyType === 'fileUrl') {
|
|
30
|
+
key = fileUrl
|
|
31
|
+
} else if (keyType === 'absolute') {
|
|
32
|
+
key = absolutePath.split(path.sep).join('/')
|
|
33
|
+
} else {
|
|
34
|
+
// Standard Vite 'relative' behavior
|
|
35
|
+
key = relativePath.split(path.sep).join('/')
|
|
36
|
+
if (!key.startsWith('.') && !key.startsWith('/')) {
|
|
37
|
+
key = `./${key}`
|
|
38
|
+
}
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
// Always use full fileUrl for the actual import
|
|
42
|
+
if (eager) {
|
|
43
|
+
modules[key] = await import(/* @vite-ignore */ fileUrl)
|
|
44
|
+
} else {
|
|
45
|
+
modules[key] = () => import(/* @vite-ignore */ fileUrl)
|
|
46
|
+
}
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
return modules
|
|
50
|
+
}
|
|
@@ -1,9 +1 @@
|
|
|
1
|
-
export * from
|
|
2
|
-
export * from "./renderDomToString.js";
|
|
3
|
-
export * from "./glob-imports.js";
|
|
4
|
-
export * from "./write-to-dist.js";
|
|
5
|
-
export * from './manifest-parser.js';
|
|
6
|
-
export * from './import-prerendered-routes.js'
|
|
7
|
-
export * from './import-middlwares.js'
|
|
8
|
-
export * from './resolve-static-routes.js'
|
|
9
|
-
export * from './read-files.js'
|
|
1
|
+
export * from './globImports.js'
|
package/README.md
DELETED
|
@@ -1,72 +0,0 @@
|
|
|
1
|
-
[](https://github.com/zikojs)
|
|
2
|
-
|
|
3
|
-
# Ziko-server
|
|
4
|
-
|
|
5
|
-
Server-side rendering for Zikojs with file-based routing and client-side hydration.
|
|
6
|
-
|
|
7
|
-
# Features
|
|
8
|
-
- ✅ Server Side Rendering
|
|
9
|
-
- ✅ Client Side Hydration with no additional config
|
|
10
|
-
- ✅ File Based Routing
|
|
11
|
-
- ✅ Mdzjs Supports
|
|
12
|
-
- ✅ Supports Dynamic Routes
|
|
13
|
-
- ✅ Supports both Sync And Async rendering
|
|
14
|
-
- ✅ Supports API
|
|
15
|
-
|
|
16
|
-
<!--
|
|
17
|
-
compare with type
|
|
18
|
-
-->
|
|
19
|
-
|
|
20
|
-
# Project Structure
|
|
21
|
-
```
|
|
22
|
-
App
|
|
23
|
-
├──public/
|
|
24
|
-
├── src/
|
|
25
|
-
├── .ziko #generated
|
|
26
|
-
├── pages/ # required
|
|
27
|
-
├── index.js
|
|
28
|
-
├── components/
|
|
29
|
-
├── layouts/
|
|
30
|
-
├── contents/
|
|
31
|
-
├── db/
|
|
32
|
-
├── i18n/
|
|
33
|
-
├── middlewares.js
|
|
34
|
-
├── tsconfig.json
|
|
35
|
-
├── ziko.config.js
|
|
36
|
-
├── package.json
|
|
37
|
-
|
|
38
|
-
```
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
# Config
|
|
42
|
-
|
|
43
|
-
```js
|
|
44
|
-
// server.js
|
|
45
|
-
import { createServer } from "ziko-server/server";
|
|
46
|
-
createServer()
|
|
47
|
-
```
|
|
48
|
-
|
|
49
|
-
```js
|
|
50
|
-
// entry-server.js
|
|
51
|
-
import {defineServerEntry} from "ziko-server/entry-server";
|
|
52
|
-
export default defineServerEntry({
|
|
53
|
-
pages : import.meta.glob("./pages/**/*{.js,.mdz}")
|
|
54
|
-
})
|
|
55
|
-
```
|
|
56
|
-
```js
|
|
57
|
-
// entry-client.js
|
|
58
|
-
import {EntryClient} from "ziko-server/entry-client";
|
|
59
|
-
EntryClient({
|
|
60
|
-
pages : import.meta.glob("./pages/**/*{.js,.mdz}")
|
|
61
|
-
})
|
|
62
|
-
```
|
|
63
|
-
|
|
64
|
-
# ⭐️ Show your support
|
|
65
|
-
|
|
66
|
-
If you appreciate the project, kindly demonstrate your support by giving it a star!<br>
|
|
67
|
-
|
|
68
|
-
[](https://github.com/zakarialaoui10/ziko-server)
|
|
69
|
-
<!--## Financial support-->
|
|
70
|
-
# License
|
|
71
|
-
This projet is licensed under the terms of MIT License
|
|
72
|
-
<img src="https://img.shields.io/github/license/zakarialaoui10/ziko-server?color=rgb%2820%2C21%2C169%29" width="100" align="right">
|