@modern-js/plugin-ssg 1.0.0-rc.9 → 1.1.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/.eslintrc.js +6 -0
- package/CHANGELOG.md +249 -0
- package/README.md +19 -21
- package/dist/js/modern/index.js +96 -58
- package/dist/js/modern/libs/{render.js → make.js} +22 -0
- package/dist/js/modern/libs/replace.js +3 -2
- package/dist/js/modern/libs/util.js +38 -22
- package/dist/js/modern/server/index.js +1 -1
- package/dist/js/modern/server/process.js +3 -2
- package/dist/js/modern/types.js +1 -0
- package/dist/js/node/index.js +94 -57
- package/dist/js/node/libs/{render.js → make.js} +28 -0
- package/dist/js/node/libs/replace.js +3 -2
- package/dist/js/node/libs/util.js +38 -29
- package/dist/js/node/server/index.js +2 -2
- package/dist/js/node/server/process.js +3 -2
- package/dist/types/libs/make.d.ts +5 -0
- package/dist/types/libs/replace.d.ts +1 -1
- package/dist/types/libs/util.d.ts +4 -8
- package/dist/types/types.d.ts +13 -17
- package/package.json +21 -9
- package/src/index.ts +84 -83
- package/src/libs/make.ts +45 -0
- package/src/libs/replace.ts +7 -4
- package/src/libs/util.ts +40 -28
- package/src/server/index.ts +2 -2
- package/src/server/process.ts +4 -2
- package/src/types.ts +26 -20
- package/tests/.eslintrc.js +6 -0
- package/tests/lib.test.ts +48 -169
- package/tests/util.test.ts +71 -32
- package/dist/js/modern/libs/createPage.js +0 -46
- package/dist/js/modern/libs/invoker.js +0 -55
- package/dist/js/modern/loader/index.js +0 -105
- package/dist/js/modern/manifest-op.js +0 -101
- package/dist/js/node/libs/createPage.js +0 -57
- package/dist/js/node/libs/invoker.js +0 -66
- package/dist/js/node/loader/index.js +0 -115
- package/dist/js/node/manifest-op.js +0 -124
- package/dist/types/libs/createPage.d.ts +0 -2
- package/dist/types/libs/invoker.d.ts +0 -5
- package/dist/types/libs/render.d.ts +0 -3
- package/dist/types/loader/index.d.ts +0 -4
- package/dist/types/manifest-op.d.ts +0 -18
- package/src/libs/createPage.ts +0 -42
- package/src/libs/invoker.ts +0 -55
- package/src/libs/render.ts +0 -16
- package/src/loader/index.ts +0 -99
- package/src/manifest-op.ts +0 -111
- package/tests/operate.test.ts +0 -39
package/tests/lib.test.ts
CHANGED
|
@@ -1,178 +1,10 @@
|
|
|
1
1
|
import fs from 'fs';
|
|
2
2
|
import path from 'path';
|
|
3
|
-
// import { createInvoker } from '../libs/invoker';
|
|
4
3
|
import { ModernRoute } from '@modern-js/server';
|
|
5
4
|
import { exist, replaceRoute } from '@/libs/replace';
|
|
6
|
-
import {
|
|
7
|
-
AgreedRoute,
|
|
8
|
-
CreatePageListener,
|
|
9
|
-
HookContext,
|
|
10
|
-
SsgRoute,
|
|
11
|
-
} from '@/types';
|
|
12
|
-
import { createPageFactory } from '@/libs/createPage';
|
|
13
|
-
import { invoker } from '@/libs/invoker';
|
|
14
|
-
|
|
15
|
-
const noop = () => {
|
|
16
|
-
//
|
|
17
|
-
};
|
|
5
|
+
import { makeRoute } from '@/libs/make';
|
|
18
6
|
|
|
19
7
|
describe('test functional function', () => {
|
|
20
|
-
it('should listener get arguments correctly', () => {
|
|
21
|
-
const route = { path: '/foo', agreed: false };
|
|
22
|
-
const listener: CreatePageListener = (r: SsgRoute, agreed?: boolean) => {
|
|
23
|
-
expect(r.urlPath).toBe('/foo');
|
|
24
|
-
expect(agreed).toBeFalsy();
|
|
25
|
-
};
|
|
26
|
-
const createPage = createPageFactory(route as any, listener);
|
|
27
|
-
createPage();
|
|
28
|
-
});
|
|
29
|
-
|
|
30
|
-
it('should listener get url correctly', () => {
|
|
31
|
-
const route = { path: '/foo', agreed: false };
|
|
32
|
-
const listener: CreatePageListener = (r: SsgRoute, agreed?: boolean) => {
|
|
33
|
-
expect(r.urlPath).toBe('/bar');
|
|
34
|
-
expect(agreed).toBeFalsy();
|
|
35
|
-
};
|
|
36
|
-
const createPage = createPageFactory(route as any, listener);
|
|
37
|
-
createPage({ url: '/bar' });
|
|
38
|
-
});
|
|
39
|
-
|
|
40
|
-
it('should listener get output correctly', () => {
|
|
41
|
-
const route = { path: '/foo', agreed: false };
|
|
42
|
-
const listener: CreatePageListener = (r: SsgRoute, agreed?: boolean) => {
|
|
43
|
-
expect(r.output).toBe('./bar');
|
|
44
|
-
expect(agreed).toBeFalsy();
|
|
45
|
-
};
|
|
46
|
-
const createPage = createPageFactory(route as any, listener);
|
|
47
|
-
createPage({ output: './bar' });
|
|
48
|
-
});
|
|
49
|
-
|
|
50
|
-
it('should listener get dynamic route correctly', () => {
|
|
51
|
-
const route = { path: '/:foo', agreed: true };
|
|
52
|
-
const listener: CreatePageListener = (r: SsgRoute, agreed?: boolean) => {
|
|
53
|
-
expect(r.urlPath).toBe('/bar');
|
|
54
|
-
expect(agreed).toBeTruthy();
|
|
55
|
-
};
|
|
56
|
-
const createPage = createPageFactory(route as any, listener);
|
|
57
|
-
createPage({ params: { foo: 'bar' } });
|
|
58
|
-
});
|
|
59
|
-
|
|
60
|
-
it('should listener get multi route correctly', () => {
|
|
61
|
-
const route = { path: '/foo', agreed: false };
|
|
62
|
-
const urls = ['/a', '/b', '/c'];
|
|
63
|
-
const listener: CreatePageListener = (r: SsgRoute) => {
|
|
64
|
-
expect(urls.includes(r.urlPath)).toBe(true);
|
|
65
|
-
};
|
|
66
|
-
const createPage = createPageFactory(route as any, listener);
|
|
67
|
-
createPage(urls.map(url => ({ url })));
|
|
68
|
-
});
|
|
69
|
-
|
|
70
|
-
it('should hook get context correctly', () => {
|
|
71
|
-
const pageRoutes = [
|
|
72
|
-
{
|
|
73
|
-
urlPath: '/foo',
|
|
74
|
-
entryName: 'foo',
|
|
75
|
-
},
|
|
76
|
-
{
|
|
77
|
-
urlPath: '/bar',
|
|
78
|
-
entryName: 'bar',
|
|
79
|
-
},
|
|
80
|
-
];
|
|
81
|
-
let i = 0;
|
|
82
|
-
const hook = (context: HookContext) => {
|
|
83
|
-
expect(typeof context.createPage).toBe('function');
|
|
84
|
-
expect(context.route.path).toEqual(pageRoutes[i].urlPath);
|
|
85
|
-
i++;
|
|
86
|
-
};
|
|
87
|
-
|
|
88
|
-
invoker(pageRoutes as any, {}, hook, () => false, noop);
|
|
89
|
-
});
|
|
90
|
-
|
|
91
|
-
it('should hook get context correctly while use appoint', () => {
|
|
92
|
-
const pageRoutes = [
|
|
93
|
-
{
|
|
94
|
-
urlPath: '/foo',
|
|
95
|
-
entryName: 'foo',
|
|
96
|
-
},
|
|
97
|
-
];
|
|
98
|
-
const appointRouteMap: Record<string, AgreedRoute[]> = {
|
|
99
|
-
foo: [
|
|
100
|
-
{
|
|
101
|
-
path: '/a',
|
|
102
|
-
component: 'a',
|
|
103
|
-
_component: 'a',
|
|
104
|
-
exact: true,
|
|
105
|
-
},
|
|
106
|
-
{
|
|
107
|
-
path: '/b',
|
|
108
|
-
component: 'b',
|
|
109
|
-
_component: 'b',
|
|
110
|
-
exact: true,
|
|
111
|
-
},
|
|
112
|
-
],
|
|
113
|
-
};
|
|
114
|
-
|
|
115
|
-
let i = 0;
|
|
116
|
-
const hook = (context: HookContext) => {
|
|
117
|
-
expect(typeof context.createPage).toBe('function');
|
|
118
|
-
expect(context.route.path).toEqual(`/foo${appointRouteMap.foo[i].path}`);
|
|
119
|
-
i++;
|
|
120
|
-
};
|
|
121
|
-
|
|
122
|
-
invoker(
|
|
123
|
-
pageRoutes as any,
|
|
124
|
-
appointRouteMap,
|
|
125
|
-
hook,
|
|
126
|
-
context => {
|
|
127
|
-
expect(['a', 'b'].includes(context.component)).toBeTruthy();
|
|
128
|
-
return true;
|
|
129
|
-
},
|
|
130
|
-
noop,
|
|
131
|
-
);
|
|
132
|
-
});
|
|
133
|
-
|
|
134
|
-
it('only static route invoke checker', () => {
|
|
135
|
-
const pageRoutes = [
|
|
136
|
-
{
|
|
137
|
-
urlPath: '/foo',
|
|
138
|
-
entryName: 'foo',
|
|
139
|
-
},
|
|
140
|
-
{
|
|
141
|
-
urlPath: '/:bar',
|
|
142
|
-
entryName: 'bar',
|
|
143
|
-
},
|
|
144
|
-
];
|
|
145
|
-
const appointRouteMap: Record<string, AgreedRoute[]> = {
|
|
146
|
-
foo: [
|
|
147
|
-
{
|
|
148
|
-
path: '/a',
|
|
149
|
-
component: 'a',
|
|
150
|
-
_component: 'a',
|
|
151
|
-
exact: true,
|
|
152
|
-
},
|
|
153
|
-
],
|
|
154
|
-
bar: [
|
|
155
|
-
{
|
|
156
|
-
path: '/b',
|
|
157
|
-
component: 'b',
|
|
158
|
-
_component: 'b',
|
|
159
|
-
exact: true,
|
|
160
|
-
},
|
|
161
|
-
],
|
|
162
|
-
};
|
|
163
|
-
|
|
164
|
-
invoker(
|
|
165
|
-
pageRoutes as any,
|
|
166
|
-
appointRouteMap,
|
|
167
|
-
noop,
|
|
168
|
-
context => {
|
|
169
|
-
expect(context.component).toBe('a');
|
|
170
|
-
return true;
|
|
171
|
-
},
|
|
172
|
-
noop,
|
|
173
|
-
);
|
|
174
|
-
});
|
|
175
|
-
|
|
176
8
|
it('should check route exist correctly', () => {
|
|
177
9
|
const pageRoutes: ModernRoute[] = JSON.parse(
|
|
178
10
|
fs.readFileSync(path.join(__dirname, 'material/lib.route.json'), 'utf-8'),
|
|
@@ -222,4 +54,51 @@ describe('test functional function', () => {
|
|
|
222
54
|
|
|
223
55
|
expect(result).toEqual(final);
|
|
224
56
|
});
|
|
57
|
+
|
|
58
|
+
it('shoule generate route correctly', () => {
|
|
59
|
+
const baseRoute: ModernRoute = {
|
|
60
|
+
urlPath: '/foo',
|
|
61
|
+
isSPA: true,
|
|
62
|
+
isSSR: false,
|
|
63
|
+
entryName: 'foo',
|
|
64
|
+
isApi: false,
|
|
65
|
+
bundle: '',
|
|
66
|
+
entryPath: 'html/foo/index.html',
|
|
67
|
+
};
|
|
68
|
+
|
|
69
|
+
const route1 = makeRoute(baseRoute, '/baz');
|
|
70
|
+
expect(route1.urlPath).toBe('/foo/baz');
|
|
71
|
+
expect(route1.urlPath).toBe('/foo/baz');
|
|
72
|
+
|
|
73
|
+
const route2 = makeRoute(baseRoute, { url: '/baz' });
|
|
74
|
+
expect(route2.urlPath).toBe('/foo/baz');
|
|
75
|
+
expect(route2.output).toBe(path.normalize('html/foo/baz'));
|
|
76
|
+
|
|
77
|
+
const route3 = makeRoute(baseRoute, {
|
|
78
|
+
url: '/baz',
|
|
79
|
+
output: 'html/baz.html',
|
|
80
|
+
});
|
|
81
|
+
expect(route3.output).toBe(path.normalize('html/baz.html'));
|
|
82
|
+
|
|
83
|
+
const route4 = makeRoute(
|
|
84
|
+
baseRoute,
|
|
85
|
+
{
|
|
86
|
+
url: '/baz',
|
|
87
|
+
},
|
|
88
|
+
{ ua: 'mobile' },
|
|
89
|
+
);
|
|
90
|
+
expect(route4.headers).toEqual({ ua: 'mobile' });
|
|
91
|
+
|
|
92
|
+
const route5 = makeRoute(
|
|
93
|
+
baseRoute,
|
|
94
|
+
{
|
|
95
|
+
url: '/baz',
|
|
96
|
+
headers: {
|
|
97
|
+
ua: 'pc',
|
|
98
|
+
},
|
|
99
|
+
},
|
|
100
|
+
{ ua: 'mobile' },
|
|
101
|
+
);
|
|
102
|
+
expect(route5.headers).toEqual({ ua: 'pc' });
|
|
103
|
+
});
|
|
225
104
|
});
|
package/tests/util.test.ts
CHANGED
|
@@ -4,11 +4,9 @@ import {
|
|
|
4
4
|
isDynamicUrl,
|
|
5
5
|
getUrlPrefix,
|
|
6
6
|
getOutput,
|
|
7
|
-
getSSGRenderLevel,
|
|
8
|
-
parsedSSGConfig,
|
|
9
7
|
replaceWithAlias,
|
|
8
|
+
standardOptions,
|
|
10
9
|
} from '@/libs/util';
|
|
11
|
-
import { MODE } from '@/manifest-op';
|
|
12
10
|
|
|
13
11
|
describe('test ssg util function', () => {
|
|
14
12
|
it('should return format path correctly', () => {
|
|
@@ -64,42 +62,83 @@ describe('test ssg util function', () => {
|
|
|
64
62
|
});
|
|
65
63
|
|
|
66
64
|
it('should return format output correctly', () => {
|
|
67
|
-
const
|
|
68
|
-
|
|
69
|
-
expect(onlyBase).toBe(entryPath);
|
|
65
|
+
const entryPath1 = '/base/home/index.html';
|
|
66
|
+
expect(formatOutput(entryPath1)).toBe(entryPath1);
|
|
70
67
|
|
|
71
|
-
const
|
|
72
|
-
expect(
|
|
68
|
+
const entryPath2 = '/base/home';
|
|
69
|
+
expect(formatOutput(entryPath2)).toBe(entryPath1);
|
|
70
|
+
});
|
|
73
71
|
|
|
74
|
-
|
|
75
|
-
expect(
|
|
72
|
+
it('should replace alias correctly', () => {
|
|
73
|
+
expect(replaceWithAlias('/src', '/src/app.js', '@src')).toBe('@src/app.js');
|
|
74
|
+
});
|
|
76
75
|
|
|
77
|
-
|
|
78
|
-
|
|
76
|
+
it('should starndar user config correctly', () => {
|
|
77
|
+
const opt0 = standardOptions(false, []);
|
|
78
|
+
expect(opt0).toBeFalsy();
|
|
79
79
|
|
|
80
|
-
const
|
|
81
|
-
expect(
|
|
82
|
-
});
|
|
80
|
+
const opt1 = standardOptions(true, [{ entryName: 'main', entry: '' }]);
|
|
81
|
+
expect(opt1).toEqual({ main: true });
|
|
83
82
|
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
83
|
+
const opt2 = standardOptions(true, [
|
|
84
|
+
{ entryName: 'main', entry: '' },
|
|
85
|
+
{ entryName: 'home', entry: '' },
|
|
86
|
+
]);
|
|
87
|
+
expect(opt2).toEqual({ main: true, home: true });
|
|
88
|
+
|
|
89
|
+
const opt3 = standardOptions(true, [
|
|
90
|
+
{ entryName: 'main', entry: '' },
|
|
91
|
+
{ entryName: 'home', entry: '' },
|
|
92
|
+
]);
|
|
93
|
+
expect(opt3).toEqual({ main: true, home: true });
|
|
89
94
|
|
|
90
|
-
|
|
91
|
-
const
|
|
92
|
-
|
|
95
|
+
// single entry, object config
|
|
96
|
+
const ssg1 = {
|
|
97
|
+
routes: ['/foo', { url: '/baz' }],
|
|
93
98
|
};
|
|
94
|
-
|
|
95
|
-
expect(
|
|
96
|
-
expect(parsedSSGConfig(true as any).useSSG).toBe(true);
|
|
97
|
-
expect(parsedSSGConfig(true as any).userHook).toBeInstanceOf(Function);
|
|
98
|
-
expect(parsedSSGConfig(empty).useSSG).toBe(true);
|
|
99
|
-
expect(parsedSSGConfig(empty).userHook).toBe(empty);
|
|
99
|
+
const opt4 = standardOptions(ssg1, [{ entryName: 'main', entry: '' }]);
|
|
100
|
+
expect(opt4).toEqual({ main: ssg1 });
|
|
100
101
|
});
|
|
101
102
|
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
103
|
+
// error usage, just test
|
|
104
|
+
const ssg2 = {
|
|
105
|
+
routes: ['/foo', { url: '/baz' }],
|
|
106
|
+
};
|
|
107
|
+
const opt5 = standardOptions(ssg2, [
|
|
108
|
+
{ entryName: 'main', entry: '' },
|
|
109
|
+
{ entryName: 'home', entry: '' },
|
|
110
|
+
]);
|
|
111
|
+
expect(opt5).toEqual(ssg2);
|
|
112
|
+
|
|
113
|
+
const ssg3 = {
|
|
114
|
+
main: { routes: ['/foo', { url: '/baz' }] },
|
|
115
|
+
home: false,
|
|
116
|
+
};
|
|
117
|
+
const opt6 = standardOptions(ssg3, [
|
|
118
|
+
{ entryName: 'main', entry: '' },
|
|
119
|
+
{ entryName: 'home', entry: '' },
|
|
120
|
+
]);
|
|
121
|
+
expect(opt6).toEqual(ssg3);
|
|
122
|
+
|
|
123
|
+
const ssg4 = () => true;
|
|
124
|
+
const opt7 = standardOptions(ssg4, [
|
|
125
|
+
{ entryName: 'main', entry: '' },
|
|
126
|
+
{ entryName: 'home', entry: '' },
|
|
127
|
+
]);
|
|
128
|
+
expect(opt7).toEqual({ main: true, home: true });
|
|
129
|
+
|
|
130
|
+
const ssg5 = (entryName: string) => {
|
|
131
|
+
if (entryName === 'main') {
|
|
132
|
+
return true;
|
|
133
|
+
} else {
|
|
134
|
+
return {
|
|
135
|
+
routes: ['/foo'],
|
|
136
|
+
};
|
|
137
|
+
}
|
|
138
|
+
};
|
|
139
|
+
const opt8 = standardOptions(ssg5, [
|
|
140
|
+
{ entryName: 'main', entry: '' },
|
|
141
|
+
{ entryName: 'home', entry: '' },
|
|
142
|
+
]);
|
|
143
|
+
expect(opt8).toEqual({ main: true, home: { routes: ['/foo'] } });
|
|
105
144
|
});
|
|
@@ -1,46 +0,0 @@
|
|
|
1
|
-
const _excluded = ["path", "agreed"];
|
|
2
|
-
|
|
3
|
-
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; }
|
|
4
|
-
|
|
5
|
-
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; }
|
|
6
|
-
|
|
7
|
-
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
|
-
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
|
-
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
|
-
import { generatePath } from 'react-router-dom';
|
|
14
|
-
import { formatPath, isDynamicUrl } from "./util";
|
|
15
|
-
export const createPageFactory = (route, listener) => config => {
|
|
16
|
-
if (Array.isArray(config)) {
|
|
17
|
-
config.forEach(cfg => {
|
|
18
|
-
listener(createPage(route, cfg), route.agreed);
|
|
19
|
-
});
|
|
20
|
-
} else {
|
|
21
|
-
listener(createPage(route, config), route.agreed);
|
|
22
|
-
}
|
|
23
|
-
};
|
|
24
|
-
|
|
25
|
-
function createPage(route, config = {}) {
|
|
26
|
-
const {
|
|
27
|
-
path,
|
|
28
|
-
agreed
|
|
29
|
-
} = route,
|
|
30
|
-
filterRoute = _objectWithoutProperties(route, _excluded);
|
|
31
|
-
|
|
32
|
-
const urlPath = formatPath(config.url || path);
|
|
33
|
-
|
|
34
|
-
const ssgRoute = _objectSpread(_objectSpread({}, filterRoute), {}, {
|
|
35
|
-
urlPath
|
|
36
|
-
}); // using params completion dynamic routing
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
if (agreed && isDynamicUrl(urlPath) && config.params) {
|
|
40
|
-
ssgRoute.urlPath = generatePath(urlPath, config.params);
|
|
41
|
-
}
|
|
42
|
-
|
|
43
|
-
ssgRoute.output = config.output;
|
|
44
|
-
ssgRoute.headers = config.headers;
|
|
45
|
-
return ssgRoute;
|
|
46
|
-
}
|
|
@@ -1,55 +0,0 @@
|
|
|
1
|
-
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; }
|
|
2
|
-
|
|
3
|
-
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; }
|
|
4
|
-
|
|
5
|
-
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
|
-
import normalize from 'normalize-path';
|
|
8
|
-
import { isDynamicUrl } from "./util";
|
|
9
|
-
import { createPageFactory } from "./createPage";
|
|
10
|
-
|
|
11
|
-
function createContext(route, listener) {
|
|
12
|
-
return {
|
|
13
|
-
createPage: createPageFactory(route, listener),
|
|
14
|
-
route
|
|
15
|
-
};
|
|
16
|
-
}
|
|
17
|
-
|
|
18
|
-
export async function invoker(pageRoutes, agreedRouteMap, hook, autoAddAgreed, listener) {
|
|
19
|
-
for (const pageRoute of pageRoutes) {
|
|
20
|
-
const {
|
|
21
|
-
urlPath,
|
|
22
|
-
entryName
|
|
23
|
-
} = pageRoute;
|
|
24
|
-
const agreedRoutes = agreedRouteMap[entryName];
|
|
25
|
-
|
|
26
|
-
if (agreedRoutes) {
|
|
27
|
-
for (const agreedRoute of agreedRoutes) {
|
|
28
|
-
const fullpath = normalize(`${urlPath}${agreedRoute.path}`) || '/';
|
|
29
|
-
|
|
30
|
-
const route = _objectSpread(_objectSpread({}, pageRoute), {}, {
|
|
31
|
-
path: fullpath,
|
|
32
|
-
agreed: true
|
|
33
|
-
});
|
|
34
|
-
|
|
35
|
-
const context = createContext(route, listener); // The hook function can return false to prevent the automatic addition of agreed routes
|
|
36
|
-
|
|
37
|
-
const isStaticPage = await hook(context);
|
|
38
|
-
|
|
39
|
-
if (!isDynamicUrl(fullpath) && isStaticPage !== false) {
|
|
40
|
-
const autoAdd = autoAddAgreed(_objectSpread(_objectSpread({}, context), {}, {
|
|
41
|
-
component: agreedRoute._component
|
|
42
|
-
}));
|
|
43
|
-
autoAdd && context.createPage();
|
|
44
|
-
}
|
|
45
|
-
}
|
|
46
|
-
} else {
|
|
47
|
-
const route = _objectSpread(_objectSpread({}, pageRoute), {}, {
|
|
48
|
-
path: urlPath
|
|
49
|
-
});
|
|
50
|
-
|
|
51
|
-
const context = createContext(route, listener);
|
|
52
|
-
await hook(context);
|
|
53
|
-
}
|
|
54
|
-
}
|
|
55
|
-
}
|
|
@@ -1,105 +0,0 @@
|
|
|
1
|
-
import { isDev } from '@modern-js/utils';
|
|
2
|
-
import { LoaderManifest, MODE } from "../manifest-op";
|
|
3
|
-
const FUNCTION_CREATE_CONTAINER_NAME = 'createContainer';
|
|
4
|
-
const FUNCTION_USE_LOADER_NAME = 'useLoader';
|
|
5
|
-
const FUNCTION_USE_STATIC_LOADER_NAME = 'useStaticLoader';
|
|
6
|
-
const CONTAINER_LOADER_NAME = 'loader';
|
|
7
|
-
const CONTAINER_STATIC_LOADER_NAME = 'staticLoader';
|
|
8
|
-
|
|
9
|
-
const noop = function noop() {
|
|
10
|
-
return {
|
|
11
|
-
name: 'babel-plugin-ssg-static-loader'
|
|
12
|
-
};
|
|
13
|
-
}; // develoment not need to static analysis
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
const loader = isDev() ? noop : function () {
|
|
17
|
-
const loaderManifest = new LoaderManifest();
|
|
18
|
-
let useSSG = 0;
|
|
19
|
-
let createContainer = null;
|
|
20
|
-
let useStaticLoader = null;
|
|
21
|
-
let useLoader = null;
|
|
22
|
-
return {
|
|
23
|
-
name: 'babel-plugin-ssg-static-loader',
|
|
24
|
-
|
|
25
|
-
// reset settings whenever a new file passes through loader
|
|
26
|
-
pre() {
|
|
27
|
-
useSSG = 0;
|
|
28
|
-
createContainer = null;
|
|
29
|
-
useStaticLoader = null;
|
|
30
|
-
useLoader = null;
|
|
31
|
-
},
|
|
32
|
-
|
|
33
|
-
visitor: {
|
|
34
|
-
ImportSpecifier(path) {
|
|
35
|
-
const importName = path.get('imported.name').node;
|
|
36
|
-
const localName = path.get('local.name').node;
|
|
37
|
-
|
|
38
|
-
if (importName === FUNCTION_CREATE_CONTAINER_NAME) {
|
|
39
|
-
createContainer = localName;
|
|
40
|
-
}
|
|
41
|
-
|
|
42
|
-
if (importName === FUNCTION_USE_STATIC_LOADER_NAME) {
|
|
43
|
-
useStaticLoader = localName;
|
|
44
|
-
}
|
|
45
|
-
|
|
46
|
-
if (importName === FUNCTION_USE_LOADER_NAME) {
|
|
47
|
-
useLoader = localName;
|
|
48
|
-
}
|
|
49
|
-
},
|
|
50
|
-
|
|
51
|
-
Identifier(path) {
|
|
52
|
-
var _closestPath$node, _closestPath$node$cal;
|
|
53
|
-
|
|
54
|
-
// If the current file uses useLoader, the page can use SSG in MIXIN mode
|
|
55
|
-
// Todo: Mixin Mode is not support
|
|
56
|
-
const nodeName = path.node.name;
|
|
57
|
-
|
|
58
|
-
if (nodeName === useLoader && path.key === 'callee') {
|
|
59
|
-
useSSG = Math.max(useSSG, MODE.MIXIN);
|
|
60
|
-
return;
|
|
61
|
-
} // If the current file uses useStaticLoader, the page can use SSG in STRICT mode
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
if (nodeName === useStaticLoader && path.key === 'callee') {
|
|
65
|
-
useSSG = Math.max(useSSG, MODE.STRICT);
|
|
66
|
-
return;
|
|
67
|
-
} // after testing the Hook API, skip detection if the current nodeName is not 'container.(loader | staticLoader)'
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
if (nodeName !== CONTAINER_LOADER_NAME && nodeName !== CONTAINER_STATIC_LOADER_NAME) {
|
|
71
|
-
return;
|
|
72
|
-
} // if the current nodeName is 'container.(loader | staticLoader)', check whether the calling node is 'createContainer'
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
const closestPath = path.find(p => p.isCallExpression());
|
|
76
|
-
|
|
77
|
-
if ((closestPath === null || closestPath === void 0 ? void 0 : (_closestPath$node = closestPath.node) === null || _closestPath$node === void 0 ? void 0 : (_closestPath$node$cal = _closestPath$node.callee) === null || _closestPath$node$cal === void 0 ? void 0 : _closestPath$node$cal.name) === createContainer) {
|
|
78
|
-
if (nodeName === CONTAINER_LOADER_NAME) {
|
|
79
|
-
useSSG = Math.max(useSSG, MODE.MIXIN);
|
|
80
|
-
return;
|
|
81
|
-
}
|
|
82
|
-
|
|
83
|
-
if (nodeName === CONTAINER_STATIC_LOADER_NAME) {
|
|
84
|
-
useSSG = Math.max(useSSG, MODE.STRICT);
|
|
85
|
-
}
|
|
86
|
-
}
|
|
87
|
-
}
|
|
88
|
-
|
|
89
|
-
},
|
|
90
|
-
|
|
91
|
-
post(file) {
|
|
92
|
-
const {
|
|
93
|
-
filename
|
|
94
|
-
} = file.opts; // if the current usage mode is not determined, that is, no runtime API is used, the default is LOOSE
|
|
95
|
-
|
|
96
|
-
if (!useSSG) {
|
|
97
|
-
useSSG = MODE.LOOSE;
|
|
98
|
-
}
|
|
99
|
-
|
|
100
|
-
loaderManifest.add(filename, useSSG);
|
|
101
|
-
}
|
|
102
|
-
|
|
103
|
-
};
|
|
104
|
-
};
|
|
105
|
-
export default loader;
|
|
@@ -1,101 +0,0 @@
|
|
|
1
|
-
import path from 'path';
|
|
2
|
-
import { fs } from '@modern-js/utils';
|
|
3
|
-
const CACHE_DIRECTORY = './node_modules/.cache';
|
|
4
|
-
const cacheDir = path.join(process.cwd(), CACHE_DIRECTORY);
|
|
5
|
-
const manifest = path.join(cacheDir, 'loaderManifest.json');
|
|
6
|
-
fs.mkdirp(cacheDir);
|
|
7
|
-
export const MODE = {
|
|
8
|
-
STRICT: 1,
|
|
9
|
-
LOOSE: 2,
|
|
10
|
-
MIXIN: 3
|
|
11
|
-
};
|
|
12
|
-
export function toKey(level) {
|
|
13
|
-
return `file_${level}`;
|
|
14
|
-
}
|
|
15
|
-
export class LoaderManifest {
|
|
16
|
-
constructor() {
|
|
17
|
-
this.content = void 0;
|
|
18
|
-
this.content = {};
|
|
19
|
-
this.load();
|
|
20
|
-
}
|
|
21
|
-
|
|
22
|
-
get(root, targetLevel) {
|
|
23
|
-
return Object.values(MODE).reduce((total, level) => {
|
|
24
|
-
if (level > targetLevel) {
|
|
25
|
-
return total;
|
|
26
|
-
}
|
|
27
|
-
|
|
28
|
-
const key = toKey(level);
|
|
29
|
-
const allow = this.content[key].filter(file => file.includes(root));
|
|
30
|
-
return total.concat(allow);
|
|
31
|
-
}, []);
|
|
32
|
-
}
|
|
33
|
-
|
|
34
|
-
add(filename, level) {
|
|
35
|
-
const key = toKey(level);
|
|
36
|
-
this.load();
|
|
37
|
-
|
|
38
|
-
if (this.includes(filename, key)) {
|
|
39
|
-
return;
|
|
40
|
-
}
|
|
41
|
-
|
|
42
|
-
this.cleanExist(filename);
|
|
43
|
-
this.content[key].push(filename);
|
|
44
|
-
this.dump();
|
|
45
|
-
}
|
|
46
|
-
|
|
47
|
-
initContent() {
|
|
48
|
-
return Object.values(MODE).reduce((total, level) => {
|
|
49
|
-
const key = toKey(level);
|
|
50
|
-
total[key] = [];
|
|
51
|
-
return total;
|
|
52
|
-
}, {});
|
|
53
|
-
}
|
|
54
|
-
|
|
55
|
-
dump() {
|
|
56
|
-
fs.writeFileSync(manifest, JSON.stringify(this.content, null, 4));
|
|
57
|
-
}
|
|
58
|
-
|
|
59
|
-
load() {
|
|
60
|
-
const exist = fs.existsSync(manifest);
|
|
61
|
-
|
|
62
|
-
if (exist) {
|
|
63
|
-
try {
|
|
64
|
-
const contentStr = fs.readFileSync(manifest, 'utf-8');
|
|
65
|
-
this.content = JSON.parse(contentStr);
|
|
66
|
-
} catch (e) {
|
|
67
|
-
throw new Error(`解析 loader mainfest 失败:${manifest}`);
|
|
68
|
-
}
|
|
69
|
-
} else {
|
|
70
|
-
this.content = this.initContent();
|
|
71
|
-
}
|
|
72
|
-
}
|
|
73
|
-
|
|
74
|
-
includes(filename, key) {
|
|
75
|
-
return this.content[key].includes(filename);
|
|
76
|
-
}
|
|
77
|
-
|
|
78
|
-
index(filename, key) {
|
|
79
|
-
return this.content[key].indexOf(filename);
|
|
80
|
-
}
|
|
81
|
-
|
|
82
|
-
del(index, key) {
|
|
83
|
-
this.content[key].splice(index, 1);
|
|
84
|
-
}
|
|
85
|
-
|
|
86
|
-
cleanExist(filename) {
|
|
87
|
-
Object.values(MODE).some(level => {
|
|
88
|
-
const key = toKey(level);
|
|
89
|
-
|
|
90
|
-
if (this.includes(filename, key)) {
|
|
91
|
-
const index = this.index(filename, key);
|
|
92
|
-
this.del(index, key);
|
|
93
|
-
return true;
|
|
94
|
-
}
|
|
95
|
-
|
|
96
|
-
return false;
|
|
97
|
-
});
|
|
98
|
-
}
|
|
99
|
-
|
|
100
|
-
}
|
|
101
|
-
export { manifest };
|