@modern-js/plugin-ssg 2.69.4 → 3.0.0-alpha.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/dist/cjs/index.js +130 -156
- package/dist/cjs/libs/make.js +69 -62
- package/dist/cjs/libs/output.js +50 -44
- package/dist/cjs/libs/replace.js +68 -64
- package/dist/cjs/libs/util.js +200 -182
- package/dist/cjs/server/consts.js +33 -25
- package/dist/cjs/server/index.js +137 -92
- package/dist/cjs/server/prerender.js +72 -68
- package/dist/cjs/types.js +17 -15
- package/dist/esm/index.mjs +89 -0
- package/dist/esm/libs/make.mjs +31 -0
- package/dist/esm/libs/output.mjs +11 -0
- package/dist/esm/libs/replace.mjs +28 -0
- package/dist/esm/libs/util.mjs +147 -0
- package/dist/esm/server/consts.mjs +2 -0
- package/dist/esm/server/index.mjs +97 -0
- package/dist/esm/server/prerender.mjs +30 -0
- package/dist/esm-node/index.mjs +89 -0
- package/dist/esm-node/libs/make.mjs +31 -0
- package/dist/esm-node/libs/output.mjs +11 -0
- package/dist/esm-node/libs/replace.mjs +28 -0
- package/dist/esm-node/libs/util.mjs +147 -0
- package/dist/esm-node/server/consts.mjs +2 -0
- package/dist/esm-node/server/index.mjs +97 -0
- package/dist/esm-node/server/prerender.mjs +30 -0
- package/dist/types/libs/util.d.ts +1 -1
- package/dist/types/server/index.d.ts +2 -2
- package/package.json +27 -29
- package/rslib.config.mts +4 -0
- package/rstest.config.ts +7 -0
- package/dist/cjs/server/process.js +0 -108
- package/dist/esm/index.js +0 -163
- package/dist/esm/libs/make.js +0 -36
- package/dist/esm/libs/output.js +0 -15
- package/dist/esm/libs/replace.js +0 -41
- package/dist/esm/libs/util.js +0 -210
- package/dist/esm/server/consts.js +0 -4
- package/dist/esm/server/index.js +0 -66
- package/dist/esm/server/prerender.js +0 -46
- package/dist/esm/server/process.js +0 -263
- package/dist/esm-node/index.js +0 -128
- package/dist/esm-node/libs/make.js +0 -37
- package/dist/esm-node/libs/output.js +0 -15
- package/dist/esm-node/libs/replace.js +0 -36
- package/dist/esm-node/libs/util.js +0 -161
- package/dist/esm-node/server/consts.js +0 -4
- package/dist/esm-node/server/index.js +0 -62
- package/dist/esm-node/server/prerender.js +0 -37
- package/dist/esm-node/server/process.js +0 -85
- package/dist/types/server/process.d.ts +0 -1
- /package/dist/esm/{types.js → types.mjs} +0 -0
- /package/dist/esm-node/{types.js → types.mjs} +0 -0
package/dist/esm-node/index.js
DELETED
|
@@ -1,128 +0,0 @@
|
|
|
1
|
-
import path from "path";
|
|
2
|
-
import { filterRoutesForServer, logger } from "@modern-js/utils";
|
|
3
|
-
import { generatePath } from "react-router-dom";
|
|
4
|
-
import { makeRoute } from "./libs/make";
|
|
5
|
-
import { writeHtmlFile } from "./libs/output";
|
|
6
|
-
import { replaceRoute } from "./libs/replace";
|
|
7
|
-
import { flattenRoutes, formatOutput, isDynamicUrl, readJSONSpec, standardOptions, writeJSONSpec } from "./libs/util";
|
|
8
|
-
import { createServer } from "./server";
|
|
9
|
-
const ssgPlugin = () => ({
|
|
10
|
-
name: "@modern-js/plugin-ssg",
|
|
11
|
-
pre: [
|
|
12
|
-
"@modern-js/plugin-server",
|
|
13
|
-
"@modern-js/plugin-bff"
|
|
14
|
-
],
|
|
15
|
-
setup: (api) => {
|
|
16
|
-
const agreedRouteMap = {};
|
|
17
|
-
return {
|
|
18
|
-
modifyFileSystemRoutes({ entrypoint, routes }) {
|
|
19
|
-
const { entryName } = entrypoint;
|
|
20
|
-
const flattedRoutes = flattenRoutes(filterRoutesForServer(routes));
|
|
21
|
-
agreedRouteMap[entryName] = flattedRoutes;
|
|
22
|
-
return {
|
|
23
|
-
entrypoint,
|
|
24
|
-
routes
|
|
25
|
-
};
|
|
26
|
-
},
|
|
27
|
-
async afterBuild() {
|
|
28
|
-
const resolvedConfig = api.useResolvedConfigContext();
|
|
29
|
-
const appContext = api.useAppContext();
|
|
30
|
-
const { appDirectory, entrypoints } = appContext;
|
|
31
|
-
const { output, server } = resolvedConfig;
|
|
32
|
-
const { ssg, distPath: { root: outputPath } = {} } = output;
|
|
33
|
-
const ssgOptions = (Array.isArray(ssg) ? ssg.pop() : ssg) || true;
|
|
34
|
-
const buildDir = path.join(appDirectory, outputPath);
|
|
35
|
-
const routes = readJSONSpec(buildDir);
|
|
36
|
-
const pageRoutes = routes.filter((route) => route.isSPA);
|
|
37
|
-
const apiRoutes = routes.filter((route) => !route.isSPA);
|
|
38
|
-
if (pageRoutes.length === 0) {
|
|
39
|
-
return;
|
|
40
|
-
}
|
|
41
|
-
const intermediateOptions = standardOptions(ssgOptions, entrypoints, pageRoutes, server);
|
|
42
|
-
if (!intermediateOptions) {
|
|
43
|
-
return;
|
|
44
|
-
}
|
|
45
|
-
const ssgRoutes = [];
|
|
46
|
-
pageRoutes.forEach((pageRoute) => {
|
|
47
|
-
const { entryName, entryPath } = pageRoute;
|
|
48
|
-
const agreedRoutes = agreedRouteMap[entryName];
|
|
49
|
-
let entryOptions = intermediateOptions[entryName] || intermediateOptions[pageRoute.urlPath];
|
|
50
|
-
if (!agreedRoutes) {
|
|
51
|
-
if (!entryOptions) {
|
|
52
|
-
return;
|
|
53
|
-
}
|
|
54
|
-
if (entryOptions === true) {
|
|
55
|
-
ssgRoutes.push({
|
|
56
|
-
...pageRoute,
|
|
57
|
-
output: entryPath
|
|
58
|
-
});
|
|
59
|
-
} else if (entryOptions.routes && entryOptions.routes.length > 0) {
|
|
60
|
-
const { routes: enrtyRoutes, headers } = entryOptions;
|
|
61
|
-
enrtyRoutes.forEach((route) => {
|
|
62
|
-
ssgRoutes.push(makeRoute(pageRoute, route, headers));
|
|
63
|
-
});
|
|
64
|
-
}
|
|
65
|
-
} else {
|
|
66
|
-
if (!entryOptions) {
|
|
67
|
-
return;
|
|
68
|
-
}
|
|
69
|
-
if (entryOptions === true) {
|
|
70
|
-
entryOptions = {
|
|
71
|
-
preventDefault: [],
|
|
72
|
-
routes: [],
|
|
73
|
-
headers: {}
|
|
74
|
-
};
|
|
75
|
-
}
|
|
76
|
-
const { preventDefault = [], routes: userRoutes = [], headers } = entryOptions;
|
|
77
|
-
if (userRoutes.length > 0) {
|
|
78
|
-
userRoutes.forEach((route) => {
|
|
79
|
-
if (typeof route === "string") {
|
|
80
|
-
ssgRoutes.push(makeRoute(pageRoute, route, headers));
|
|
81
|
-
} else if (Array.isArray(route.params)) {
|
|
82
|
-
route.params.forEach((param) => {
|
|
83
|
-
ssgRoutes.push(makeRoute(pageRoute, {
|
|
84
|
-
...route,
|
|
85
|
-
url: generatePath(route.url, param)
|
|
86
|
-
}, headers));
|
|
87
|
-
});
|
|
88
|
-
} else {
|
|
89
|
-
ssgRoutes.push(makeRoute(pageRoute, route, headers));
|
|
90
|
-
}
|
|
91
|
-
});
|
|
92
|
-
} else {
|
|
93
|
-
agreedRoutes.filter((route) => !preventDefault.includes(route.path)).forEach((route) => {
|
|
94
|
-
if (!isDynamicUrl(route.path)) {
|
|
95
|
-
ssgRoutes.push(makeRoute(pageRoute, route.path, headers));
|
|
96
|
-
}
|
|
97
|
-
});
|
|
98
|
-
}
|
|
99
|
-
}
|
|
100
|
-
});
|
|
101
|
-
if (ssgRoutes.length === 0) {
|
|
102
|
-
return;
|
|
103
|
-
}
|
|
104
|
-
ssgRoutes.forEach((ssgRoute) => {
|
|
105
|
-
if (ssgRoute.isSSR) {
|
|
106
|
-
const isOriginRoute = pageRoutes.some((pageRoute) => pageRoute.urlPath === ssgRoute.urlPath && pageRoute.entryName === ssgRoute.entryName);
|
|
107
|
-
if (isOriginRoute) {
|
|
108
|
-
throw new Error(`ssg can not using with ssr,url - ${ssgRoute.urlPath}, entry - ${ssgRoute.entryName} `);
|
|
109
|
-
}
|
|
110
|
-
logger.warn(`new ssg route ${ssgRoute.urlPath} is using ssr now,maybe from parent route ${ssgRoute.entryName},close ssr`);
|
|
111
|
-
}
|
|
112
|
-
ssgRoute.isSSR = false;
|
|
113
|
-
ssgRoute.output = formatOutput(ssgRoute.output);
|
|
114
|
-
});
|
|
115
|
-
const htmlAry = await createServer(api, ssgRoutes, pageRoutes, apiRoutes, resolvedConfig, appDirectory);
|
|
116
|
-
writeHtmlFile(htmlAry, ssgRoutes, buildDir);
|
|
117
|
-
replaceRoute(ssgRoutes, pageRoutes);
|
|
118
|
-
writeJSONSpec(buildDir, pageRoutes.concat(apiRoutes));
|
|
119
|
-
logger.info("ssg Compiled successfully");
|
|
120
|
-
}
|
|
121
|
-
};
|
|
122
|
-
}
|
|
123
|
-
});
|
|
124
|
-
var src_default = ssgPlugin;
|
|
125
|
-
export {
|
|
126
|
-
src_default as default,
|
|
127
|
-
ssgPlugin
|
|
128
|
-
};
|
|
@@ -1,37 +0,0 @@
|
|
|
1
|
-
import path from "path";
|
|
2
|
-
import normalize from "normalize-path";
|
|
3
|
-
function makeRender(ssgRoutes, render, port) {
|
|
4
|
-
return ssgRoutes.map((ssgRoute) => render({
|
|
5
|
-
url: ssgRoute.urlPath,
|
|
6
|
-
headers: {
|
|
7
|
-
host: `localhost:${port}`,
|
|
8
|
-
...ssgRoute.headers
|
|
9
|
-
},
|
|
10
|
-
connection: {}
|
|
11
|
-
}));
|
|
12
|
-
}
|
|
13
|
-
function makeRoute(baseRoute, route, headers = {}) {
|
|
14
|
-
const { urlPath, entryPath } = baseRoute;
|
|
15
|
-
if (typeof route === "string") {
|
|
16
|
-
return {
|
|
17
|
-
...baseRoute,
|
|
18
|
-
urlPath: normalize(`${urlPath}${route}`) || "/",
|
|
19
|
-
headers,
|
|
20
|
-
output: path.join(entryPath, `..${route === "/" ? "" : route}`)
|
|
21
|
-
};
|
|
22
|
-
} else {
|
|
23
|
-
return {
|
|
24
|
-
...baseRoute,
|
|
25
|
-
urlPath: normalize(`${urlPath}${route.url}`) || "/",
|
|
26
|
-
headers: {
|
|
27
|
-
...headers,
|
|
28
|
-
...route.headers
|
|
29
|
-
},
|
|
30
|
-
output: route.output ? path.normalize(route.output) : path.join(entryPath, `..${route.url === "/" ? "" : route.url}`)
|
|
31
|
-
};
|
|
32
|
-
}
|
|
33
|
-
}
|
|
34
|
-
export {
|
|
35
|
-
makeRender,
|
|
36
|
-
makeRoute
|
|
37
|
-
};
|
|
@@ -1,15 +0,0 @@
|
|
|
1
|
-
import path from "path";
|
|
2
|
-
import { fs } from "@modern-js/utils";
|
|
3
|
-
function writeHtmlFile(htmlAry, ssgRoutes, baseDir) {
|
|
4
|
-
htmlAry.forEach((html, index) => {
|
|
5
|
-
const ssgRoute = ssgRoutes[index];
|
|
6
|
-
const filepath = path.join(baseDir, ssgRoute.output);
|
|
7
|
-
if (!fs.existsSync(path.dirname(filepath))) {
|
|
8
|
-
fs.ensureDirSync(path.dirname(filepath));
|
|
9
|
-
}
|
|
10
|
-
fs.writeFileSync(filepath, html);
|
|
11
|
-
});
|
|
12
|
-
}
|
|
13
|
-
export {
|
|
14
|
-
writeHtmlFile
|
|
15
|
-
};
|
|
@@ -1,36 +0,0 @@
|
|
|
1
|
-
import normalize from "normalize-path";
|
|
2
|
-
function exist(route, pageRoutes) {
|
|
3
|
-
return pageRoutes.slice().findIndex((pageRoute) => {
|
|
4
|
-
const urlEqual = normalize(pageRoute.urlPath) === normalize(route.urlPath);
|
|
5
|
-
const entryEqual = pageRoute.entryName === route.entryName;
|
|
6
|
-
if (urlEqual && entryEqual) {
|
|
7
|
-
return true;
|
|
8
|
-
}
|
|
9
|
-
return false;
|
|
10
|
-
});
|
|
11
|
-
}
|
|
12
|
-
function replaceRoute(ssgRoutes, pageRoutes) {
|
|
13
|
-
const cleanSsgRoutes = ssgRoutes.map((ssgRoute) => {
|
|
14
|
-
const { output, headers, ...cleanSsgRoute } = ssgRoute;
|
|
15
|
-
return Object.assign(cleanSsgRoute, output ? {
|
|
16
|
-
entryPath: output
|
|
17
|
-
} : {});
|
|
18
|
-
});
|
|
19
|
-
const freshRoutes = [];
|
|
20
|
-
cleanSsgRoutes.forEach((ssgRoute) => {
|
|
21
|
-
const index = exist(ssgRoute, pageRoutes);
|
|
22
|
-
if (index < 0) {
|
|
23
|
-
freshRoutes.push({
|
|
24
|
-
...ssgRoute
|
|
25
|
-
});
|
|
26
|
-
} else {
|
|
27
|
-
pageRoutes[index].entryPath = ssgRoute.entryPath;
|
|
28
|
-
}
|
|
29
|
-
});
|
|
30
|
-
pageRoutes.push(...freshRoutes);
|
|
31
|
-
return pageRoutes;
|
|
32
|
-
}
|
|
33
|
-
export {
|
|
34
|
-
exist,
|
|
35
|
-
replaceRoute
|
|
36
|
-
};
|
|
@@ -1,161 +0,0 @@
|
|
|
1
|
-
import path from "path";
|
|
2
|
-
import { fs, ROUTE_SPEC_FILE, SERVER_BUNDLE_DIRECTORY, isSingleEntry } from "@modern-js/utils";
|
|
3
|
-
function formatOutput(filename) {
|
|
4
|
-
const outputPath = path.extname(filename) ? filename : `${filename}/index.html`;
|
|
5
|
-
return outputPath;
|
|
6
|
-
}
|
|
7
|
-
function formatPath(str) {
|
|
8
|
-
let addr = str;
|
|
9
|
-
if (!addr || typeof addr !== "string") {
|
|
10
|
-
return addr;
|
|
11
|
-
}
|
|
12
|
-
if (addr.startsWith(".")) {
|
|
13
|
-
addr = addr.slice(1);
|
|
14
|
-
}
|
|
15
|
-
if (!addr.startsWith("/")) {
|
|
16
|
-
addr = `/${addr}`;
|
|
17
|
-
}
|
|
18
|
-
if (addr.endsWith("/") && addr !== "/") {
|
|
19
|
-
addr = addr.slice(0, addr.length - 1);
|
|
20
|
-
}
|
|
21
|
-
return addr;
|
|
22
|
-
}
|
|
23
|
-
function isDynamicUrl(url) {
|
|
24
|
-
return url.includes(":");
|
|
25
|
-
}
|
|
26
|
-
function getUrlPrefix(route, baseUrl) {
|
|
27
|
-
let base = "";
|
|
28
|
-
if (Array.isArray(baseUrl)) {
|
|
29
|
-
const filters = baseUrl.filter((url) => route.urlPath.includes(url));
|
|
30
|
-
if (filters.length > 1) {
|
|
31
|
-
const matched = filters.sort((a, b) => a.length - b.length)[0];
|
|
32
|
-
if (!matched) {
|
|
33
|
-
throw new Error("");
|
|
34
|
-
}
|
|
35
|
-
base = matched;
|
|
36
|
-
}
|
|
37
|
-
} else {
|
|
38
|
-
base = baseUrl;
|
|
39
|
-
}
|
|
40
|
-
base = base === "/" ? "" : base;
|
|
41
|
-
const entryName = route.entryName === "main" ? "" : route.entryName;
|
|
42
|
-
const prefix = `${base}/${entryName}`;
|
|
43
|
-
return prefix.endsWith("/") ? prefix.slice(0, -1) : prefix;
|
|
44
|
-
}
|
|
45
|
-
function getOutput(route, base, agreed) {
|
|
46
|
-
const { output } = route;
|
|
47
|
-
if (output) {
|
|
48
|
-
return output;
|
|
49
|
-
}
|
|
50
|
-
if (agreed) {
|
|
51
|
-
const urlWithoutBase = route.urlPath.replace(base, "");
|
|
52
|
-
return urlWithoutBase.startsWith("/") ? urlWithoutBase.slice(1) : urlWithoutBase;
|
|
53
|
-
}
|
|
54
|
-
throw new Error(`routing must provide output when calling createPage(), check ${route.urlPath}`);
|
|
55
|
-
}
|
|
56
|
-
const readJSONSpec = (dir) => {
|
|
57
|
-
const routeJSONPath = path.join(dir, ROUTE_SPEC_FILE);
|
|
58
|
-
const routeJSON = require(routeJSONPath);
|
|
59
|
-
const { routes } = routeJSON;
|
|
60
|
-
return routes;
|
|
61
|
-
};
|
|
62
|
-
const writeJSONSpec = (dir, routes) => {
|
|
63
|
-
const routeJSONPath = path.join(dir, ROUTE_SPEC_FILE);
|
|
64
|
-
fs.writeJSONSync(routeJSONPath, {
|
|
65
|
-
routes
|
|
66
|
-
}, {
|
|
67
|
-
spaces: 2
|
|
68
|
-
});
|
|
69
|
-
};
|
|
70
|
-
const replaceWithAlias = (base, filePath, alias) => path.posix.join(alias, path.posix.relative(base, filePath));
|
|
71
|
-
const standardOptions = (ssgOptions, entrypoints, routes, server) => {
|
|
72
|
-
if (ssgOptions === false) {
|
|
73
|
-
return false;
|
|
74
|
-
}
|
|
75
|
-
if (ssgOptions === true) {
|
|
76
|
-
return entrypoints.reduce((opt, entry) => {
|
|
77
|
-
opt[entry.entryName] = ssgOptions;
|
|
78
|
-
return opt;
|
|
79
|
-
}, {});
|
|
80
|
-
} else if (typeof ssgOptions === "object") {
|
|
81
|
-
const isSingle = isSingleEntry(entrypoints);
|
|
82
|
-
if (isSingle && typeof ssgOptions.main === "undefined") {
|
|
83
|
-
return {
|
|
84
|
-
main: ssgOptions
|
|
85
|
-
};
|
|
86
|
-
} else {
|
|
87
|
-
return ssgOptions;
|
|
88
|
-
}
|
|
89
|
-
} else if (typeof ssgOptions === "function") {
|
|
90
|
-
const intermediateOptions = {};
|
|
91
|
-
for (const entrypoint of entrypoints) {
|
|
92
|
-
const { entryName } = entrypoint;
|
|
93
|
-
if (Array.isArray(server === null || server === void 0 ? void 0 : server.baseUrl)) {
|
|
94
|
-
for (const url of server.baseUrl) {
|
|
95
|
-
const matchUrl = entryName === "main" ? url : `${url}/${entryName}`;
|
|
96
|
-
const route = routes.find((route2) => route2.urlPath === matchUrl);
|
|
97
|
-
intermediateOptions[route === null || route === void 0 ? void 0 : route.urlPath] = ssgOptions(entryName, {
|
|
98
|
-
baseUrl: url
|
|
99
|
-
});
|
|
100
|
-
}
|
|
101
|
-
} else {
|
|
102
|
-
intermediateOptions[entryName] = ssgOptions(entryName, {
|
|
103
|
-
baseUrl: server === null || server === void 0 ? void 0 : server.baseUrl
|
|
104
|
-
});
|
|
105
|
-
}
|
|
106
|
-
}
|
|
107
|
-
return intermediateOptions;
|
|
108
|
-
}
|
|
109
|
-
return false;
|
|
110
|
-
};
|
|
111
|
-
const openRouteSSR = (routes, entries = []) => routes.map((ssgRoute) => ({
|
|
112
|
-
...ssgRoute,
|
|
113
|
-
isSSR: entries.includes(ssgRoute.entryName),
|
|
114
|
-
bundle: `${SERVER_BUNDLE_DIRECTORY}/${ssgRoute.entryName}.js`
|
|
115
|
-
}));
|
|
116
|
-
const flattenRoutes = (routes) => {
|
|
117
|
-
const parents = [];
|
|
118
|
-
const newRoutes = [];
|
|
119
|
-
const traverseRoute = (route) => {
|
|
120
|
-
const parent = parents[parents.length - 1];
|
|
121
|
-
let path2 = parent ? `${parent.path}/${route.path || ""}`.replace(/\/+/g, "/") : route.path || "";
|
|
122
|
-
path2 = path2.replace(/\/$/, "");
|
|
123
|
-
if (route._component && (path2 !== "/" || path2 === "/" && !parent)) {
|
|
124
|
-
newRoutes.push({
|
|
125
|
-
...route,
|
|
126
|
-
path: path2
|
|
127
|
-
});
|
|
128
|
-
}
|
|
129
|
-
if (route.children) {
|
|
130
|
-
parents.push({
|
|
131
|
-
...route,
|
|
132
|
-
path: path2
|
|
133
|
-
});
|
|
134
|
-
route.children.forEach(traverseRoute);
|
|
135
|
-
parents.pop();
|
|
136
|
-
}
|
|
137
|
-
};
|
|
138
|
-
routes.forEach(traverseRoute);
|
|
139
|
-
return newRoutes;
|
|
140
|
-
};
|
|
141
|
-
function chunkArray(arr, size) {
|
|
142
|
-
const result = [];
|
|
143
|
-
for (let i = 0; i < arr.length; i += size) {
|
|
144
|
-
result.push(arr.slice(i, i + size));
|
|
145
|
-
}
|
|
146
|
-
return result;
|
|
147
|
-
}
|
|
148
|
-
export {
|
|
149
|
-
chunkArray,
|
|
150
|
-
flattenRoutes,
|
|
151
|
-
formatOutput,
|
|
152
|
-
formatPath,
|
|
153
|
-
getOutput,
|
|
154
|
-
getUrlPrefix,
|
|
155
|
-
isDynamicUrl,
|
|
156
|
-
openRouteSSR,
|
|
157
|
-
readJSONSpec,
|
|
158
|
-
replaceWithAlias,
|
|
159
|
-
standardOptions,
|
|
160
|
-
writeJSONSpec
|
|
161
|
-
};
|
|
@@ -1,62 +0,0 @@
|
|
|
1
|
-
import childProcess from "child_process";
|
|
2
|
-
import path from "path";
|
|
3
|
-
import { logger } from "@modern-js/utils";
|
|
4
|
-
import { openRouteSSR } from "../libs/util";
|
|
5
|
-
import { CLOSE_SIGN } from "./consts";
|
|
6
|
-
const createServer = (api, ssgRoutes, pageRoutes, apiRoutes, options, appDirectory) => new Promise((resolve, reject) => {
|
|
7
|
-
var _cp_stderr, _cp_stdout;
|
|
8
|
-
const entries = ssgRoutes.map((route) => route.entryName);
|
|
9
|
-
const backup = openRouteSSR(pageRoutes, entries);
|
|
10
|
-
const total = backup.concat(apiRoutes);
|
|
11
|
-
const cp = childProcess.fork(path.join(__dirname, "process"), {
|
|
12
|
-
cwd: appDirectory,
|
|
13
|
-
silent: true
|
|
14
|
-
});
|
|
15
|
-
const appContext = api.useAppContext();
|
|
16
|
-
const plugins = appContext.serverPlugins;
|
|
17
|
-
cp.send(JSON.stringify({
|
|
18
|
-
options,
|
|
19
|
-
renderRoutes: ssgRoutes,
|
|
20
|
-
routes: total,
|
|
21
|
-
appContext: {
|
|
22
|
-
// Make sure that bff runs the product of the dist directory, because we dont register ts-node in the child process
|
|
23
|
-
apiDirectory: path.join(appContext.distDirectory, path.relative(appContext.appDirectory, appContext.apiDirectory)),
|
|
24
|
-
lambdaDirectory: path.join(appContext.distDirectory, path.relative(appContext.appDirectory, appContext.lambdaDirectory)),
|
|
25
|
-
appDirectory: appContext.appDirectory
|
|
26
|
-
},
|
|
27
|
-
plugins,
|
|
28
|
-
distDirectory: appContext.distDirectory
|
|
29
|
-
}));
|
|
30
|
-
const htmlChunks = [];
|
|
31
|
-
const htmlAry = [];
|
|
32
|
-
cp.on("message", (chunk) => {
|
|
33
|
-
if (chunk !== null) {
|
|
34
|
-
htmlChunks.push(chunk);
|
|
35
|
-
} else {
|
|
36
|
-
const html = htmlChunks.join("");
|
|
37
|
-
htmlAry.push(html);
|
|
38
|
-
htmlChunks.length = 0;
|
|
39
|
-
}
|
|
40
|
-
if (htmlAry.length === ssgRoutes.length) {
|
|
41
|
-
cp.send(CLOSE_SIGN);
|
|
42
|
-
resolve(htmlAry);
|
|
43
|
-
}
|
|
44
|
-
});
|
|
45
|
-
(_cp_stderr = cp.stderr) === null || _cp_stderr === void 0 ? void 0 : _cp_stderr.on("data", (chunk) => {
|
|
46
|
-
const str = chunk.toString();
|
|
47
|
-
if (str.includes("Error")) {
|
|
48
|
-
logger.error(str);
|
|
49
|
-
reject(new Error("ssg render failed"));
|
|
50
|
-
cp.kill("SIGKILL");
|
|
51
|
-
} else {
|
|
52
|
-
logger.info(str.replace(/[^\S\n]+/g, " "));
|
|
53
|
-
}
|
|
54
|
-
});
|
|
55
|
-
(_cp_stdout = cp.stdout) === null || _cp_stdout === void 0 ? void 0 : _cp_stdout.on("data", (chunk) => {
|
|
56
|
-
const str = chunk.toString();
|
|
57
|
-
logger.info(str.replace(/[^\S\n]+/g, " "));
|
|
58
|
-
});
|
|
59
|
-
});
|
|
60
|
-
export {
|
|
61
|
-
createServer
|
|
62
|
-
};
|
|
@@ -1,37 +0,0 @@
|
|
|
1
|
-
import EventEmitter from "events";
|
|
2
|
-
import { Readable } from "stream";
|
|
3
|
-
import httpMocks from "node-mocks-http";
|
|
4
|
-
const compile = (requestHandler) => (options, extend = {}) => new Promise((resolve, reject) => {
|
|
5
|
-
const req = httpMocks.createRequest({
|
|
6
|
-
...options,
|
|
7
|
-
eventEmitter: Readable
|
|
8
|
-
});
|
|
9
|
-
const res = httpMocks.createResponse({
|
|
10
|
-
eventEmitter: EventEmitter
|
|
11
|
-
});
|
|
12
|
-
Object.assign(req, extend);
|
|
13
|
-
const proxyRes = new Proxy(res, {
|
|
14
|
-
get(obj, prop) {
|
|
15
|
-
if (typeof prop === "symbol" && !obj[prop]) {
|
|
16
|
-
return null;
|
|
17
|
-
}
|
|
18
|
-
return obj[prop];
|
|
19
|
-
}
|
|
20
|
-
});
|
|
21
|
-
res.on("finish", () => {
|
|
22
|
-
if (res.statusCode !== 200) {
|
|
23
|
-
reject(new Error(res.statusMessage));
|
|
24
|
-
} else {
|
|
25
|
-
resolve(res._getData());
|
|
26
|
-
}
|
|
27
|
-
});
|
|
28
|
-
res.on("error", (e) => reject(e));
|
|
29
|
-
try {
|
|
30
|
-
requestHandler(req, proxyRes);
|
|
31
|
-
} catch (e) {
|
|
32
|
-
reject(e);
|
|
33
|
-
}
|
|
34
|
-
});
|
|
35
|
-
export {
|
|
36
|
-
compile
|
|
37
|
-
};
|
|
@@ -1,85 +0,0 @@
|
|
|
1
|
-
import assert from "node:assert";
|
|
2
|
-
import { request } from "node:http";
|
|
3
|
-
import { createProdServer, loadServerPlugins } from "@modern-js/prod-server";
|
|
4
|
-
import { createLogger } from "@modern-js/utils";
|
|
5
|
-
import portfinder from "portfinder";
|
|
6
|
-
import { chunkArray } from "../libs/util";
|
|
7
|
-
import { CLOSE_SIGN } from "./consts";
|
|
8
|
-
function getLogger() {
|
|
9
|
-
const logger = createLogger({
|
|
10
|
-
level: "verbose"
|
|
11
|
-
});
|
|
12
|
-
return {
|
|
13
|
-
...logger,
|
|
14
|
-
error: (...args) => {
|
|
15
|
-
console.error(...args);
|
|
16
|
-
}
|
|
17
|
-
};
|
|
18
|
-
}
|
|
19
|
-
const MAX_CONCURRENT_REQUESTS = 10;
|
|
20
|
-
process.on("message", async (chunk) => {
|
|
21
|
-
if (chunk === CLOSE_SIGN) {
|
|
22
|
-
process.exit();
|
|
23
|
-
}
|
|
24
|
-
const context = JSON.parse(chunk);
|
|
25
|
-
const { routes, renderRoutes, options, appContext, plugins, distDirectory } = context;
|
|
26
|
-
let nodeServer = null;
|
|
27
|
-
try {
|
|
28
|
-
const { server: serverConfig } = options;
|
|
29
|
-
const defaultPort = Number(process.env.PORT) || serverConfig.port;
|
|
30
|
-
portfinder.basePort = defaultPort;
|
|
31
|
-
const port = await portfinder.getPortPromise();
|
|
32
|
-
const serverOptions = {
|
|
33
|
-
pwd: distDirectory,
|
|
34
|
-
config: options,
|
|
35
|
-
appContext,
|
|
36
|
-
// TODO
|
|
37
|
-
serverConfigPath: "",
|
|
38
|
-
routes,
|
|
39
|
-
plugins: await loadServerPlugins(plugins, appContext.appDirectory || distDirectory),
|
|
40
|
-
staticGenerate: true,
|
|
41
|
-
logger: getLogger()
|
|
42
|
-
};
|
|
43
|
-
assert(process.send, "process.send is not available");
|
|
44
|
-
const sendProcessMessage = process.send.bind(process);
|
|
45
|
-
nodeServer = await createProdServer(serverOptions);
|
|
46
|
-
nodeServer.listen(port, async () => {
|
|
47
|
-
if (!nodeServer)
|
|
48
|
-
return;
|
|
49
|
-
const chunkedRoutes = chunkArray(renderRoutes, MAX_CONCURRENT_REQUESTS);
|
|
50
|
-
for (const routes2 of chunkedRoutes) {
|
|
51
|
-
const promises = routes2.map(async (route) => getHtml(`http://localhost:${port}${route.urlPath}`, port));
|
|
52
|
-
for (const result of await Promise.all(promises)) {
|
|
53
|
-
sendProcessMessage(result);
|
|
54
|
-
sendProcessMessage(null);
|
|
55
|
-
}
|
|
56
|
-
}
|
|
57
|
-
nodeServer.close();
|
|
58
|
-
});
|
|
59
|
-
} catch (e) {
|
|
60
|
-
nodeServer === null || nodeServer === void 0 ? void 0 : nodeServer.close();
|
|
61
|
-
process.stderr.write(e instanceof Error ? e.stack : e.toString());
|
|
62
|
-
}
|
|
63
|
-
});
|
|
64
|
-
function getHtml(url, port) {
|
|
65
|
-
const headers = {
|
|
66
|
-
host: `localhost:${port}`
|
|
67
|
-
};
|
|
68
|
-
return new Promise((resolve, reject) => {
|
|
69
|
-
request(url, {
|
|
70
|
-
headers
|
|
71
|
-
}, (res) => {
|
|
72
|
-
const chunks = [];
|
|
73
|
-
res.on("error", (error) => {
|
|
74
|
-
reject(error);
|
|
75
|
-
});
|
|
76
|
-
res.on("data", (chunk) => {
|
|
77
|
-
chunks.push(chunk);
|
|
78
|
-
});
|
|
79
|
-
res.on("end", () => {
|
|
80
|
-
const html = Buffer.concat(chunks).toString();
|
|
81
|
-
resolve(html);
|
|
82
|
-
});
|
|
83
|
-
}).end();
|
|
84
|
-
});
|
|
85
|
-
}
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
export {};
|
|
File without changes
|
|
File without changes
|