@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
@@ -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
- }
@@ -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
- }
@@ -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;
@@ -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 };
@@ -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
- });