@modern-js/plugin-ssg 1.0.1 → 1.1.2

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.
Files changed (52) hide show
  1. package/CHANGELOG.md +38 -6
  2. package/dist/js/modern/index.js +96 -58
  3. package/dist/js/modern/libs/make.js +37 -0
  4. package/dist/js/modern/libs/replace.js +5 -4
  5. package/dist/js/modern/libs/util.js +38 -22
  6. package/dist/js/modern/server/index.js +2 -2
  7. package/dist/js/modern/server/prerender.js +2 -2
  8. package/dist/js/modern/server/process.js +1 -1
  9. package/dist/js/modern/types.js +0 -1
  10. package/dist/js/node/index.js +92 -55
  11. package/dist/js/node/libs/make.js +50 -0
  12. package/dist/js/node/libs/replace.js +5 -4
  13. package/dist/js/node/libs/util.js +38 -29
  14. package/dist/js/node/server/index.js +2 -2
  15. package/dist/js/node/server/prerender.js +2 -2
  16. package/dist/js/node/server/process.js +2 -2
  17. package/dist/types/libs/make.d.ts +5 -0
  18. package/dist/types/libs/replace.d.ts +1 -1
  19. package/dist/types/libs/util.d.ts +4 -8
  20. package/dist/types/types.d.ts +13 -17
  21. package/package.json +10 -11
  22. package/src/index.ts +84 -83
  23. package/src/libs/make.ts +45 -0
  24. package/src/libs/output.ts +1 -1
  25. package/src/libs/replace.ts +7 -4
  26. package/src/libs/util.ts +39 -27
  27. package/src/server/index.ts +1 -1
  28. package/src/server/process.ts +3 -2
  29. package/src/types.ts +26 -20
  30. package/tests/lib.test.ts +48 -169
  31. package/tests/util.test.ts +71 -32
  32. package/dist/js/modern/libs/createPage.js +0 -46
  33. package/dist/js/modern/libs/invoker.js +0 -56
  34. package/dist/js/modern/libs/render.js +0 -15
  35. package/dist/js/modern/loader/index.js +0 -105
  36. package/dist/js/modern/manifest-op.js +0 -101
  37. package/dist/js/node/libs/createPage.js +0 -57
  38. package/dist/js/node/libs/invoker.js +0 -67
  39. package/dist/js/node/libs/render.js +0 -22
  40. package/dist/js/node/loader/index.js +0 -115
  41. package/dist/js/node/manifest-op.js +0 -124
  42. package/dist/types/libs/createPage.d.ts +0 -2
  43. package/dist/types/libs/invoker.d.ts +0 -5
  44. package/dist/types/libs/render.d.ts +0 -3
  45. package/dist/types/loader/index.d.ts +0 -4
  46. package/dist/types/manifest-op.d.ts +0 -18
  47. package/src/libs/createPage.ts +0 -42
  48. package/src/libs/invoker.ts +0 -56
  49. package/src/libs/render.ts +0 -16
  50. package/src/loader/index.ts +0 -99
  51. package/src/manifest-op.ts +0 -111
  52. package/tests/operate.test.ts +0 -39
@@ -0,0 +1,50 @@
1
+ "use strict";
2
+
3
+ Object.defineProperty(exports, "__esModule", {
4
+ value: true
5
+ });
6
+ exports.makeRender = makeRender;
7
+ exports.makeRoute = makeRoute;
8
+
9
+ var _path = _interopRequireDefault(require("path"));
10
+
11
+ var _normalizePath = _interopRequireDefault(require("normalize-path"));
12
+
13
+ function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
14
+
15
+ 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; }
16
+
17
+ 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; }
18
+
19
+ 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; }
20
+
21
+ function makeRender(ssgRoutes, render, port) {
22
+ return ssgRoutes.map(ssgRoute => render({
23
+ url: ssgRoute.urlPath,
24
+ headers: _objectSpread({
25
+ host: `localhost:${port}`
26
+ }, ssgRoute.headers),
27
+ connection: {}
28
+ }));
29
+ }
30
+
31
+ function makeRoute(baseRoute, route, headers = {}) {
32
+ const {
33
+ urlPath,
34
+ entryPath
35
+ } = baseRoute;
36
+
37
+ if (typeof route === 'string') {
38
+ return _objectSpread(_objectSpread({}, baseRoute), {}, {
39
+ urlPath: (0, _normalizePath.default)(`${urlPath}${route}`) || '/',
40
+ headers,
41
+ output: _path.default.join(entryPath, `..${route}`)
42
+ });
43
+ } else {
44
+ return _objectSpread(_objectSpread({}, baseRoute), {}, {
45
+ urlPath: (0, _normalizePath.default)(`${urlPath}${route.url}`) || '/',
46
+ headers: _objectSpread(_objectSpread({}, headers), route.headers),
47
+ output: route.output ? _path.default.normalize(route.output) : _path.default.join(entryPath, `..${route.url}`)
48
+ });
49
+ }
50
+ }
@@ -8,13 +8,13 @@ exports.replaceRoute = replaceRoute;
8
8
 
