@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.
- package/CHANGELOG.md +38 -6
- package/dist/js/modern/index.js +96 -58
- package/dist/js/modern/libs/make.js +37 -0
- package/dist/js/modern/libs/replace.js +5 -4
- package/dist/js/modern/libs/util.js +38 -22
- package/dist/js/modern/server/index.js +2 -2
- package/dist/js/modern/server/prerender.js +2 -2
- package/dist/js/modern/server/process.js +1 -1
- package/dist/js/modern/types.js +0 -1
- package/dist/js/node/index.js +92 -55
- package/dist/js/node/libs/make.js +50 -0
- package/dist/js/node/libs/replace.js +5 -4
- package/dist/js/node/libs/util.js +38 -29
- package/dist/js/node/server/index.js +2 -2
- package/dist/js/node/server/prerender.js +2 -2
- package/dist/js/node/server/process.js +2 -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 +10 -11
- package/src/index.ts +84 -83
- package/src/libs/make.ts +45 -0
- package/src/libs/output.ts +1 -1
- package/src/libs/replace.ts +7 -4
- package/src/libs/util.ts +39 -27
- package/src/server/index.ts +1 -1
- package/src/server/process.ts +3 -2
- package/src/types.ts +26 -20
- 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 -56
- package/dist/js/modern/libs/render.js +0 -15
- 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 -67
- package/dist/js/node/libs/render.js +0 -22
- 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 -56
- 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/src/libs/invoker.ts
DELETED
|
@@ -1,56 +0,0 @@
|
|
|
1
|
-
import normalize from 'normalize-path';
|
|
2
|
-
import { ModernRoute } from '@modern-js/server';
|
|
3
|
-
import {
|
|
4
|
-
CreatePageListener,
|
|
5
|
-
HookContext,
|
|
6
|
-
UserInterfaceRoute,
|
|
7
|
-
AgreedRouteMap,
|
|
8
|
-
} from '../types';
|
|
9
|
-
import { isDynamicUrl } from './util';
|
|
10
|
-
import { createPageFactory } from './createPage';
|
|
11
|
-
|
|
12
|
-
function createContext(
|
|
13
|
-
route: UserInterfaceRoute,
|
|
14
|
-
listener: CreatePageListener,
|
|
15
|
-
) {
|
|
16
|
-
return {
|
|
17
|
-
createPage: createPageFactory(route, listener),
|
|
18
|
-
route,
|
|
19
|
-
};
|
|
20
|
-
}
|
|
21
|
-
|
|
22
|
-
// eslint-disable-next-line max-params
|
|
23
|
-
export async function invoker(
|
|
24
|
-
pageRoutes: ModernRoute[],
|
|
25
|
-
agreedRouteMap: AgreedRouteMap,
|
|
26
|
-
hook: (context: HookContext) => any,
|
|
27
|
-
autoAddAgreed: (context: HookContext & { component: string }) => boolean,
|
|
28
|
-
listener: CreatePageListener,
|
|
29
|
-
) {
|
|
30
|
-
for (const pageRoute of pageRoutes) {
|
|
31
|
-
const { urlPath, entryName } = pageRoute;
|
|
32
|
-
|
|
33
|
-
const agreedRoutes = agreedRouteMap[entryName];
|
|
34
|
-
if (agreedRoutes) {
|
|
35
|
-
for (const agreedRoute of agreedRoutes) {
|
|
36
|
-
const fullpath = normalize(`${urlPath}${agreedRoute.path}`) || '/';
|
|
37
|
-
const route = { ...pageRoute, path: fullpath, agreed: true };
|
|
38
|
-
const context = createContext(route, listener);
|
|
39
|
-
// The hook function can return false to prevent the automatic addition of agreed routes
|
|
40
|
-
const isStaticPage = await hook(context);
|
|
41
|
-
|
|
42
|
-
if (!isDynamicUrl(fullpath) && isStaticPage !== false) {
|
|
43
|
-
const autoAdd = autoAddAgreed({
|
|
44
|
-
...context,
|
|
45
|
-
component: agreedRoute._component,
|
|
46
|
-
});
|
|
47
|
-
autoAdd && context.createPage();
|
|
48
|
-
}
|
|
49
|
-
}
|
|
50
|
-
} else {
|
|
51
|
-
const route = { ...pageRoute, path: urlPath };
|
|
52
|
-
const context = createContext(route, listener);
|
|
53
|
-
await hook(context);
|
|
54
|
-
}
|
|
55
|
-
}
|
|
56
|
-
}
|
package/src/libs/render.ts
DELETED
|
@@ -1,16 +0,0 @@
|
|
|
1
|
-
import { compile } from '../server/prerender';
|
|
2
|
-
import { SsgRoute } from '../types';
|
|
3
|
-
|
|
4
|
-
export function makeRender(
|
|
5
|
-
ssgRoutes: SsgRoute[],
|
|
6
|
-
render: ReturnType<typeof compile>,
|
|
7
|
-
port: number,
|
|
8
|
-
): Promise<string>[] {
|
|
9
|
-
return ssgRoutes.map((ssgRoute: SsgRoute) =>
|
|
10
|
-
render({
|
|
11
|
-
url: ssgRoute.urlPath,
|
|
12
|
-
headers: { host: `localhost:${port}`, ...ssgRoute.headers },
|
|
13
|
-
connection: {},
|
|
14
|
-
}),
|
|
15
|
-
);
|
|
16
|
-
}
|
package/src/loader/index.ts
DELETED
|
@@ -1,99 +0,0 @@
|
|
|
1
|
-
import { isDev } from '@modern-js/utils';
|
|
2
|
-
import { LoaderManifest, MODE } from '../manifest-op';
|
|
3
|
-
|
|
4
|
-
const FUNCTION_CREATE_CONTAINER_NAME = 'createContainer';
|
|
5
|
-
const FUNCTION_USE_LOADER_NAME = 'useLoader';
|
|
6
|
-
const FUNCTION_USE_STATIC_LOADER_NAME = 'useStaticLoader';
|
|
7
|
-
const CONTAINER_LOADER_NAME = 'loader';
|
|
8
|
-
const CONTAINER_STATIC_LOADER_NAME = 'staticLoader';
|
|
9
|
-
|
|
10
|
-
const noop = function () {
|
|
11
|
-
return { name: 'babel-plugin-ssg-static-loader' };
|
|
12
|
-
};
|
|
13
|
-
|
|
14
|
-
// develoment not need to static analysis
|
|
15
|
-
const loader = isDev()
|
|
16
|
-
? noop
|
|
17
|
-
: function () {
|
|
18
|
-
const loaderManifest = new LoaderManifest();
|
|
19
|
-
let useSSG = 0;
|
|
20
|
-
let createContainer: string | null = null;
|
|
21
|
-
let useStaticLoader: string | null = null;
|
|
22
|
-
let useLoader: string | null = null;
|
|
23
|
-
|
|
24
|
-
return {
|
|
25
|
-
name: 'babel-plugin-ssg-static-loader',
|
|
26
|
-
// reset settings whenever a new file passes through loader
|
|
27
|
-
pre() {
|
|
28
|
-
useSSG = 0;
|
|
29
|
-
createContainer = null;
|
|
30
|
-
useStaticLoader = null;
|
|
31
|
-
useLoader = null;
|
|
32
|
-
},
|
|
33
|
-
visitor: {
|
|
34
|
-
ImportSpecifier(path: any) {
|
|
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
|
-
Identifier(path: any) {
|
|
51
|
-
// If the current file uses useLoader, the page can use SSG in MIXIN mode
|
|
52
|
-
// Todo: Mixin Mode is not support
|
|
53
|
-
const nodeName = path.node.name;
|
|
54
|
-
if (nodeName === useLoader && path.key === 'callee') {
|
|
55
|
-
useSSG = Math.max(useSSG, MODE.MIXIN);
|
|
56
|
-
return;
|
|
57
|
-
}
|
|
58
|
-
|
|
59
|
-
// If the current file uses useStaticLoader, the page can use SSG in STRICT mode
|
|
60
|
-
if (nodeName === useStaticLoader && path.key === 'callee') {
|
|
61
|
-
useSSG = Math.max(useSSG, MODE.STRICT);
|
|
62
|
-
return;
|
|
63
|
-
}
|
|
64
|
-
|
|
65
|
-
// after testing the Hook API, skip detection if the current nodeName is not 'container.(loader | staticLoader)'
|
|
66
|
-
if (
|
|
67
|
-
nodeName !== CONTAINER_LOADER_NAME &&
|
|
68
|
-
nodeName !== CONTAINER_STATIC_LOADER_NAME
|
|
69
|
-
) {
|
|
70
|
-
return;
|
|
71
|
-
}
|
|
72
|
-
|
|
73
|
-
// if the current nodeName is 'container.(loader | staticLoader)', check whether the calling node is 'createContainer'
|
|
74
|
-
const closestPath = path.find((p: any) => p.isCallExpression());
|
|
75
|
-
if (closestPath?.node?.callee?.name === createContainer) {
|
|
76
|
-
if (nodeName === CONTAINER_LOADER_NAME) {
|
|
77
|
-
useSSG = Math.max(useSSG, MODE.MIXIN);
|
|
78
|
-
return;
|
|
79
|
-
}
|
|
80
|
-
|
|
81
|
-
if (nodeName === CONTAINER_STATIC_LOADER_NAME) {
|
|
82
|
-
useSSG = Math.max(useSSG, MODE.STRICT);
|
|
83
|
-
}
|
|
84
|
-
}
|
|
85
|
-
},
|
|
86
|
-
},
|
|
87
|
-
post(file: any) {
|
|
88
|
-
const { filename } = file.opts;
|
|
89
|
-
// if the current usage mode is not determined, that is, no runtime API is used, the default is LOOSE
|
|
90
|
-
if (!useSSG) {
|
|
91
|
-
useSSG = MODE.LOOSE;
|
|
92
|
-
}
|
|
93
|
-
|
|
94
|
-
loaderManifest.add(filename, useSSG);
|
|
95
|
-
},
|
|
96
|
-
};
|
|
97
|
-
};
|
|
98
|
-
|
|
99
|
-
export default loader;
|
package/src/manifest-op.ts
DELETED
|
@@ -1,111 +0,0 @@
|
|
|
1
|
-
import path from 'path';
|
|
2
|
-
import { fs } from '@modern-js/utils';
|
|
3
|
-
|
|
4
|
-
type ManifestContent = Record<string, string[]>;
|
|
5
|
-
|
|
6
|
-
const CACHE_DIRECTORY = './node_modules/.cache';
|
|
7
|
-
|
|
8
|
-
const cacheDir = path.join(process.cwd(), CACHE_DIRECTORY);
|
|
9
|
-
const manifest = path.join(cacheDir, 'loaderManifest.json');
|
|
10
|
-
fs.mkdirp(cacheDir);
|
|
11
|
-
|
|
12
|
-
export const MODE: Record<string, number> = {
|
|
13
|
-
STRICT: 1,
|
|
14
|
-
LOOSE: 2,
|
|
15
|
-
MIXIN: 3,
|
|
16
|
-
};
|
|
17
|
-
|
|
18
|
-
export function toKey(level: number): string {
|
|
19
|
-
return `file_${level}`;
|
|
20
|
-
}
|
|
21
|
-
export class LoaderManifest {
|
|
22
|
-
content: ManifestContent;
|
|
23
|
-
|
|
24
|
-
constructor() {
|
|
25
|
-
this.content = {};
|
|
26
|
-
this.load();
|
|
27
|
-
}
|
|
28
|
-
|
|
29
|
-
public get(root: string, targetLevel: number): string[] {
|
|
30
|
-
return Object.values(MODE).reduce((total: string[], level: number) => {
|
|
31
|
-
if (level > targetLevel) {
|
|
32
|
-
return total;
|
|
33
|
-
}
|
|
34
|
-
|
|
35
|
-
const key = toKey(level);
|
|
36
|
-
const allow = this.content[key].filter((file: string) =>
|
|
37
|
-
file.includes(root),
|
|
38
|
-
);
|
|
39
|
-
return total.concat(allow);
|
|
40
|
-
}, []);
|
|
41
|
-
}
|
|
42
|
-
|
|
43
|
-
public add(filename: string, level: number) {
|
|
44
|
-
const key = toKey(level);
|
|
45
|
-
this.load();
|
|
46
|
-
if (this.includes(filename, key)) {
|
|
47
|
-
return;
|
|
48
|
-
}
|
|
49
|
-
|
|
50
|
-
this.cleanExist(filename);
|
|
51
|
-
this.content[key].push(filename);
|
|
52
|
-
this.dump();
|
|
53
|
-
}
|
|
54
|
-
|
|
55
|
-
private initContent() {
|
|
56
|
-
return Object.values(MODE).reduce(
|
|
57
|
-
(total: ManifestContent, level: number) => {
|
|
58
|
-
const key = toKey(level);
|
|
59
|
-
total[key] = [];
|
|
60
|
-
return total;
|
|
61
|
-
},
|
|
62
|
-
{},
|
|
63
|
-
);
|
|
64
|
-
}
|
|
65
|
-
|
|
66
|
-
private dump() {
|
|
67
|
-
fs.writeFileSync(manifest, JSON.stringify(this.content, null, 4));
|
|
68
|
-
}
|
|
69
|
-
|
|
70
|
-
private load() {
|
|
71
|
-
const exist = fs.existsSync(manifest);
|
|
72
|
-
if (exist) {
|
|
73
|
-
try {
|
|
74
|
-
const contentStr = fs.readFileSync(manifest, 'utf-8');
|
|
75
|
-
this.content = JSON.parse(contentStr);
|
|
76
|
-
} catch (e) {
|
|
77
|
-
throw new Error(`解析 loader mainfest 失败:${manifest}`);
|
|
78
|
-
}
|
|
79
|
-
} else {
|
|
80
|
-
this.content = this.initContent();
|
|
81
|
-
}
|
|
82
|
-
}
|
|
83
|
-
|
|
84
|
-
private includes(filename: string, key: string) {
|
|
85
|
-
return this.content[key].includes(filename);
|
|
86
|
-
}
|
|
87
|
-
|
|
88
|
-
private index(filename: string, key: string) {
|
|
89
|
-
return this.content[key].indexOf(filename);
|
|
90
|
-
}
|
|
91
|
-
|
|
92
|
-
private del(index: number, key: string) {
|
|
93
|
-
this.content[key].splice(index, 1);
|
|
94
|
-
}
|
|
95
|
-
|
|
96
|
-
private cleanExist(filename: string) {
|
|
97
|
-
Object.values(MODE).some((level: number) => {
|
|
98
|
-
const key = toKey(level);
|
|
99
|
-
|
|
100
|
-
if (this.includes(filename, key)) {
|
|
101
|
-
const index = this.index(filename, key);
|
|
102
|
-
this.del(index, key);
|
|
103
|
-
return true;
|
|
104
|
-
}
|
|
105
|
-
|
|
106
|
-
return false;
|
|
107
|
-
});
|
|
108
|
-
}
|
|
109
|
-
}
|
|
110
|
-
|
|
111
|
-
export { manifest };
|
package/tests/operate.test.ts
DELETED
|
@@ -1,39 +0,0 @@
|
|
|
1
|
-
import { fs } from '@modern-js/utils';
|
|
2
|
-
import { LoaderManifest, manifest } from '@/manifest-op';
|
|
3
|
-
|
|
4
|
-
describe('test ssg manifest operate', () => {
|
|
5
|
-
beforeAll(() => {
|
|
6
|
-
if (fs.existsSync(manifest)) {
|
|
7
|
-
fs.unlinkSync(manifest);
|
|
8
|
-
}
|
|
9
|
-
});
|
|
10
|
-
|
|
11
|
-
test('should get correctly initial data', () => {
|
|
12
|
-
const loaderManifest = new LoaderManifest();
|
|
13
|
-
expect(loaderManifest.content).toEqual({
|
|
14
|
-
file_1: [],
|
|
15
|
-
file_2: [],
|
|
16
|
-
file_3: [],
|
|
17
|
-
});
|
|
18
|
-
});
|
|
19
|
-
|
|
20
|
-
test('should add file correctly', () => {
|
|
21
|
-
const loaderManifest = new LoaderManifest();
|
|
22
|
-
loaderManifest.add('/foo.js', 1);
|
|
23
|
-
loaderManifest.add('/bar.js', 2);
|
|
24
|
-
loaderManifest.add('/dir/baz.js', 2);
|
|
25
|
-
loaderManifest.add('/dir/foo.js', 3);
|
|
26
|
-
expect(loaderManifest.content).toEqual({
|
|
27
|
-
file_1: ['/foo.js'],
|
|
28
|
-
file_2: ['/bar.js', '/dir/baz.js'],
|
|
29
|
-
file_3: ['/dir/foo.js'],
|
|
30
|
-
});
|
|
31
|
-
});
|
|
32
|
-
|
|
33
|
-
test('should get file correctly', () => {
|
|
34
|
-
const loaderManifest = new LoaderManifest();
|
|
35
|
-
expect(loaderManifest.get('/', 1)).toEqual(['/foo.js']);
|
|
36
|
-
expect(loaderManifest.get('/dir', 2)).toEqual(['/dir/baz.js']);
|
|
37
|
-
expect(loaderManifest.get('/unknow', 3)).toEqual([]);
|
|
38
|
-
});
|
|
39
|
-
});
|