vite-plugin-ssr-config 1.0.3
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/README.md +244 -0
- package/dist/index.cjs +489 -0
- package/dist/index.d.cts +29 -0
- package/dist/index.d.ts +29 -0
- package/dist/index.js +452 -0
- package/package.json +57 -0
- package/ssr/entryClient.jsx +25 -0
- package/ssr/entryRender.jsx +44 -0
- package/ssr/errorBoundary.jsx +165 -0
- package/ssr/handler.js +13 -0
- package/ssr/liveReload.jsx +33 -0
- package/ssr/pageBrowser.jsx +36 -0
- package/ssr/pageServer.jsx +39 -0
- package/ssr/root.jsx +21 -0
- package/ssr/rootRoutes.jsx +16 -0
- package/ssr/server.js +49 -0
- package/ssr/viteScripts.jsx +7 -0
package/dist/index.js
ADDED
|
@@ -0,0 +1,452 @@
|
|
|
1
|
+
// src/index.ts
|
|
2
|
+
import path5 from "path";
|
|
3
|
+
|
|
4
|
+
// src/model.ts
|
|
5
|
+
var assertSSRConfig = (ssrOpts = {}) => {
|
|
6
|
+
let {
|
|
7
|
+
root = process.cwd(),
|
|
8
|
+
disableBuild = false,
|
|
9
|
+
//Main Entry
|
|
10
|
+
entryClient = ".ssr/entryClient.jsx",
|
|
11
|
+
entryRender = ".ssr/entryRender.jsx",
|
|
12
|
+
rootDocument = ".ssr/root.jsx",
|
|
13
|
+
//Server
|
|
14
|
+
server = ".ssr/server.js",
|
|
15
|
+
handler = ".ssr/handler.js",
|
|
16
|
+
//SSR
|
|
17
|
+
pageServer = ".ssr/pageServer.jsx",
|
|
18
|
+
pageBrowser = ".ssr/pageBrowser.jsx",
|
|
19
|
+
rootRoutes = ".ssr/rootRoutes.jsx",
|
|
20
|
+
errorBoundary = ".ssr/errorBoundary.jsx",
|
|
21
|
+
//Scripts
|
|
22
|
+
liveReload = ".ssr/liveReload.jsx",
|
|
23
|
+
viteScripts = ".ssr/viteScripts.jsx",
|
|
24
|
+
//Out directories
|
|
25
|
+
serverOutDir = "dist/",
|
|
26
|
+
serverMinify = false,
|
|
27
|
+
serverBuild = (config) => config,
|
|
28
|
+
clientOutDir = "dist/client",
|
|
29
|
+
clientMinify = true,
|
|
30
|
+
clientBuild = (config) => config
|
|
31
|
+
} = ssrOpts;
|
|
32
|
+
return {
|
|
33
|
+
root,
|
|
34
|
+
disableBuild,
|
|
35
|
+
entryClient,
|
|
36
|
+
entryRender,
|
|
37
|
+
rootDocument,
|
|
38
|
+
server,
|
|
39
|
+
handler,
|
|
40
|
+
pageServer,
|
|
41
|
+
pageBrowser,
|
|
42
|
+
rootRoutes,
|
|
43
|
+
errorBoundary,
|
|
44
|
+
liveReload,
|
|
45
|
+
viteScripts,
|
|
46
|
+
serverOutDir,
|
|
47
|
+
serverMinify,
|
|
48
|
+
serverBuild,
|
|
49
|
+
clientOutDir,
|
|
50
|
+
clientMinify,
|
|
51
|
+
clientBuild
|
|
52
|
+
};
|
|
53
|
+
};
|
|
54
|
+
|
|
55
|
+
// src/utils.ts
|
|
56
|
+
import fs from "fs-extra";
|
|
57
|
+
import path from "path";
|
|
58
|
+
import { fileURLToPath } from "url";
|
|
59
|
+
var finalUrl = (base, name) => {
|
|
60
|
+
return path.join(base, name).replaceAll("\\", "/");
|
|
61
|
+
};
|
|
62
|
+
var getPluginDirectory = () => {
|
|
63
|
+
if (typeof __dirname === "undefined") {
|
|
64
|
+
const filename = fileURLToPath(import.meta.url);
|
|
65
|
+
return path.dirname(filename);
|
|
66
|
+
} else {
|
|
67
|
+
return __dirname;
|
|
68
|
+
}
|
|
69
|
+
};
|
|
70
|
+
var findDirPlugin = (dirname, max = 5) => {
|
|
71
|
+
const basedir = getPluginDirectory();
|
|
72
|
+
let relative = "/";
|
|
73
|
+
let dirPath = "";
|
|
74
|
+
for (var i = 0; i < max; i++) {
|
|
75
|
+
dirPath = path.join(basedir, relative, dirname);
|
|
76
|
+
if (fs.existsSync(dirPath)) {
|
|
77
|
+
return dirPath;
|
|
78
|
+
}
|
|
79
|
+
relative += "../";
|
|
80
|
+
}
|
|
81
|
+
throw Error(`Not found: ${dirPath}`);
|
|
82
|
+
};
|
|
83
|
+
var cleanDirectory = (target) => {
|
|
84
|
+
if (fs.existsSync(target)) {
|
|
85
|
+
fs.rmSync(target, { recursive: true, force: true });
|
|
86
|
+
}
|
|
87
|
+
fs.mkdirSync(target, { recursive: true });
|
|
88
|
+
};
|
|
89
|
+
var copyFilesDirectory = (origin, target, {
|
|
90
|
+
files = [],
|
|
91
|
+
oldId = "",
|
|
92
|
+
newId = ""
|
|
93
|
+
}) => {
|
|
94
|
+
files.forEach((file) => {
|
|
95
|
+
const sourceFilePath = path.join(origin, file);
|
|
96
|
+
const targetFilePath = path.join(target, file);
|
|
97
|
+
if (oldId !== newId) {
|
|
98
|
+
let fileContent = fs.readFileSync(sourceFilePath, "utf-8");
|
|
99
|
+
fileContent = fileContent.replace(new RegExp(oldId, "g"), newId);
|
|
100
|
+
fs.writeFileSync(targetFilePath, fileContent, "utf-8");
|
|
101
|
+
} else {
|
|
102
|
+
fs.copySync(sourceFilePath, targetFilePath, { overwrite: true });
|
|
103
|
+
}
|
|
104
|
+
});
|
|
105
|
+
};
|
|
106
|
+
|
|
107
|
+
// src/plugin-build/build.ts
|
|
108
|
+
import fs2 from "fs-extra";
|
|
109
|
+
import path2 from "path";
|
|
110
|
+
import { build, mergeConfig } from "vite";
|
|
111
|
+
var doBuildServer = async (ssrConfig2, viteConfig) => {
|
|
112
|
+
const {
|
|
113
|
+
root,
|
|
114
|
+
serverMinify,
|
|
115
|
+
serverOutDir,
|
|
116
|
+
entryClient,
|
|
117
|
+
clientOutDir,
|
|
118
|
+
server,
|
|
119
|
+
handler,
|
|
120
|
+
serverBuild,
|
|
121
|
+
rootDocument,
|
|
122
|
+
entryRender,
|
|
123
|
+
pageServer,
|
|
124
|
+
pageBrowser,
|
|
125
|
+
rootRoutes,
|
|
126
|
+
errorBoundary,
|
|
127
|
+
liveReload,
|
|
128
|
+
viteScripts
|
|
129
|
+
} = ssrConfig2;
|
|
130
|
+
const { base = "/" } = viteConfig;
|
|
131
|
+
const ssrServerFile = path2.resolve(root, server);
|
|
132
|
+
const ssrPublicDir = path2.relative(serverOutDir, clientOutDir);
|
|
133
|
+
const manifestFile = path2.resolve(`${clientOutDir}/manifest.json`);
|
|
134
|
+
const manifestContent = fs2.readFileSync(manifestFile, "utf-8");
|
|
135
|
+
const manifest = JSON.parse(manifestContent);
|
|
136
|
+
const manifestOut = manifest[entryClient].file;
|
|
137
|
+
const ssrEntryClientURL = finalUrl(base, manifestOut);
|
|
138
|
+
const ssrFiles = [
|
|
139
|
+
handler,
|
|
140
|
+
rootDocument,
|
|
141
|
+
entryClient,
|
|
142
|
+
entryRender,
|
|
143
|
+
pageServer,
|
|
144
|
+
pageBrowser,
|
|
145
|
+
rootRoutes,
|
|
146
|
+
errorBoundary,
|
|
147
|
+
liveReload,
|
|
148
|
+
viteScripts
|
|
149
|
+
];
|
|
150
|
+
const baseConfig = {
|
|
151
|
+
appType: "custom",
|
|
152
|
+
base,
|
|
153
|
+
root,
|
|
154
|
+
publicDir: "private",
|
|
155
|
+
define: {
|
|
156
|
+
"process.env.SSR_BASENAME": JSON.stringify(base),
|
|
157
|
+
"process.env.SSR_PUBLIC_DIR": JSON.stringify(ssrPublicDir),
|
|
158
|
+
"process.env.SSR_ENTRY_CLIENT": JSON.stringify(ssrEntryClientURL),
|
|
159
|
+
"process.env.SSR": JSON.stringify(true)
|
|
160
|
+
},
|
|
161
|
+
ssr: {
|
|
162
|
+
noExternal: []
|
|
163
|
+
},
|
|
164
|
+
build: {
|
|
165
|
+
outDir: serverOutDir,
|
|
166
|
+
ssr: ssrServerFile,
|
|
167
|
+
write: true,
|
|
168
|
+
minify: serverMinify,
|
|
169
|
+
target: "esnext",
|
|
170
|
+
emptyOutDir: false,
|
|
171
|
+
rollupOptions: {
|
|
172
|
+
external: viteConfig.build?.rollupOptions?.external,
|
|
173
|
+
output: {
|
|
174
|
+
format: "es",
|
|
175
|
+
entryFileNames: "app.js",
|
|
176
|
+
chunkFileNames: "bin/[name]-[hash].js",
|
|
177
|
+
assetFileNames: "assets/[name]-[hash].[ext]",
|
|
178
|
+
manualChunks: (id) => {
|
|
179
|
+
const isSsr = ssrFiles.find(
|
|
180
|
+
(it) => id.startsWith(it) || id.endsWith(it)
|
|
181
|
+
);
|
|
182
|
+
if (isSsr) {
|
|
183
|
+
return "ssr";
|
|
184
|
+
}
|
|
185
|
+
if (id.startsWith("virtual")) {
|
|
186
|
+
return "virtual";
|
|
187
|
+
}
|
|
188
|
+
}
|
|
189
|
+
},
|
|
190
|
+
onwarn: (warning, handler2) => {
|
|
191
|
+
if (warning.code === "UNUSED_EXTERNAL_IMPORT" && warning.ids.some((id) => id.includes("node_modules"))) {
|
|
192
|
+
return;
|
|
193
|
+
}
|
|
194
|
+
handler2(warning);
|
|
195
|
+
}
|
|
196
|
+
}
|
|
197
|
+
}
|
|
198
|
+
};
|
|
199
|
+
const customConfig = await serverBuild(baseConfig);
|
|
200
|
+
const finalConfig = mergeConfig(baseConfig, customConfig);
|
|
201
|
+
await build(finalConfig);
|
|
202
|
+
};
|
|
203
|
+
var doBuildClient = async (ssrConfig2, viteConfig) => {
|
|
204
|
+
const { base = "/" } = viteConfig;
|
|
205
|
+
const { root, clientMinify, clientOutDir, entryClient, clientBuild } = ssrConfig2;
|
|
206
|
+
const preloadFiles = [
|
|
207
|
+
"modulepreload",
|
|
208
|
+
"commonjsHelpers",
|
|
209
|
+
"vite/",
|
|
210
|
+
"installHook"
|
|
211
|
+
];
|
|
212
|
+
const baseConfig = {
|
|
213
|
+
root,
|
|
214
|
+
appType: "custom",
|
|
215
|
+
base,
|
|
216
|
+
define: {
|
|
217
|
+
"process.env.SSR_BASENAME": JSON.stringify(base),
|
|
218
|
+
"process.env.SSR": JSON.stringify(false)
|
|
219
|
+
},
|
|
220
|
+
build: {
|
|
221
|
+
write: true,
|
|
222
|
+
manifest: true,
|
|
223
|
+
minify: clientMinify,
|
|
224
|
+
target: "modules",
|
|
225
|
+
emptyOutDir: false,
|
|
226
|
+
outDir: clientOutDir,
|
|
227
|
+
rollupOptions: {
|
|
228
|
+
external: viteConfig.build?.rollupOptions?.external,
|
|
229
|
+
input: {
|
|
230
|
+
main: path2.resolve(root, entryClient)
|
|
231
|
+
},
|
|
232
|
+
output: {
|
|
233
|
+
format: "es",
|
|
234
|
+
entryFileNames: `assets/[name]-[hash].js`,
|
|
235
|
+
chunkFileNames: `chunks/[name]-[hash].js`,
|
|
236
|
+
assetFileNames: `assets/[name]-[hash].[ext]`,
|
|
237
|
+
manualChunks: (id) => {
|
|
238
|
+
const isInternal = preloadFiles.find((it) => id.includes(it));
|
|
239
|
+
if (isInternal) {
|
|
240
|
+
return "preload";
|
|
241
|
+
}
|
|
242
|
+
if (id.includes("node_modules")) {
|
|
243
|
+
return "vendor";
|
|
244
|
+
}
|
|
245
|
+
}
|
|
246
|
+
}
|
|
247
|
+
}
|
|
248
|
+
}
|
|
249
|
+
};
|
|
250
|
+
const customConfig = await clientBuild(baseConfig);
|
|
251
|
+
const finalConfig = mergeConfig(baseConfig, customConfig);
|
|
252
|
+
await build(finalConfig);
|
|
253
|
+
};
|
|
254
|
+
|
|
255
|
+
// src/plugin-build/index.ts
|
|
256
|
+
var pluginBuildSkip = () => {
|
|
257
|
+
const ENTRY_NONE = "____.html";
|
|
258
|
+
return {
|
|
259
|
+
name: "vite-plugin-ssr-config:skip",
|
|
260
|
+
enforce: "pre",
|
|
261
|
+
apply: "build",
|
|
262
|
+
config: () => {
|
|
263
|
+
if (process.env.IS_SSR_KIT_BUILD) return {};
|
|
264
|
+
return {
|
|
265
|
+
build: {
|
|
266
|
+
emptyOutDir: true,
|
|
267
|
+
copyPublicDir: false,
|
|
268
|
+
write: false,
|
|
269
|
+
rollupOptions: {
|
|
270
|
+
input: {
|
|
271
|
+
main: ENTRY_NONE
|
|
272
|
+
}
|
|
273
|
+
}
|
|
274
|
+
}
|
|
275
|
+
};
|
|
276
|
+
},
|
|
277
|
+
resolveId: (id) => {
|
|
278
|
+
if (id === ENTRY_NONE) {
|
|
279
|
+
return id;
|
|
280
|
+
}
|
|
281
|
+
return null;
|
|
282
|
+
},
|
|
283
|
+
load: (id) => {
|
|
284
|
+
if (id === ENTRY_NONE) {
|
|
285
|
+
return "";
|
|
286
|
+
}
|
|
287
|
+
return null;
|
|
288
|
+
}
|
|
289
|
+
};
|
|
290
|
+
};
|
|
291
|
+
var pluginBuildSSR = (ssrConfig2) => {
|
|
292
|
+
let viteConfig = {};
|
|
293
|
+
return {
|
|
294
|
+
name: "vite-plugin-ssr-config:build",
|
|
295
|
+
enforce: "pre",
|
|
296
|
+
apply: "build",
|
|
297
|
+
configResolved: (config) => {
|
|
298
|
+
viteConfig = config;
|
|
299
|
+
},
|
|
300
|
+
buildStart: async () => {
|
|
301
|
+
if (process.env.IS_SSR_KIT_BUILD) return;
|
|
302
|
+
process.env.IS_SSR_KIT_BUILD = "true";
|
|
303
|
+
cleanDirectory(ssrConfig2.clientOutDir);
|
|
304
|
+
cleanDirectory(ssrConfig2.serverOutDir);
|
|
305
|
+
viteConfig.logger.info("");
|
|
306
|
+
viteConfig.logger.info("\x1B[1m\x1B[31mCLIENT BUILD\x1B[0m");
|
|
307
|
+
await doBuildClient(ssrConfig2, viteConfig);
|
|
308
|
+
viteConfig.logger.info("");
|
|
309
|
+
viteConfig.logger.info("\x1B[1m\x1B[31mSERVER BUILD\x1B[0m");
|
|
310
|
+
await doBuildServer(ssrConfig2, viteConfig);
|
|
311
|
+
viteConfig.logger.info("");
|
|
312
|
+
}
|
|
313
|
+
};
|
|
314
|
+
};
|
|
315
|
+
var pluginBuild = (ssrConfig2) => {
|
|
316
|
+
if (ssrConfig2.disableBuild) {
|
|
317
|
+
return null;
|
|
318
|
+
}
|
|
319
|
+
return [pluginBuildSkip(), pluginBuildSSR(ssrConfig2)];
|
|
320
|
+
};
|
|
321
|
+
|
|
322
|
+
// src/plugin-resolve/index.ts
|
|
323
|
+
import path3 from "path";
|
|
324
|
+
var pluginResolve = (ssrConfig2) => {
|
|
325
|
+
let {
|
|
326
|
+
root,
|
|
327
|
+
server,
|
|
328
|
+
handler,
|
|
329
|
+
rootDocument,
|
|
330
|
+
entryClient,
|
|
331
|
+
entryRender,
|
|
332
|
+
pageServer,
|
|
333
|
+
pageBrowser,
|
|
334
|
+
rootRoutes,
|
|
335
|
+
errorBoundary,
|
|
336
|
+
liveReload,
|
|
337
|
+
viteScripts
|
|
338
|
+
} = ssrConfig2;
|
|
339
|
+
const absoluteFile = (name) => {
|
|
340
|
+
return path3.join(root, name);
|
|
341
|
+
};
|
|
342
|
+
return {
|
|
343
|
+
name: "vite-plugin-ssr-config:resolve",
|
|
344
|
+
enforce: "pre",
|
|
345
|
+
config: () => {
|
|
346
|
+
return {
|
|
347
|
+
resolve: {
|
|
348
|
+
alias: {
|
|
349
|
+
"@ssr/server.js": absoluteFile(server),
|
|
350
|
+
"@ssr/handler.js": absoluteFile(handler),
|
|
351
|
+
"@ssr/root.jsx": absoluteFile(rootDocument),
|
|
352
|
+
"@ssr/entryClient.jsx": absoluteFile(entryClient),
|
|
353
|
+
"@ssr/entryRender.jsx": absoluteFile(entryRender),
|
|
354
|
+
"@ssr/pageServer.jsx": absoluteFile(pageServer),
|
|
355
|
+
"@ssr/pageBrowser.jsx": absoluteFile(pageBrowser),
|
|
356
|
+
"@ssr/rootRoutes.jsx": absoluteFile(rootRoutes),
|
|
357
|
+
"@ssr/errorBoundary.jsx": absoluteFile(errorBoundary),
|
|
358
|
+
"@ssr/liveReload.jsx": absoluteFile(liveReload),
|
|
359
|
+
"@ssr/viteScripts.jsx": absoluteFile(viteScripts)
|
|
360
|
+
}
|
|
361
|
+
}
|
|
362
|
+
};
|
|
363
|
+
}
|
|
364
|
+
};
|
|
365
|
+
};
|
|
366
|
+
|
|
367
|
+
// src/plugin-serve/index.ts
|
|
368
|
+
import fs3 from "fs-extra";
|
|
369
|
+
import path4 from "path";
|
|
370
|
+
var pluginServe = (ssrConfig2) => {
|
|
371
|
+
const { entryClient, root } = ssrConfig2;
|
|
372
|
+
return {
|
|
373
|
+
name: "vite-plugin-ssr-config:serve",
|
|
374
|
+
enforce: "post",
|
|
375
|
+
apply: "serve",
|
|
376
|
+
config: ({ base = "/" }) => {
|
|
377
|
+
const ssrClientEntry = finalUrl(base, entryClient);
|
|
378
|
+
return {
|
|
379
|
+
appType: "custom",
|
|
380
|
+
define: {
|
|
381
|
+
"process.env.SSR_BASENAME": JSON.stringify(base),
|
|
382
|
+
"process.env.SSR_ENTRY_CLIENT": JSON.stringify(ssrClientEntry)
|
|
383
|
+
}
|
|
384
|
+
};
|
|
385
|
+
},
|
|
386
|
+
configureServer: async (devServer) => {
|
|
387
|
+
return async () => {
|
|
388
|
+
devServer.middlewares.use(async (req, res, next) => {
|
|
389
|
+
const indexHtmlPath = path4.join(root, req.url, "index.html");
|
|
390
|
+
if (fs3.existsSync(indexHtmlPath)) {
|
|
391
|
+
return devServer.transformIndexHtml(
|
|
392
|
+
req.url,
|
|
393
|
+
fs3.readFileSync(indexHtmlPath, "utf-8")
|
|
394
|
+
).then((html) => {
|
|
395
|
+
res.setHeader("Content-Type", "text/html");
|
|
396
|
+
res.setHeader("Pragma", "no-cache");
|
|
397
|
+
res.setHeader("Expires", "0");
|
|
398
|
+
res.end(html);
|
|
399
|
+
});
|
|
400
|
+
}
|
|
401
|
+
next();
|
|
402
|
+
});
|
|
403
|
+
devServer.middlewares.use(async (req, res, next) => {
|
|
404
|
+
try {
|
|
405
|
+
process.env.SSR = true;
|
|
406
|
+
const mod = await devServer.ssrLoadModule("@ssr/handler.js", {
|
|
407
|
+
fixStacktrace: true
|
|
408
|
+
});
|
|
409
|
+
await mod.handler(req, res, next);
|
|
410
|
+
} catch (error) {
|
|
411
|
+
next(error);
|
|
412
|
+
}
|
|
413
|
+
});
|
|
414
|
+
};
|
|
415
|
+
}
|
|
416
|
+
};
|
|
417
|
+
};
|
|
418
|
+
|
|
419
|
+
// src/index.ts
|
|
420
|
+
var ssrConfig = (opts = {}) => {
|
|
421
|
+
const ssrConfig2 = assertSSRConfig(opts);
|
|
422
|
+
const cacheOrigin = findDirPlugin("ssr");
|
|
423
|
+
const cacheTarget = path5.join(ssrConfig2.root, ".ssr");
|
|
424
|
+
cleanDirectory(cacheTarget);
|
|
425
|
+
copyFilesDirectory(cacheOrigin, cacheTarget, {
|
|
426
|
+
files: [
|
|
427
|
+
"entryClient.jsx",
|
|
428
|
+
"entryRender.jsx",
|
|
429
|
+
"errorBoundary.jsx",
|
|
430
|
+
"handler.js",
|
|
431
|
+
"liveReload.jsx",
|
|
432
|
+
"pageBrowser.jsx",
|
|
433
|
+
"pageServer.jsx",
|
|
434
|
+
"root.jsx",
|
|
435
|
+
"rootRoutes.jsx",
|
|
436
|
+
"server.js",
|
|
437
|
+
"viteScripts.jsx"
|
|
438
|
+
]
|
|
439
|
+
});
|
|
440
|
+
return [
|
|
441
|
+
pluginResolve(ssrConfig2),
|
|
442
|
+
pluginServe(ssrConfig2),
|
|
443
|
+
pluginBuild(ssrConfig2)
|
|
444
|
+
];
|
|
445
|
+
};
|
|
446
|
+
var ssr = ssrConfig;
|
|
447
|
+
var index_default = ssrConfig;
|
|
448
|
+
export {
|
|
449
|
+
index_default as default,
|
|
450
|
+
ssr,
|
|
451
|
+
ssrConfig
|
|
452
|
+
};
|
package/package.json
ADDED
|
@@ -0,0 +1,57 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "vite-plugin-ssr-config",
|
|
3
|
+
"version": "1.0.3",
|
|
4
|
+
"license": "MIT",
|
|
5
|
+
"description": "A powerful Vite plugin designed to enable Server-Side Rendering (SSR) for React applications. It provides a comprehensive solution for bundling both SSR and CSR, with built-in support for React Router and React Query for efficient API handling and page rendering.",
|
|
6
|
+
"keywords": [
|
|
7
|
+
"vite",
|
|
8
|
+
"vite plugin",
|
|
9
|
+
"ssr",
|
|
10
|
+
"react",
|
|
11
|
+
"react-router",
|
|
12
|
+
"react-query",
|
|
13
|
+
"server",
|
|
14
|
+
"express"
|
|
15
|
+
],
|
|
16
|
+
"author": "Willyams Yujra",
|
|
17
|
+
"type": "module",
|
|
18
|
+
"exports": {
|
|
19
|
+
".": {
|
|
20
|
+
"types": "./dist/index.d.ts",
|
|
21
|
+
"import": "./dist/index.js",
|
|
22
|
+
"require": "./dist/index.cjs"
|
|
23
|
+
}
|
|
24
|
+
},
|
|
25
|
+
"files": [
|
|
26
|
+
"dist/",
|
|
27
|
+
"ssr/",
|
|
28
|
+
"README.md"
|
|
29
|
+
],
|
|
30
|
+
"repository": {
|
|
31
|
+
"type": "git",
|
|
32
|
+
"url": "git+https://github.com/yracnet/vite-plugin-ssr-config.git"
|
|
33
|
+
},
|
|
34
|
+
"homepage": "https://github.com/yracnet/vite-plugin-ssr-config",
|
|
35
|
+
"bugs": "https://github.com/yracnet/vite-plugin-ssr-config/issues",
|
|
36
|
+
"scripts": {
|
|
37
|
+
"build": "tsup",
|
|
38
|
+
"prepublish": "yarn build",
|
|
39
|
+
"prepack": "yarn build"
|
|
40
|
+
},
|
|
41
|
+
"dependencies": {
|
|
42
|
+
"dotenv-local": "^1.0.2",
|
|
43
|
+
"fs-extra": "^11.2.0"
|
|
44
|
+
},
|
|
45
|
+
"peerDependencies": {
|
|
46
|
+
"vite": "^2 || ^3 || ^4 || ^5 || ^6"
|
|
47
|
+
},
|
|
48
|
+
"devDependencies": {
|
|
49
|
+
"@types/express": "^5.0.0",
|
|
50
|
+
"@types/fs-extra": "^11.0.4",
|
|
51
|
+
"@types/node": "^22.10.2",
|
|
52
|
+
"express": "^4.21.2",
|
|
53
|
+
"tsup": "^8.3.5",
|
|
54
|
+
"typescript": "^5.7.2",
|
|
55
|
+
"vite": "^4.0.0"
|
|
56
|
+
}
|
|
57
|
+
}
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
import { PageBrowser } from "@ssr/pageBrowser.jsx";
|
|
2
|
+
import { startTransition, StrictMode } from "react";
|
|
3
|
+
import { hydrateRoot } from "react-dom/client";
|
|
4
|
+
|
|
5
|
+
startTransition(() => {
|
|
6
|
+
const hydratedState = JSON.parse(atob(window.__HYDRATED_STATE__));
|
|
7
|
+
const setHydratedState = () => {
|
|
8
|
+
throw Error("Changes Not Allowed");
|
|
9
|
+
};
|
|
10
|
+
hydrateRoot(
|
|
11
|
+
document,
|
|
12
|
+
<StrictMode>
|
|
13
|
+
<PageBrowser
|
|
14
|
+
hydratedState={hydratedState}
|
|
15
|
+
setHydratedState={setHydratedState}
|
|
16
|
+
/>
|
|
17
|
+
</StrictMode>,
|
|
18
|
+
{
|
|
19
|
+
onRecoverableError: (error, { componentStack }) => {
|
|
20
|
+
const logs = componentStack?.split("\n");
|
|
21
|
+
console.log("Error:", error, logs);
|
|
22
|
+
},
|
|
23
|
+
}
|
|
24
|
+
);
|
|
25
|
+
});
|
|
@@ -0,0 +1,44 @@
|
|
|
1
|
+
import { PageServer } from "@ssr/pageServer.jsx";
|
|
2
|
+
import { StrictMode } from "react";
|
|
3
|
+
import { renderToPipeableStream } from "react-dom/server";
|
|
4
|
+
|
|
5
|
+
const renderDefault = async (request, response, next) => {
|
|
6
|
+
let hydratedState = {};
|
|
7
|
+
const setHydratedState = (state) => {
|
|
8
|
+
hydratedState = state;
|
|
9
|
+
};
|
|
10
|
+
const { pipe } = renderToPipeableStream(
|
|
11
|
+
<StrictMode>
|
|
12
|
+
<PageServer
|
|
13
|
+
path={request.originalUrl}
|
|
14
|
+
hydratedState={""} // Access is Not Allowed
|
|
15
|
+
setHydratedState={setHydratedState}
|
|
16
|
+
/>
|
|
17
|
+
</StrictMode>,
|
|
18
|
+
{
|
|
19
|
+
bootstrapScripts: [],
|
|
20
|
+
onShellReady: () => {
|
|
21
|
+
// console.log(request.originalUrl, "onShellReady");
|
|
22
|
+
},
|
|
23
|
+
onAllReady: () => {
|
|
24
|
+
// console.log(request.originalUrl, "onAllReady");
|
|
25
|
+
response.setHeader("content-type", "text/html");
|
|
26
|
+
pipe(response);
|
|
27
|
+
response.write(
|
|
28
|
+
`<script>window.__HYDRATED_STATE__ = "${btoa(
|
|
29
|
+
JSON.stringify(hydratedState)
|
|
30
|
+
)}";</script>`
|
|
31
|
+
);
|
|
32
|
+
},
|
|
33
|
+
onShellError: (error) => {
|
|
34
|
+
// console.log(request.originalUrl, "onShellError", error);
|
|
35
|
+
},
|
|
36
|
+
onError: (error, errorInfo) => {
|
|
37
|
+
// console.log(request.originalUrl, "onError", error, errorInfo);
|
|
38
|
+
next(error);
|
|
39
|
+
},
|
|
40
|
+
}
|
|
41
|
+
);
|
|
42
|
+
};
|
|
43
|
+
|
|
44
|
+
export const render = renderDefault;
|