9
9
  var _normalizePath = _interopRequireDefault(require("normalize-path"));
10
10
 
11
- const _excluded = ["output"];
11
+ const _excluded = ["output", "headers"];
12
12
 
13
13
  function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
14
14
 
15
- function ownKeys(object, enumerableOnly) { var keys = Object.keys(object); if (Object.getOwnPropertySymbols) { var symbols = Object.getOwnPropertySymbols(object); if (enumerableOnly) { symbols = symbols.filter(function (sym) { return Object.getOwnPropertyDescriptor(object, sym).enumerable; }); } keys.push.apply(keys, symbols); } return keys; }
15
+ 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; }
16
16
 
17
- function _objectSpread(target) { for (var i = 1; i < arguments.length; i++) { var source = arguments[i] != null ? arguments[i] : {}; if (i % 2) { ownKeys(Object(source), true).forEach(function (key) { _defineProperty(target, key, source[key]); }); } else if (Object.getOwnPropertyDescriptors) { Object.defineProperties(target, Object.getOwnPropertyDescriptors(source)); } else { ownKeys(Object(source)).forEach(function (key) { Object.defineProperty(target, key, Object.getOwnPropertyDescriptor(source, key)); }); } } return target; }
17
+ 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; }
18
18
 
19
19
  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; }
20
20
 
