@modern-js/plugin-ssg 1.21.5 → 2.0.0-beta.1
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/CHANGELOG.md +49 -17
- package/dist/js/modern/index.js +24 -34
- package/dist/js/modern/libs/make.js +0 -4
- package/dist/js/modern/libs/output.js +0 -2
- package/dist/js/modern/libs/replace.js +6 -15
- package/dist/js/modern/libs/util.js +35 -28
- package/dist/js/modern/server/index.js +1 -4
- package/dist/js/modern/server/prerender.js +0 -6
- package/dist/js/modern/server/process.js +9 -28
- package/dist/js/node/index.js +23 -46
- package/dist/js/node/libs/make.js +0 -9
- package/dist/js/node/libs/output.js +0 -7
- package/dist/js/node/libs/replace.js +6 -19
- package/dist/js/node/libs/util.js +36 -46
- package/dist/js/node/server/index.js +1 -16
- package/dist/js/node/server/prerender.js +0 -14
- package/dist/js/node/server/process.js +9 -34
- package/dist/types/index.d.ts +0 -2
- package/dist/types/libs/util.d.ts +3 -2
- package/dist/types/types.d.ts +5 -4
- package/package.json +19 -36
package/CHANGELOG.md
CHANGED
|
@@ -1,22 +1,54 @@
|
|
|
1
1
|
# @modern-js/plugin-ssg
|
|
2
2
|
|
|
3
|
-
##
|
|
4
|
-
|
|
5
|
-
###
|
|
6
|
-
|
|
7
|
-
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
-
|
|
3
|
+
## 2.0.0-beta.1
|
|
4
|
+
|
|
5
|
+
### Major Changes
|
|
6
|
+
|
|
7
|
+
- dda38c9: chore: v2
|
|
8
|
+
|
|
9
|
+
### Patch Changes
|
|
10
|
+
|
|
11
|
+
- cc971eabfc: refactor: move server plugin load logic in `@modern-js/core`
|
|
12
|
+
refactor:移除在 `@modern-js/core` 中的 server 插件加载逻辑
|
|
13
|
+
- 8b8e1bb571: feat: support nested routes
|
|
14
|
+
feat: 支持嵌套路由
|
|
15
|
+
- Updated dependencies [92f0ead]
|
|
16
|
+
- Updated dependencies [edd1cfb1af]
|
|
17
|
+
- Updated dependencies [cc971eabfc]
|
|
18
|
+
- Updated dependencies [5b9049f]
|
|
19
|
+
- Updated dependencies [92004d1]
|
|
20
|
+
- Updated dependencies [b8bbe036c7]
|
|
21
|
+
- Updated dependencies [d5a31df781]
|
|
22
|
+
- Updated dependencies [dda38c9]
|
|
23
|
+
- Updated dependencies [3bbea92b2a]
|
|
24
|
+
- Updated dependencies [abf3421]
|
|
25
|
+
- Updated dependencies [543be9558e]
|
|
26
|
+
- Updated dependencies [14b712d]
|
|
27
|
+
- @modern-js/utils@2.0.0-beta.1
|
|
28
|
+
|
|
29
|
+
## 2.0.0-beta.0
|
|
30
|
+
|
|
31
|
+
### Major Changes
|
|
32
|
+
|
|
33
|
+
- dda38c9: chore: v2
|
|
34
|
+
|
|
35
|
+
### Patch Changes
|
|
36
|
+
|
|
37
|
+
- cc971eabf: refactor: move server plugin load logic in `@modern-js/core`
|
|
38
|
+
refactor:移除在 `@modern-js/core` 中的 server 插件加载逻辑
|
|
39
|
+
- 8b8e1bb57: feat: support nested routes
|
|
40
|
+
feat: 支持嵌套路由
|
|
41
|
+
- Updated dependencies [edd1cfb1a]
|
|
42
|
+
- Updated dependencies [cc971eabf]
|
|
43
|
+
- Updated dependencies [5b9049f]
|
|
44
|
+
- Updated dependencies [b8bbe036c]
|
|
45
|
+
- Updated dependencies [d5a31df78]
|
|
46
|
+
- Updated dependencies [dda38c9]
|
|
47
|
+
- Updated dependencies [3bbea92b2]
|
|
48
|
+
- Updated dependencies [abf3421]
|
|
49
|
+
- Updated dependencies [543be95]
|
|
50
|
+
- Updated dependencies [14b712d]
|
|
51
|
+
- @modern-js/utils@2.0.0-beta.0
|
|
20
52
|
|
|
21
53
|
## 1.21.2
|
|
22
54
|
|
package/dist/js/modern/index.js
CHANGED
|
@@ -1,26 +1,23 @@
|
|
|
1
1
|
function ownKeys(object, enumerableOnly) { var keys = Object.keys(object); if (Object.getOwnPropertySymbols) { var symbols = Object.getOwnPropertySymbols(object); enumerableOnly && (symbols = symbols.filter(function (sym) { return Object.getOwnPropertyDescriptor(object, sym).enumerable; })), keys.push.apply(keys, symbols); } return keys; }
|
|
2
|
-
|
|
3
2
|
function _objectSpread(target) { for (var i = 1; i < arguments.length; i++) { var source = null != arguments[i] ? arguments[i] : {}; i % 2 ? ownKeys(Object(source), !0).forEach(function (key) { _defineProperty(target, key, source[key]); }) : Object.getOwnPropertyDescriptors ? Object.defineProperties(target, Object.getOwnPropertyDescriptors(source)) : ownKeys(Object(source)).forEach(function (key) { Object.defineProperty(target, key, Object.getOwnPropertyDescriptor(source, key)); }); } return target; }
|
|
4
|
-
|
|
5
3
|
function _defineProperty(obj, key, value) { if (key in obj) { Object.defineProperty(obj, key, { value: value, enumerable: true, configurable: true, writable: true }); } else { obj[key] = value; } return obj; }
|
|
6
|
-
|
|
7
4
|
import path from 'path';
|
|
8
5
|
import { logger, PLUGIN_SCHEMAS } from '@modern-js/utils';
|
|
9
6
|
import { generatePath } from 'react-router-dom';
|
|
10
|
-
import { formatOutput, isDynamicUrl, readJSONSpec, standardOptions, writeJSONSpec } from "./libs/util";
|
|
7
|
+
import { flattenRoutes, formatOutput, isDynamicUrl, readJSONSpec, standardOptions, writeJSONSpec } from "./libs/util";
|
|
11
8
|
import { createServer } from "./server";
|
|
12
9
|
import { writeHtmlFile } from "./libs/output";
|
|
13
10
|
import { replaceRoute } from "./libs/replace";
|
|
14
11
|
import { makeRoute } from "./libs/make";
|
|
15
12
|
export default (() => ({
|
|
16
13
|
name: '@modern-js/plugin-ssg',
|
|
14
|
+
pre: ['@modern-js/plugin-server', '@modern-js/plugin-bff'],
|
|
17
15
|
setup: api => {
|
|
18
16
|
const agreedRouteMap = {};
|
|
19
17
|
return {
|
|
20
18
|
validateSchema() {
|
|
21
19
|
return PLUGIN_SCHEMAS['@modern-js/plugin-ssg'];
|
|
22
20
|
},
|
|
23
|
-
|
|
24
21
|
modifyFileSystemRoutes({
|
|
25
22
|
entrypoint,
|
|
26
23
|
routes
|
|
@@ -28,13 +25,13 @@ export default (() => ({
|
|
|
28
25
|
const {
|
|
29
26
|
entryName
|
|
30
27
|
} = entrypoint;
|
|
31
|
-
|
|
28
|
+
const flattedRoutes = flattenRoutes(routes);
|
|
29
|
+
agreedRouteMap[entryName] = flattedRoutes;
|
|
32
30
|
return {
|
|
33
31
|
entrypoint,
|
|
34
32
|
routes
|
|
35
33
|
};
|
|
36
34
|
},
|
|
37
|
-
|
|
38
35
|
async afterBuild() {
|
|
39
36
|
const resolvedConfig = api.useResolvedConfigContext();
|
|
40
37
|
const appContext = api.useAppContext();
|
|
@@ -50,30 +47,28 @@ export default (() => ({
|
|
|
50
47
|
ssg,
|
|
51
48
|
path: outputPath
|
|
52
49
|
} = output;
|
|
53
|
-
const ssgOptions = Array.isArray(ssg) ? ssg.pop() : ssg;
|
|
54
|
-
|
|
50
|
+
const ssgOptions = Array.isArray(ssg) ? ssg.pop() : ssg;
|
|
51
|
+
// no ssg configuration, skip ssg render.
|
|
55
52
|
if (!ssgOptions) {
|
|
56
53
|
return;
|
|
57
54
|
}
|
|
58
|
-
|
|
59
55
|
const buildDir = path.join(appDirectory, outputPath);
|
|
60
|
-
const routes = readJSONSpec(buildDir);
|
|
56
|
+
const routes = readJSONSpec(buildDir);
|
|
61
57
|
|
|
58
|
+
// filter all routes not web
|
|
62
59
|
const pageRoutes = routes.filter(route => !route.isApi);
|
|
63
|
-
const apiRoutes = routes.filter(route => route.isApi);
|
|
60
|
+
const apiRoutes = routes.filter(route => route.isApi);
|
|
64
61
|
|
|
62
|
+
// if no web page route, skip ssg render
|
|
65
63
|
if (pageRoutes.length === 0) {
|
|
66
64
|
return;
|
|
67
65
|
}
|
|
68
|
-
|
|
69
66
|
const intermediateOptions = standardOptions(ssgOptions, entrypoints, pageRoutes, server);
|
|
70
|
-
|
|
71
67
|
if (!intermediateOptions) {
|
|
72
68
|
return;
|
|
73
69
|
}
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
70
|
+
const ssgRoutes = [];
|
|
71
|
+
// each route will try to match the configuration
|
|
77
72
|
pageRoutes.forEach(pageRoute => {
|
|
78
73
|
const {
|
|
79
74
|
entryName,
|
|
@@ -81,14 +76,13 @@ export default (() => ({
|
|
|
81
76
|
} = pageRoute;
|
|
82
77
|
const agreedRoutes = agreedRouteMap[entryName];
|
|
83
78
|
let entryOptions = intermediateOptions[entryName] || intermediateOptions[pageRoute.urlPath];
|
|
84
|
-
|
|
85
79
|
if (!agreedRoutes) {
|
|
86
80
|
// default behavior for non-agreed route
|
|
87
81
|
if (!entryOptions) {
|
|
88
82
|
return;
|
|
89
|
-
}
|
|
90
|
-
|
|
83
|
+
}
|
|
91
84
|
|
|
85
|
+
// only add entry route if entryOptions is true
|
|
92
86
|
if (entryOptions === true) {
|
|
93
87
|
ssgRoutes.push(_objectSpread(_objectSpread({}, pageRoute), {}, {
|
|
94
88
|
output: entryPath
|
|
@@ -110,7 +104,6 @@ export default (() => ({
|
|
|
110
104
|
if (!entryOptions) {
|
|
111
105
|
return;
|
|
112
106
|
}
|
|
113
|
-
|
|
114
107
|
if (entryOptions === true) {
|
|
115
108
|
entryOptions = {
|
|
116
109
|
preventDefault: [],
|
|
@@ -118,13 +111,12 @@ export default (() => ({
|
|
|
118
111
|
headers: {}
|
|
119
112
|
};
|
|
120
113
|
}
|
|
121
|
-
|
|
122
114
|
const {
|
|
123
115
|
preventDefault = [],
|
|
124
116
|
routes: userRoutes = [],
|
|
125
117
|
headers
|
|
126
|
-
} = entryOptions;
|
|
127
|
-
|
|
118
|
+
} = entryOptions;
|
|
119
|
+
// if the user sets the routes, then only add them
|
|
128
120
|
if (userRoutes.length > 0) {
|
|
129
121
|
userRoutes.forEach(route => {
|
|
130
122
|
if (typeof route === 'string') {
|
|
@@ -149,36 +141,34 @@ export default (() => ({
|
|
|
149
141
|
}
|
|
150
142
|
}
|
|
151
143
|
});
|
|
152
|
-
|
|
153
144
|
if (ssgRoutes.length === 0) {
|
|
154
145
|
return;
|
|
155
|
-
}
|
|
156
|
-
|
|
146
|
+
}
|
|
157
147
|
|
|
148
|
+
// currently SSG and SSR cannot be turned on at the same time、same route
|
|
158
149
|
ssgRoutes.forEach(ssgRoute => {
|
|
159
150
|
if (ssgRoute.isSSR) {
|
|
160
151
|
const isOriginRoute = pageRoutes.some(pageRoute => pageRoute.urlPath === ssgRoute.urlPath && pageRoute.entryName === ssgRoute.entryName);
|
|
161
|
-
|
|
162
152
|
if (isOriginRoute) {
|
|
163
153
|
throw new Error(`ssg can not using with ssr,url - ${ssgRoute.urlPath}, entry - ${ssgRoute.entryName} `);
|
|
164
154
|
}
|
|
165
|
-
|
|
166
155
|
logger.warn(`new ssg route ${ssgRoute.urlPath} is using ssr now,maybe from parent route ${ssgRoute.entryName},close ssr`);
|
|
167
156
|
}
|
|
168
|
-
|
|
169
157
|
ssgRoute.isSSR = false;
|
|
170
158
|
ssgRoute.output = formatOutput(ssgRoute.output);
|
|
171
159
|
});
|
|
172
|
-
const htmlAry = await createServer(api, ssgRoutes, pageRoutes, apiRoutes, resolvedConfig, appDirectory);
|
|
160
|
+
const htmlAry = await createServer(api, ssgRoutes, pageRoutes, apiRoutes, resolvedConfig, appDirectory);
|
|
173
161
|
|
|
174
|
-
|
|
162
|
+
// write to dist file
|
|
163
|
+
writeHtmlFile(htmlAry, ssgRoutes, buildDir);
|
|
175
164
|
|
|
176
|
-
|
|
165
|
+
// format route info, side effect
|
|
166
|
+
replaceRoute(ssgRoutes, pageRoutes);
|
|
177
167
|
|
|
168
|
+
// write routes to spec file
|
|
178
169
|
writeJSONSpec(buildDir, pageRoutes.concat(apiRoutes));
|
|
179
170
|
logger.info('ssg Compiled successfully');
|
|
180
171
|
}
|
|
181
|
-
|
|
182
172
|
};
|
|
183
173
|
}
|
|
184
174
|
}));
|
|
@@ -1,9 +1,6 @@
|
|
|
1
1
|
function ownKeys(object, enumerableOnly) { var keys = Object.keys(object); if (Object.getOwnPropertySymbols) { var symbols = Object.getOwnPropertySymbols(object); enumerableOnly && (symbols = symbols.filter(function (sym) { return Object.getOwnPropertyDescriptor(object, sym).enumerable; })), keys.push.apply(keys, symbols); } return keys; }
|
|
2
|
-
|
|
3
2
|
function _objectSpread(target) { for (var i = 1; i < arguments.length; i++) { var source = null != arguments[i] ? arguments[i] : {}; i % 2 ? ownKeys(Object(source), !0).forEach(function (key) { _defineProperty(target, key, source[key]); }) : Object.getOwnPropertyDescriptors ? Object.defineProperties(target, Object.getOwnPropertyDescriptors(source)) : ownKeys(Object(source)).forEach(function (key) { Object.defineProperty(target, key, Object.getOwnPropertyDescriptor(source, key)); }); } return target; }
|
|
4
|
-
|
|
5
3
|
function _defineProperty(obj, key, value) { if (key in obj) { Object.defineProperty(obj, key, { value: value, enumerable: true, configurable: true, writable: true }); } else { obj[key] = value; } return obj; }
|
|
6
|
-
|
|
7
4
|
import path from 'path';
|
|
8
5
|
import normalize from 'normalize-path';
|
|
9
6
|
export function makeRender(ssgRoutes, render, port) {
|
|
@@ -20,7 +17,6 @@ export function makeRoute(baseRoute, route, headers = {}) {
|
|
|
20
17
|
urlPath,
|
|
21
18
|
entryPath
|
|
22
19
|
} = baseRoute;
|
|
23
|
-
|
|
24
20
|
if (typeof route === 'string') {
|
|
25
21
|
return _objectSpread(_objectSpread({}, baseRoute), {}, {
|
|
26
22
|
urlPath: normalize(`${urlPath}${route}`) || '/',
|
|
@@ -4,11 +4,9 @@ export function writeHtmlFile(htmlAry, ssgRoutes, baseDir) {
|
|
|
4
4
|
htmlAry.forEach((html, index) => {
|
|
5
5
|
const ssgRoute = ssgRoutes[index];
|
|
6
6
|
const filepath = path.join(baseDir, ssgRoute.output);
|
|
7
|
-
|
|
8
7
|
if (!fs.existsSync(path.dirname(filepath))) {
|
|
9
8
|
fs.ensureDirSync(path.dirname(filepath));
|
|
10
9
|
}
|
|
11
|
-
|
|
12
10
|
fs.writeFileSync(filepath, html);
|
|
13
11
|
});
|
|
14
12
|
}
|
|
@@ -1,25 +1,17 @@
|
|
|
1
1
|
const _excluded = ["output", "headers"];
|
|
2
|
-
|
|
3
2
|
function ownKeys(object, enumerableOnly) { var keys = Object.keys(object); if (Object.getOwnPropertySymbols) { var symbols = Object.getOwnPropertySymbols(object); enumerableOnly && (symbols = symbols.filter(function (sym) { return Object.getOwnPropertyDescriptor(object, sym).enumerable; })), keys.push.apply(keys, symbols); } return keys; }
|
|
4
|
-
|
|
5
3
|
function _objectSpread(target) { for (var i = 1; i < arguments.length; i++) { var source = null != arguments[i] ? arguments[i] : {}; i % 2 ? ownKeys(Object(source), !0).forEach(function (key) { _defineProperty(target, key, source[key]); }) : Object.getOwnPropertyDescriptors ? Object.defineProperties(target, Object.getOwnPropertyDescriptors(source)) : ownKeys(Object(source)).forEach(function (key) { Object.defineProperty(target, key, Object.getOwnPropertyDescriptor(source, key)); }); } return target; }
|
|
6
|
-
|
|
7
4
|
function _defineProperty(obj, key, value) { if (key in obj) { Object.defineProperty(obj, key, { value: value, enumerable: true, configurable: true, writable: true }); } else { obj[key] = value; } return obj; }
|
|
8
|
-
|
|
9
5
|
function _objectWithoutProperties(source, excluded) { if (source == null) return {}; var target = _objectWithoutPropertiesLoose(source, excluded); var key, i; if (Object.getOwnPropertySymbols) { var sourceSymbolKeys = Object.getOwnPropertySymbols(source); for (i = 0; i < sourceSymbolKeys.length; i++) { key = sourceSymbolKeys[i]; if (excluded.indexOf(key) >= 0) continue; if (!Object.prototype.propertyIsEnumerable.call(source, key)) continue; target[key] = source[key]; } } return target; }
|
|
10
|
-
|
|
11
6
|
function _objectWithoutPropertiesLoose(source, excluded) { if (source == null) return {}; var target = {}; var sourceKeys = Object.keys(source); var key, i; for (i = 0; i < sourceKeys.length; i++) { key = sourceKeys[i]; if (excluded.indexOf(key) >= 0) continue; target[key] = source[key]; } return target; }
|
|
12
|
-
|
|
13
7
|
import normalize from 'normalize-path';
|
|
14
8
|
export function exist(route, pageRoutes) {
|
|
15
9
|
return pageRoutes.slice().findIndex(pageRoute => {
|
|
16
10
|
const urlEqual = normalize(pageRoute.urlPath) === normalize(route.urlPath);
|
|
17
11
|
const entryEqual = pageRoute.entryName === route.entryName;
|
|
18
|
-
|
|
19
12
|
if (urlEqual && entryEqual) {
|
|
20
13
|
return true;
|
|
21
14
|
}
|
|
22
|
-
|
|
23
15
|
return false;
|
|
24
16
|
});
|
|
25
17
|
}
|
|
@@ -27,20 +19,19 @@ export function replaceRoute(ssgRoutes, pageRoutes) {
|
|
|
27
19
|
// remove redundant fields and replace rendered entryPath
|
|
28
20
|
const cleanSsgRoutes = ssgRoutes.map(ssgRoute => {
|
|
29
21
|
const {
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
22
|
+
output,
|
|
23
|
+
headers
|
|
24
|
+
} = ssgRoute,
|
|
25
|
+
cleanSsgRoute = _objectWithoutProperties(ssgRoute, _excluded);
|
|
35
26
|
return Object.assign(cleanSsgRoute, output ? {
|
|
36
27
|
entryPath: output
|
|
37
28
|
} : {});
|
|
38
|
-
});
|
|
29
|
+
});
|
|
39
30
|
|
|
31
|
+
// all routes that need to be added and replaced
|
|
40
32
|
const freshRoutes = [];
|
|
41
33
|
cleanSsgRoutes.forEach(ssgRoute => {
|
|
42
34
|
const index = exist(ssgRoute, pageRoutes);
|
|
43
|
-
|
|
44
35
|
if (index < 0) {
|
|
45
36
|
// new route
|
|
46
37
|
freshRoutes.push(_objectSpread({}, ssgRoute));
|
|
@@ -1,9 +1,6 @@
|
|
|
1
1
|
function ownKeys(object, enumerableOnly) { var keys = Object.keys(object); if (Object.getOwnPropertySymbols) { var symbols = Object.getOwnPropertySymbols(object); enumerableOnly && (symbols = symbols.filter(function (sym) { return Object.getOwnPropertyDescriptor(object, sym).enumerable; })), keys.push.apply(keys, symbols); } return keys; }
|
|
2
|
-
|
|
3
2
|
function _objectSpread(target) { for (var i = 1; i < arguments.length; i++) { var source = null != arguments[i] ? arguments[i] : {}; i % 2 ? ownKeys(Object(source), !0).forEach(function (key) { _defineProperty(target, key, source[key]); }) : Object.getOwnPropertyDescriptors ? Object.defineProperties(target, Object.getOwnPropertyDescriptors(source)) : ownKeys(Object(source)).forEach(function (key) { Object.defineProperty(target, key, Object.getOwnPropertyDescriptor(source, key)); }); } return target; }
|
|
4
|
-
|
|
5
3
|
function _defineProperty(obj, key, value) { if (key in obj) { Object.defineProperty(obj, key, { value: value, enumerable: true, configurable: true, writable: true }); } else { obj[key] = value; } return obj; }
|
|
6
|
-
|
|
7
4
|
import path from 'path';
|
|
8
5
|
import { ROUTE_SPEC_FILE, fs, isSingleEntry, SERVER_BUNDLE_DIRECTORY } from '@modern-js/utils';
|
|
9
6
|
export function formatOutput(filename) {
|
|
@@ -12,23 +9,18 @@ export function formatOutput(filename) {
|
|
|
12
9
|
}
|
|
13
10
|
export function formatPath(str) {
|
|
14
11
|
let addr = str;
|
|
15
|
-
|
|
16
12
|
if (!addr || typeof addr !== 'string') {
|
|
17
13
|
return addr;
|
|
18
14
|
}
|
|
19
|
-
|
|
20
15
|
if (addr.startsWith('.')) {
|
|
21
16
|
addr = addr.slice(1);
|
|
22
17
|
}
|
|
23
|
-
|
|
24
18
|
if (!addr.startsWith('/')) {
|
|
25
19
|
addr = `/${addr}`;
|
|
26
20
|
}
|
|
27
|
-
|
|
28
21
|
if (addr.endsWith('/') && addr !== '/') {
|
|
29
22
|
addr = addr.slice(0, addr.length - 1);
|
|
30
23
|
}
|
|
31
|
-
|
|
32
24
|
return addr;
|
|
33
25
|
}
|
|
34
26
|
export function isDynamicUrl(url) {
|
|
@@ -36,51 +28,44 @@ export function isDynamicUrl(url) {
|
|
|
36
28
|
}
|
|
37
29
|
export function getUrlPrefix(route, baseUrl) {
|
|
38
30
|
let base = '';
|
|
39
|
-
|
|
40
31
|
if (Array.isArray(baseUrl)) {
|
|
41
32
|
const filters = baseUrl.filter(url => route.urlPath.includes(url));
|
|
42
|
-
|
|
43
33
|
if (filters.length > 1) {
|
|
44
|
-
const matched = filters.sort((a, b) => a.length - b.length)[0];
|
|
34
|
+
const matched = filters.sort((a, b) => a.length - b.length)[0];
|
|
45
35
|
|
|
36
|
+
// this should never happened
|
|
46
37
|
if (!matched) {
|
|
47
38
|
throw new Error('');
|
|
48
39
|
}
|
|
49
|
-
|
|
50
40
|
base = matched;
|
|
51
41
|
}
|
|
52
42
|
} else {
|
|
53
43
|
base = baseUrl;
|
|
54
44
|
}
|
|
55
|
-
|
|
56
45
|
base = base === '/' ? '' : base;
|
|
57
46
|
const entryName = route.entryName === 'main' ? '' : route.entryName;
|
|
58
47
|
const prefix = `${base}/${entryName}`;
|
|
59
48
|
return prefix.endsWith('/') ? prefix.slice(0, -1) : prefix;
|
|
60
|
-
}
|
|
61
|
-
// or throw error for control-route
|
|
49
|
+
}
|
|
62
50
|
|
|
51
|
+
// if no output, return default path for aggred-route(relative),
|
|
52
|
+
// or throw error for control-route
|
|
63
53
|
export function getOutput(route, base, agreed) {
|
|
64
54
|
const {
|
|
65
55
|
output
|
|
66
56
|
} = route;
|
|
67
|
-
|
|
68
57
|
if (output) {
|
|
69
58
|
return output;
|
|
70
59
|
}
|
|
71
|
-
|
|
72
60
|
if (agreed) {
|
|
73
61
|
const urlWithoutBase = route.urlPath.replace(base, '');
|
|
74
62
|
return urlWithoutBase.startsWith('/') ? urlWithoutBase.slice(1) : urlWithoutBase;
|
|
75
63
|
}
|
|
76
|
-
|
|
77
64
|
throw new Error(`routing must provide output when calling createPage(), check ${route.urlPath}`);
|
|
78
65
|
}
|
|
79
66
|
export const readJSONSpec = dir => {
|
|
80
67
|
const routeJSONPath = path.join(dir, ROUTE_SPEC_FILE);
|
|
81
|
-
|
|
82
68
|
const routeJSON = require(routeJSONPath);
|
|
83
|
-
|
|
84
69
|
const {
|
|
85
70
|
routes
|
|
86
71
|
} = routeJSON;
|
|
@@ -99,7 +84,6 @@ export const standardOptions = (ssgOptions, entrypoints, routes, server) => {
|
|
|
99
84
|
if (ssgOptions === false) {
|
|
100
85
|
return false;
|
|
101
86
|
}
|
|
102
|
-
|
|
103
87
|
if (ssgOptions === true) {
|
|
104
88
|
return entrypoints.reduce((opt, entry) => {
|
|
105
89
|
opt[entry.entryName] = ssgOptions;
|
|
@@ -107,7 +91,6 @@ export const standardOptions = (ssgOptions, entrypoints, routes, server) => {
|
|
|
107
91
|
}, {});
|
|
108
92
|
} else if (typeof ssgOptions === 'object') {
|
|
109
93
|
const isSingle = isSingleEntry(entrypoints);
|
|
110
|
-
|
|
111
94
|
if (isSingle && typeof ssgOptions.main === 'undefined') {
|
|
112
95
|
return {
|
|
113
96
|
main: ssgOptions
|
|
@@ -117,12 +100,11 @@ export const standardOptions = (ssgOptions, entrypoints, routes, server) => {
|
|
|
117
100
|
}
|
|
118
101
|
} else if (typeof ssgOptions === 'function') {
|
|
119
102
|
const intermediateOptions = {};
|
|
120
|
-
|
|
121
103
|
for (const entrypoint of entrypoints) {
|
|
122
104
|
const {
|
|
123
105
|
entryName
|
|
124
|
-
} = entrypoint;
|
|
125
|
-
|
|
106
|
+
} = entrypoint;
|
|
107
|
+
// TODO: may be async function
|
|
126
108
|
if (Array.isArray(server === null || server === void 0 ? void 0 : server.baseUrl)) {
|
|
127
109
|
for (const url of server.baseUrl) {
|
|
128
110
|
const matchUrl = entryName === 'main' ? url : `${url}/${entryName}`;
|
|
@@ -137,13 +119,38 @@ export const standardOptions = (ssgOptions, entrypoints, routes, server) => {
|
|
|
137
119
|
});
|
|
138
120
|
}
|
|
139
121
|
}
|
|
140
|
-
|
|
141
122
|
return intermediateOptions;
|
|
142
123
|
}
|
|
143
|
-
|
|
144
124
|
return false;
|
|
145
125
|
};
|
|
146
126
|
export const openRouteSSR = (routes, entries = []) => routes.map(ssgRoute => _objectSpread(_objectSpread({}, ssgRoute), {}, {
|
|
147
127
|
isSSR: entries.includes(ssgRoute.entryName),
|
|
148
128
|
bundle: `${SERVER_BUNDLE_DIRECTORY}/${ssgRoute.entryName}.js`
|
|
149
|
-
}));
|
|
129
|
+
}));
|
|
130
|
+
|
|
131
|
+
// TODO: 过滤带有 server loader 的路由
|
|
132
|
+
export const flattenRoutes = routes => {
|
|
133
|
+
const parents = [];
|
|
134
|
+
const newRoutes = [];
|
|
135
|
+
const traverseRoute = route => {
|
|
136
|
+
const parent = parents[parents.length - 1];
|
|
137
|
+
let path = parent ? `${parent.path}/${route.path || ''}`.replace(/\/+/g, '/') : route.path || ''; // If the route is an index route, the route has no path property
|
|
138
|
+
path = path.replace(/\/$/, '');
|
|
139
|
+
|
|
140
|
+
// If the route path is / and is not the root route, it should not be used as an ssg route
|
|
141
|
+
if (route._component && (path !== '/' || path === '/' && !parent)) {
|
|
142
|
+
newRoutes.push(_objectSpread(_objectSpread({}, route), {}, {
|
|
143
|
+
path
|
|
144
|
+
}));
|
|
145
|
+
}
|
|
146
|
+
if (route.children) {
|
|
147
|
+
parents.push(_objectSpread(_objectSpread({}, route), {}, {
|
|
148
|
+
path
|
|
149
|
+
}));
|
|
150
|
+
route.children.forEach(traverseRoute);
|
|
151
|
+
parents.pop();
|
|
152
|
+
}
|
|
153
|
+
};
|
|
154
|
+
routes.forEach(traverseRoute);
|
|
155
|
+
return newRoutes;
|
|
156
|
+
};
|
|
@@ -14,7 +14,7 @@ export const createServer = (api, ssgRoutes, pageRoutes, apiRoutes, options, app
|
|
|
14
14
|
silent: true
|
|
15
15
|
});
|
|
16
16
|
const appContext = api.useAppContext();
|
|
17
|
-
const plugins = appContext.
|
|
17
|
+
const plugins = appContext.serverInternalPlugins;
|
|
18
18
|
cp.send(JSON.stringify({
|
|
19
19
|
options,
|
|
20
20
|
renderRoutes: ssgRoutes,
|
|
@@ -32,7 +32,6 @@ export const createServer = (api, ssgRoutes, pageRoutes, apiRoutes, options, app
|
|
|
32
32
|
htmlAry.push(html);
|
|
33
33
|
htmlChunks.length = 0;
|
|
34
34
|
}
|
|
35
|
-
|
|
36
35
|
if (htmlAry.length === ssgRoutes.length) {
|
|
37
36
|
cp.send(CLOSE_SIGN);
|
|
38
37
|
resolve(htmlAry);
|
|
@@ -40,7 +39,6 @@ export const createServer = (api, ssgRoutes, pageRoutes, apiRoutes, options, app
|
|
|
40
39
|
});
|
|
41
40
|
cp.stderr.on('data', chunk => {
|
|
42
41
|
const str = chunk.toString();
|
|
43
|
-
|
|
44
42
|
if (str.includes('Error')) {
|
|
45
43
|
logger.error(str);
|
|
46
44
|
reject(new Error('ssg render failed'));
|
|
@@ -51,7 +49,6 @@ export const createServer = (api, ssgRoutes, pageRoutes, apiRoutes, options, app
|
|
|
51
49
|
});
|
|
52
50
|
cp.stdout.on('data', chunk => {
|
|
53
51
|
const str = chunk.toString();
|
|
54
|
-
|
|
55
52
|
if (str.includes('Error')) {
|
|
56
53
|
logger.error(str);
|
|
57
54
|
reject(new Error('ssg render failed'));
|
|
@@ -1,9 +1,6 @@
|
|
|
1
1
|
function ownKeys(object, enumerableOnly) { var keys = Object.keys(object); if (Object.getOwnPropertySymbols) { var symbols = Object.getOwnPropertySymbols(object); enumerableOnly && (symbols = symbols.filter(function (sym) { return Object.getOwnPropertyDescriptor(object, sym).enumerable; })), keys.push.apply(keys, symbols); } return keys; }
|
|
2
|
-
|
|
3
2
|
function _objectSpread(target) { for (var i = 1; i < arguments.length; i++) { var source = null != arguments[i] ? arguments[i] : {}; i % 2 ? ownKeys(Object(source), !0).forEach(function (key) { _defineProperty(target, key, source[key]); }) : Object.getOwnPropertyDescriptors ? Object.defineProperties(target, Object.getOwnPropertyDescriptors(source)) : ownKeys(Object(source)).forEach(function (key) { Object.defineProperty(target, key, Object.getOwnPropertyDescriptor(source, key)); }); } return target; }
|
|
4
|
-
|
|
5
3
|
function _defineProperty(obj, key, value) { if (key in obj) { Object.defineProperty(obj, key, { value: value, enumerable: true, configurable: true, writable: true }); } else { obj[key] = value; } return obj; }
|
|
6
|
-
|
|
7
4
|
import EventEmitter from 'events';
|
|
8
5
|
import { Readable } from 'stream';
|
|
9
6
|
import httpMocks from 'node-mocks-http';
|
|
@@ -20,10 +17,8 @@ export const compile = requestHandler => (options, extend = {}) => new Promise((
|
|
|
20
17
|
if (typeof prop === 'symbol' && !obj[prop]) {
|
|
21
18
|
return null;
|
|
22
19
|
}
|
|
23
|
-
|
|
24
20
|
return obj[prop];
|
|
25
21
|
}
|
|
26
|
-
|
|
27
22
|
});
|
|
28
23
|
res.on('finish', () => {
|
|
29
24
|
if (res.statusCode !== 200) {
|
|
@@ -33,7 +28,6 @@ export const compile = requestHandler => (options, extend = {}) => new Promise((
|
|
|
33
28
|
}
|
|
34
29
|
});
|
|
35
30
|
res.on('error', e => reject(e));
|
|
36
|
-
|
|
37
31
|
try {
|
|
38
32
|
requestHandler(req, proxyRes);
|
|
39
33
|
} catch (e) {
|
|
@@ -1,28 +1,13 @@
|
|
|
1
1
|
import server from '@modern-js/prod-server';
|
|
2
2
|
import portfinder from 'portfinder';
|
|
3
|
-
import { compatRequire } from '@modern-js/utils';
|
|
4
3
|
import { makeRender } from "../libs/make";
|
|
5
4
|
import { compile as createRender } from "./prerender";
|
|
6
5
|
import { CLOSE_SIGN } from "./consts";
|
|
7
|
-
|
|
8
|
-
const safetyRequire = (filename, base) => {
|
|
9
|
-
try {
|
|
10
|
-
return compatRequire(require.resolve(`${filename}/server`, {
|
|
11
|
-
paths: [base]
|
|
12
|
-
}));
|
|
13
|
-
} catch (e) {
|
|
14
|
-
return compatRequire(require.resolve(filename, {
|
|
15
|
-
paths: [base]
|
|
16
|
-
}));
|
|
17
|
-
}
|
|
18
|
-
};
|
|
19
|
-
|
|
20
6
|
process.on('message', async chunk => {
|
|
21
7
|
if (chunk === CLOSE_SIGN) {
|
|
22
8
|
// eslint-disable-next-line no-process-exit
|
|
23
9
|
process.exit();
|
|
24
10
|
}
|
|
25
|
-
|
|
26
11
|
const context = JSON.parse(chunk);
|
|
27
12
|
const {
|
|
28
13
|
routes,
|
|
@@ -31,17 +16,13 @@ process.on('message', async chunk => {
|
|
|
31
16
|
appDirectory,
|
|
32
17
|
plugins
|
|
33
18
|
} = context;
|
|
34
|
-
const instances = plugins.map(plugin => {
|
|
35
|
-
const mod = safetyRequire(plugin, appDirectory);
|
|
36
|
-
return mod();
|
|
37
|
-
});
|
|
38
19
|
let modernServer = null;
|
|
39
|
-
|
|
40
20
|
try {
|
|
41
21
|
const {
|
|
42
22
|
server: serverOptions
|
|
43
|
-
} = options;
|
|
23
|
+
} = options;
|
|
44
24
|
|
|
25
|
+
// start server in default port
|
|
45
26
|
const defaultPort = Number(process.env.PORT) || serverOptions.port;
|
|
46
27
|
portfinder.basePort = defaultPort;
|
|
47
28
|
const port = await portfinder.getPortPromise();
|
|
@@ -50,22 +31,23 @@ process.on('message', async chunk => {
|
|
|
50
31
|
config: options,
|
|
51
32
|
routes,
|
|
52
33
|
staticGenerate: true,
|
|
53
|
-
|
|
54
|
-
});
|
|
34
|
+
internalPlugins: plugins
|
|
35
|
+
});
|
|
55
36
|
|
|
37
|
+
// listen just for bff request in ssr page
|
|
56
38
|
modernServer.listen(port, async err => {
|
|
57
39
|
if (err) {
|
|
58
40
|
throw err;
|
|
59
41
|
}
|
|
60
|
-
|
|
61
42
|
if (!modernServer) {
|
|
62
43
|
return;
|
|
63
|
-
}
|
|
64
|
-
|
|
44
|
+
}
|
|
65
45
|
|
|
46
|
+
// get server handler, render to ssr
|
|
66
47
|
const render = createRender(modernServer.getRequestHandler());
|
|
67
|
-
const renderPromiseAry = makeRender(renderRoutes, render, port);
|
|
48
|
+
const renderPromiseAry = makeRender(renderRoutes, render, port);
|
|
68
49
|
|
|
50
|
+
// eslint-disable-next-line promise/no-promise-in-callback
|
|
69
51
|
const htmlAry = await Promise.all(renderPromiseAry);
|
|
70
52
|
htmlAry.forEach(html => {
|
|
71
53
|
process.send(html);
|
|
@@ -75,7 +57,6 @@ process.on('message', async chunk => {
|
|
|
75
57
|
});
|
|
76
58
|
} catch (e) {
|
|
77
59
|
var _modernServer;
|
|
78
|
-
|
|
79
60
|
(_modernServer = modernServer) === null || _modernServer === void 0 ? void 0 : _modernServer.close();
|
|
80
61
|
throw e;
|
|
81
62
|
}
|