@@ -39,7 +39,8 @@ function replaceRoute(ssgRoutes, pageRoutes) {
39
39
  // remove redundant fields and replace rendered entryPath
40
40
  const cleanSsgRoutes = ssgRoutes.map(ssgRoute => {
41
41
  const {
42
- output
42
+ output,
43
+ headers
43
44
  } = ssgRoute,
44
45
  cleanSsgRoute = _objectWithoutProperties(ssgRoute, _excluded);
45
46
 
@@ -6,25 +6,19 @@ Object.defineProperty(exports, "__esModule", {
6
6
  exports.formatOutput = formatOutput;
7
7
  exports.formatPath = formatPath;
8
8
  exports.getOutput = getOutput;
9
- exports.getSSGRenderLevel = void 0;
10
9
  exports.getUrlPrefix = getUrlPrefix;
11
10
  exports.isDynamicUrl = isDynamicUrl;
12
- exports.writeJSONSpec = exports.replaceWithAlias = exports.readJSONSpec = exports.parsedSSGConfig = void 0;
11
+ exports.writeJSONSpec = exports.standardOptions = exports.replaceWithAlias = exports.readJSONSpec = void 0;
13
12
 
14
13
  var _path = _interopRequireDefault(require("path"));
15
14
 
16
15
  var _utils = require("@modern-js/utils");
17
16
 
18
- var _manifestOp = require("../manifest-op");
19
-
20
17
  function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
21
18
 
22
- function formatOutput(base, filename) {
23
- const file = _path.default.extname(filename) ? filename : `${filename}/index.html`;
24
-
25
- const dirname = _path.default.dirname(base);
26
-
27
- return _path.default.join(dirname, file);
19
+ function formatOutput(filename) {
20
+ const outputPath = _path.default.extname(filename) ? filename : `${filename}/index.html`;
21
+ return outputPath;
28
22
  }
29
23
 
30
24
  function formatPath(str) {
@@ -122,30 +116,45 @@ const writeJSONSpec = (dir, routes) => {
122
116
 
123
117
  exports.writeJSONSpec = writeJSONSpec;
124
118
 
125
- const getSSGRenderLevel = key => {
126
- const level = typeof key === 'boolean' ? _manifestOp.MODE.LOOSE : _manifestOp.MODE[key.toUpperCase()]; // currently only MODE.STRICT and MODE.LOOSE are supported
119
+ const replaceWithAlias = (base, filePath, alias) => _path.default.posix.join(alias, _path.default.posix.relative(base, filePath));
127
120
 
128
- if (!level || level > 2 || level < 1) {
129
- throw new Error(`[SSG Render Fail] SSG 不支持当前 Mode,useSSG: ${key.toString()}, Level: ${level}`);
130
- }
121
+ exports.replaceWithAlias = replaceWithAlias;
131
122
 
132
- return level;
133
- };
123
+ const standardOptions = (ssgOptions, entrypoints) => {
124
+ if (ssgOptions === false) {
125
+ return false;
126
+ }
134
127
 
135
- exports.getSSGRenderLevel = getSSGRenderLevel;
128
+ if (ssgOptions === true) {
129
+ return entrypoints.reduce((opt, entry) => {
130
+ opt[entry.entryName] = ssgOptions;
131
+ return opt;
132
+ }, {});
133
+ } else if (typeof ssgOptions === 'object') {
134
+ const isSingle = (0, _utils.isSingleEntry)(entrypoints);
135
+
136
+ if (isSingle && typeof ssgOptions.main === 'undefined') {
137
+ return {
138
+ main: ssgOptions
139
+ };
140
+ } else {
141
+ return ssgOptions;
142
+ }
143
+ } else if (typeof ssgOptions === 'function') {
144
+ const intermediateOptions = {};
136
145
 
137
- const parsedSSGConfig = ssg => {
138
- const useSSG = Boolean(ssg); // eslint-disable-next-line @typescript-eslint/no-empty-function
146
+ for (const entrypoint of entrypoints) {
147
+ const {
148
+ entryName
149
+ } = entrypoint; // Todo may be async function
139
150
 
140
- const userHook = typeof ssg === 'function' ? ssg : () => {};
141
- return {
142
- useSSG,
143
- userHook
144
- };
145
- };
151
+ intermediateOptions[entryName] = ssgOptions(entryName);
152
+ }
146
153
 
147
- exports.parsedSSGConfig = parsedSSGConfig;
154
+ return intermediateOptions;
155
+ }
148
156
 
149
- const replaceWithAlias = (base, filePath, alias) => _path.default.join(alias, _path.default.relative(base, filePath));
157
+ return false;
158
+ };
150
159
 
151
- exports.replaceWithAlias = replaceWithAlias;
160
+ exports.standardOptions = standardOptions;
@@ -17,9 +17,9 @@ var _consts = require("./consts");
17
17
 
18
18
  function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
19
19
 
20
- function ownKeys(object, enumerableOnly) { var keys = Object.keys(object); if (Object.getOwnPropertySymbols) { var symbols = Object.getOwnPropertySymbols(object); if (enumerableOnly) { symbols = symbols.filter(function (sym) { return Object.getOwnPropertyDescriptor(object, sym).enumerable; }); } keys.push.apply(keys, symbols); } return keys; }
20
+ 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; }
21
21
 
22
- function _objectSpread(target) { for (var i = 1; i < arguments.length; i++) { var source = arguments[i] != null ? arguments[i] : {}; if (i % 2) { ownKeys(Object(source), true).forEach(function (key) { _defineProperty(target, key, source[key]); }); } else if (Object.getOwnPropertyDescriptors) { Object.defineProperties(target, Object.getOwnPropertyDescriptors(source)); } else { ownKeys(Object(source)).forEach(function (key) { Object.defineProperty(target, key, Object.getOwnPropertyDescriptor(source, key)); }); } } return target; }
22
+ 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; }
23
23
 
24
24
  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; }
25
25
 
@@ -13,9 +13,9 @@ var _nodeMocksHttp = _interopRequireDefault(require("node-mocks-http"));
13
13
 
14
14
  function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
15
15
 
16
- function ownKeys(object, enumerableOnly) { var keys = Object.keys(object); if (Object.getOwnPropertySymbols) { var symbols = Object.getOwnPropertySymbols(object); if (enumerableOnly) { symbols = symbols.filter(function (sym) { return Object.getOwnPropertyDescriptor(object, sym).enumerable; }); } keys.push.apply(keys, symbols); } return keys; }
16
+ 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; }
17
17
 
18
- function _objectSpread(target) { for (var i = 1; i < arguments.length; i++) { var source = arguments[i] != null ? arguments[i] : {}; if (i % 2) { ownKeys(Object(source), true).forEach(function (key) { _defineProperty(target, key, source[key]); }); } else if (Object.getOwnPropertyDescriptors) { Object.defineProperties(target, Object.getOwnPropertyDescriptors(source)); } else { ownKeys(Object(source)).forEach(function (key) { Object.defineProperty(target, key, Object.getOwnPropertyDescriptor(source, key)); }); } } return target; }
18
+ 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; }
19
19
 
20
20
  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; }
21
21
 
@@ -6,7 +6,7 @@ var _portfinder = _interopRequireDefault(require("portfinder"));
6
6
 
7
7
  var _utils = require("@modern-js/utils");
8
8
 
9
- var _render = require("../libs/render");
9
+ var _make = require("../libs/make");
10
10
 
11
11
  var _prerender = require("./prerender");
12
12
 
@@ -65,7 +65,7 @@ process.on('message', async chunk => {
65
65
 
66
66
 
67
67
  const render = (0, _prerender.compile)(modernServer.getRequestHandler());
68
- const renderPromiseAry = (0, _render.makeRender)(routes.filter(route => !route.isApi), render, port); // eslint-disable-next-line promise/no-promise-in-callback
68
+ const renderPromiseAry = (0, _make.makeRender)(routes.filter(route => !route.isApi), render, port); // eslint-disable-next-line promise/no-promise-in-callback
69
69
 
70
70
  const htmlAry = await Promise.all(renderPromiseAry);
71
71
  htmlAry.forEach(html => {
@@ -0,0 +1,5 @@
1
+ import { ModernRoute } from '@modern-js/server';
2
+ import { compile } from '../server/prerender';
3
+ import { RouteOptions, SsgRoute } from '../types';
4
+ export declare function makeRender(ssgRoutes: SsgRoute[], render: ReturnType<typeof compile>, port: number): Promise<string>[];
5
+ export declare function makeRoute(baseRoute: ModernRoute, route: string | RouteOptions, headers?: Record<string, any>): SsgRoute;
@@ -1,4 +1,4 @@
1
1
  import { ModernRoute } from '@modern-js/server';
2
2
  import { SsgRoute } from '../types';
3
- export declare function exist(route: SsgRoute, pageRoutes: ModernRoute[]): number;
3
+ export declare function exist(route: ModernRoute, pageRoutes: ModernRoute[]): number;
4
4
  export declare function replaceRoute(ssgRoutes: SsgRoute[], pageRoutes: ModernRoute[]): ModernRoute[];
@@ -1,15 +1,11 @@
1
1
  import { ModernRoute } from '@modern-js/server';
2
- import { SSGConfig, SsgRoute } from '../types';
3
- export declare function formatOutput(base: string, filename: string): string;
2
+ import { EntryPoint, MultiEntryOptions, SSG, SsgRoute } from '../types';
3
+ export declare function formatOutput(filename: string): string;
4
4
  export declare function formatPath(str: string): string;
5
5
  export declare function isDynamicUrl(url: string): boolean;
6
6
  export declare function getUrlPrefix(route: SsgRoute, baseUrl: string | string[]): string;
7
7
  export declare function getOutput(route: SsgRoute, base: string, agreed?: boolean): string;
8
8
  export declare const readJSONSpec: (dir: string) => ModernRoute[];
9
9
  export declare const writeJSONSpec: (dir: string, routes: ModernRoute[]) => void;
10
- export declare const getSSGRenderLevel: (key: boolean | string) => number;
11
- export declare const parsedSSGConfig: (ssg: SSGConfig) => {
12
- useSSG: boolean;
13
- userHook: (context: any) => void;
14
- };
15
- export declare const replaceWithAlias: (base: string, filePath: string, alias: string) => string;
10
+ export declare const replaceWithAlias: (base: string, filePath: string, alias: string) => string;
11
+ export declare const standardOptions: (ssgOptions: SSG, entrypoints: EntryPoint[]) => false | MultiEntryOptions;
@@ -12,27 +12,23 @@ export declare type EntryPoint = {
12
12
  export declare type AgreedRouteMap = {
13
13
  [propNames: string]: AgreedRoute[];
14
14
  };
15
- export declare type FreshPageConfig = {
16
- url?: string;
17
- output?: string;
18
- params?: Record<string, string | number>;
15
+ export declare type SsgRoute = ModernRoute & {
16
+ output: string;
19
17
  headers?: Record<string, string>;
20
18
  };
21
- export declare type UserInterfaceRoute = ModernRoute & {
22
- path: string;
23
- agreed?: boolean;
24
- };
25
- export declare type CreatePageParam = FreshPageConfig | FreshPageConfig[];
26
- export declare type CreatePageListener = (route: SsgRoute, agreed?: boolean) => void;
27
- export declare type SsgRoute = ModernRoute & {
19
+ export declare type RouteOptions = string | {
20
+ url: string;
28
21
  output?: string;
29
- headers?: Record<string, string>;
22
+ params?: Record<string, any>[];
23
+ headers?: Record<string, any>;
30
24
  };
31
- export declare type HookContext = {
32
- createPage: (config?: CreatePageParam) => any;
33
- route: UserInterfaceRoute;
25
+ export declare type SingleEntryOptions = boolean | {
26
+ preventDefault?: string[];
27
+ headers?: Record<string, any>;
28
+ routes: RouteOptions[];
34
29
  };
35
- export declare type SSGConfig = boolean | ((context: any) => void);
30
+ export declare type MultiEntryOptions = Record<string, SingleEntryOptions>;
31
+ export declare type SSG = boolean | SingleEntryOptions | MultiEntryOptions | ((entryName: string) => SingleEntryOptions);
36
32
  export declare type ExtendOutputConfig = {
37
- ssg: SSGConfig;
33
+ ssg: SSG;
38
34
  };
package/package.json CHANGED
@@ -11,7 +11,7 @@
11
11
  "modern",
12
12
  "modern.js"
13
13
  ],
14
- "version": "1.0.1",
14
+ "version": "1.1.2",
15
15
  "jsnext:source": "./src/index.ts",
16
16
  "types": "./dist/types/index.d.ts",
17
17
  "main": "./dist/js/node/index.js",
@@ -35,16 +35,14 @@
35
35
  },
36
36
  "dependencies": {
37
37
  "@babel/runtime": "^7",
38
- "@modern-js/babel-chain": "^1.0.1",
39
- "@modern-js/utils": "^1.0.1",
38
+ "@modern-js/utils": "^1.1.4",
40
39
  "node-mocks-http": "^1.10.1",
41
40
  "normalize-path": "^3.0.0",
42
41
  "portfinder": "^1.0.28",
43
- "react-router-dom": "^5.2.1",
44
- "webpack-chain": "^6.5.1"
42
+ "react-router-dom": "^5.2.1"
45
43
  },
46
44
  "devDependencies": {
47
- "@modern-js/server": "^1.0.1",
45
+ "@modern-js/server": "^1.1.4",
48
46
  "@types/jest": "^26",
49
47
  "@types/node": "^14",
50
48
  "@types/react": "^17",
@@ -52,12 +50,12 @@
52
50
  "@types/react-router": "^5.1.16",
53
51
  "@types/react-router-dom": "^5.1.8",
54
52
  "typescript": "^4",
55
- "@modern-js/core": "^1.0.1",
56
- "@modern-js/plugin-testing": "^1.0.2",
57
- "@modern-js/module-tools": "^1.0.2"
53
+ "@modern-js/core": "^1.1.4",
54
+ "@modern-js/plugin-testing": "^1.1.1",
55
+ "@modern-js/module-tools": "^1.1.1"
58
56
  },
59
57
  "peerDependencies": {
60
- "@modern-js/core": "^1.0.1"
58
+ "@modern-js/core": "^1.1.4"
61
59
  },
62
60
  "sideEffects": false,
63
61
  "modernConfig": {
@@ -74,5 +72,6 @@
74
72
  "build": "modern build",
75
73
  "dev": "modern build --watch",
76
74
  "test": "modern test --passWithNoTests"
77
- }
75
+ },
76
+ "readme": "\n<p align=\"center\">\n <a href=\"https://modernjs.dev\" target=\"blank\"><img src=\"https://lf3-static.bytednsdoc.com/obj/eden-cn/ylaelkeh7nuhfnuhf/modernjs-cover.png\" width=\"300\" alt=\"Modern.js Logo\" /></a>\n</p>\n<p align=\"center\">\n现代 Web 工程体系\n <br/>\n <a href=\"https://modernjs.dev\" target=\"blank\">\n modernjs.dev\n </a>\n</p>\n<p align=\"center\">\n The meta-framework suite designed from scratch for frontend-focused modern web development\n</p>\n\n# Introduction\n\n> The doc site ([modernjs.dev](https://modernjs.dev)) and articles are only available in Chinese for now, we are planning to add English versions soon.\n\n- [Modern.js: Hello, World!](https://zhuanlan.zhihu.com/p/426707646)\n\n## Getting Started\n\n- [Quick Start](https://modernjs.dev/docs/start)\n- [Guides](https://modernjs.dev/docs/guides)\n- [API References](https://modernjs.dev/docs/apis)\n\n## Contributing\n\n- [Contributing Guide](https://github.com/modern-js-dev/modern.js/blob/main/CONTRIBUTING.md)\n"
78
77
  }
package/src/index.ts CHANGED
@@ -1,71 +1,36 @@
1
1
  import path from 'path';
2
- import { INTERNAL_SRC_ALIAS, logger, PLUGIN_SCHEMAS } from '@modern-js/utils';
2
+ import { logger, PLUGIN_SCHEMAS } from '@modern-js/utils';
3
3
  import {
4
4
  createPlugin,
5
5
  useAppContext,
6
6
  useResolvedConfigContext,
7
7
  } from '@modern-js/core';
8
- import { BabelChain } from '@modern-js/babel-chain';
9
- import { LoaderManifest } from './manifest-op';
8
+ import { generatePath } from 'react-router-dom';
10
9
  import {
11
10
  AgreedRoute,
12
11
  AgreedRouteMap,
13
- CreatePageListener,
14
12
  EntryPoint,
15
13
  ExtendOutputConfig,
16
- HookContext,
14
+ SSG,
17
15
  SsgRoute,
18
16
  } from './types';
19
17
  import {
20
18
  formatOutput,
21
- getOutput,
22
- getSSGRenderLevel,
23
- getUrlPrefix,
24
- parsedSSGConfig,
19
+ isDynamicUrl,
25
20
  readJSONSpec,
26
- replaceWithAlias,
21
+ standardOptions,
27
22
  writeJSONSpec,
28
23
  } from './libs/util';
29
- import { invoker } from './libs/invoker';
30
24
  import { createServer } from './server';
31
25
  import { writeHtmlFile } from './libs/output';
32
26
  import { replaceRoute } from './libs/replace';
33
-
34
- const listStaticFiles = (
35
- pwd: string,
36
- entriesDir: string,
37
- useSSG: string | boolean,
38
- ) => {
39
- const absEntriesDir = path.join(pwd, entriesDir);
40
-
41
- const staticRenderLevel = getSSGRenderLevel(useSSG);
42
-
43
- const staticFiles = new LoaderManifest().get(
44
- absEntriesDir,
45
- staticRenderLevel,
46
- );
47
-
48
- // 将绝对路径转换成 alias,因为获取到的约定路由也是使用别名的
49
- const staticAlias = staticFiles.map(filepath =>
50
- replaceWithAlias(path.join(pwd, 'src'), filepath, INTERNAL_SRC_ALIAS),
51
- );
52
- return staticAlias;
53
- };
27
+ import { makeRoute } from './libs/make';
54
28
 
55
29
  export default createPlugin(
56
30
  (() => {
57
31
  const agreedRouteMap: AgreedRouteMap = {};
58
32
 
59
33
  return {
60
- config() {
61
- return {
62
- tools: {
63
- babel(config: any, { chain }: { chain: BabelChain }) {
64
- chain.plugin('./loader').use(require.resolve('./loader'));
65
- },
66
- },
67
- };
68
- },
69
34
  validateSchema() {
70
35
  return PLUGIN_SCHEMAS['@modern-js/plugin-ssg'];
71
36
  },
@@ -88,25 +53,19 @@ export default createPlugin(
88
53
  // eslint-disable-next-line react-hooks/rules-of-hooks
89
54
  const appContext = useAppContext();
90
55
 
91
- const { appDirectory } = appContext;
92
- const {
93
- output,
94
- server: { baseUrl },
95
- source: { entriesDir },
96
- } = resolvedConfig;
56
+ const { appDirectory, entrypoints } = appContext;
57
+ const { output } = resolvedConfig;
97
58
  const { ssg, path: outputPath } = output as typeof output &
98
59
  ExtendOutputConfig;
99
60
 
100
- const ssgOptions = Array.isArray(ssg) ? ssg.pop() : ssg;
61
+ const ssgOptions: SSG = Array.isArray(ssg) ? ssg.pop() : ssg;
101
62
  // no ssg configuration, skip ssg render.
102
63
  if (!ssgOptions) {
103
64
  return;
104
65
  }
105
66
 
106
- const { useSSG, userHook } = parsedSSGConfig(ssgOptions);
107
67
  const buildDir = path.join(appDirectory, outputPath as string);
108
68
  const routes = readJSONSpec(buildDir);
109
- const staticAlias = listStaticFiles(appDirectory, entriesDir!, useSSG);
110
69
 
111
70
  // filter all routes not web
112
71
  const pageRoutes = routes.filter(route => !route.isApi);
@@ -117,42 +76,83 @@ export default createPlugin(
117
76
  return;
118
77
  }
119
78
 
79
+ const intermediateOptions = standardOptions(ssgOptions, entrypoints);
80
+
81
+ if (!intermediateOptions) {
82
+ return;
83
+ }
84
+
120
85
  const ssgRoutes: SsgRoute[] = [];
86
+ // each route will try to match the configuration
87
+ pageRoutes.forEach(pageRoute => {
88
+ const { entryName, entryPath } = pageRoute;
89
+ const agreedRoutes = agreedRouteMap[entryName];
90
+ let entryOptions = intermediateOptions[entryName];
91
+
92
+ if (!agreedRoutes) {
93
+ // default behavior for non-agreed route
94
+ if (!entryOptions) {
95
+ return;
96
+ }
121
97
 
122
- // callback of context.createPage, to format output, collect page route
123
- const listener: CreatePageListener = (
124
- route: SsgRoute,
125
- agreed?: boolean,
126
- ) => {
127
- const urlPrefix = getUrlPrefix(route, baseUrl!);
128
- const ssgOutput = getOutput(route, urlPrefix, agreed);
129
- route.output = formatOutput(route.entryPath, ssgOutput);
130
- ssgRoutes.push(route);
131
- };
132
-
133
- // check if every allowed agreed route was collected
134
- const autoAddAgreed = (
135
- context: HookContext & {
136
- component: string;
137
- },
138
- ) => {
139
- // if not exist in allowed list, return false
140
- if (!staticAlias.includes(context.component)) {
141
- return false;
98
+ // only add entry route if entryOptions is true
99
+ if (entryOptions === true) {
100
+ ssgRoutes.push({ ...pageRoute, output: entryPath });
101
+ } else if (entryOptions.routes?.length > 0) {
102
+ // if entryOptions is object and has routes options
103
+ // add every route in options
104
+ const { routes: enrtyRoutes, headers } = entryOptions;
105
+ enrtyRoutes.forEach(route => {
106
+ ssgRoutes.push(makeRoute(pageRoute, route, headers));
107
+ });
108
+ }
109
+ } else {
110
+ // Unless entryOptions is set to false
111
+ // the default behavior is to add all file-based routes
112
+ if (entryOptions === false) {
113
+ return;
114
+ }
115
+
116
+ if (!entryOptions || entryOptions === true) {
117
+ entryOptions = { preventDefault: [], routes: [], headers: {} };
118
+ }
119
+
120
+ const {
121
+ preventDefault = [],
122
+ routes: userRoutes = [],
123
+ headers,
124
+ } = entryOptions;
125
+ // if the user sets the routes, then only add them
126
+ if (userRoutes.length > 0) {
127
+ userRoutes.forEach(route => {
128
+ if (typeof route === 'string') {
129
+ ssgRoutes.push(makeRoute(pageRoute, route, headers));
130
+ } else if (Array.isArray(route.params)) {
131
+ route.params.forEach(param => {
132
+ ssgRoutes.push(
133
+ makeRoute(
134
+ pageRoute,
135
+ { ...route, url: generatePath(route.url, param) },
136
+ headers,
137
+ ),
138
+ );
139
+ });
140
+ } else {
141
+ ssgRoutes.push(makeRoute(pageRoute, route, headers));
142
+ }
143
+ });
144
+ } else {
145
+ // otherwith add all except dynamic routes
146
+ agreedRoutes
147
+ .filter(route => !preventDefault.includes(route.path))
148
+ .forEach(route => {
149
+ if (!isDynamicUrl(route.path)) {
150
+ ssgRoutes.push(makeRoute(pageRoute, route.path, headers));
151
+ }
152
+ });
153
+ }
142
154
  }
143
- // if allowed, return collection state
144
- return !ssgRoutes.some(
145
- ssgRoute => ssgRoute.urlPath === context.route.path,
146
- );
147
- };
148
-
149
- await invoker(
150
- pageRoutes,
151
- agreedRouteMap,
152
- userHook,
153
- autoAddAgreed,
154
- listener,
155
- );
155
+ });
156
156
 
157
157
  if (ssgRoutes.length === 0) {
158
158
  return;
@@ -178,6 +178,7 @@ export default createPlugin(
178
178
  );
179
179
  }
180
180
  ssgRoute.isSSR = false;
181
+ ssgRoute.output = formatOutput(ssgRoute.output);
181
182
  });
182
183
 
183
184
  const htmlAry = await createServer(
@@ -0,0 +1,45 @@
1
+ import path from 'path';
2
+ import { ModernRoute } from '@modern-js/server';
3
+ import normalize from 'normalize-path';
4
+ import { compile } from '../server/prerender';
5
+ import { RouteOptions, SsgRoute } from '../types';
6
+
7
+ export function makeRender(
8
+ ssgRoutes: SsgRoute[],
9
+ render: ReturnType<typeof compile>,
10
+ port: number,
11
+ ): Promise<string>[] {
12
+ return ssgRoutes.map((ssgRoute: SsgRoute) =>
13
+ render({
14
+ url: ssgRoute.urlPath,
15
+ headers: { host: `localhost:${port}`, ...ssgRoute.headers },
16
+ connection: {},
17
+ }),
18
+ );
19
+ }
20
+
21
+ export function makeRoute(
22
+ baseRoute: ModernRoute,
23
+ route: string | RouteOptions,
24
+ headers: Record<string, any> = {},
25
+ ): SsgRoute {
26
+ const { urlPath, entryPath } = baseRoute;
27
+
28
+ if (typeof route === 'string') {
29
+ return {
30
+ ...baseRoute,
31
+ urlPath: normalize(`${urlPath}${route}`) || '/',
32
+ headers,
33
+ output: path.join(entryPath, `..${route}`),
34
+ };
35
+ } else {
36
+ return {
37
+ ...baseRoute,
38
+ urlPath: normalize(`${urlPath}${route.url}`) || '/',
39
+ headers: { ...headers, ...route.headers },
40
+ output: route.output
41
+ ? path.normalize(route.output)
42
+ : path.join(entryPath, `..${route.url}`),
43
+ };
44
+ }
45
+ }
@@ -9,7 +9,7 @@ export function writeHtmlFile(
9
9
  ) {
10
10
  htmlAry.forEach((html: any, index: number) => {
11
11
  const ssgRoute = ssgRoutes[index];
12
- const filepath = path.join(baseDir, ssgRoute.output!);
12
+ const filepath = path.join(baseDir, ssgRoute.output);
13
13
  if (!fs.existsSync(path.dirname(filepath))) {
14
14
  fs.ensureDirSync(path.dirname(filepath));
15
15
  }