-
Notifications
You must be signed in to change notification settings - Fork 34
/
htmlEntry.ts
106 lines (97 loc) · 3.37 KB
/
htmlEntry.ts
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
import fs from 'fs/promises';
// @ts-expect-error
import dedent from 'dedent';
import {Options, TemplateConfig, PlaceholderConfig} from './interface.js';
const DEFAULT_BACKGROUND_COLOR = '#f5f5f5';
const placeholderStyle = (config?: PlaceholderConfig | number): PlaceholderConfig => {
if (!config) {
return {
size: 0,
backgroundColor: DEFAULT_BACKGROUND_COLOR,
};
}
if (typeof config === 'number') {
return {
size: config,
backgroundColor: DEFAULT_BACKGROUND_COLOR,
};
}
return config;
};
const defaultTemplate = (appName: string, config?: TemplateConfig) => {
const header = placeholderStyle(config?.header);
const sidebarLeft = placeholderStyle(config?.sidebarLeft);
const footer = placeholderStyle(config?.footer);
return dedent`
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>${appName} - Qiankun</title>
<style>
body {
margin: 0;
}
#header {
position: fixed;
top: 0;
left: 0;
right: 0;
height: ${header.size}px;
background-color: ${header.backgroundColor};
}
#content {
padding-top: ${header.size}px;
display: flex;
}
#sidebar-left {
width: ${sidebarLeft.size}px;
background-color: ${sidebarLeft.backgroundColor};
min-height: calc(100vh - ${header.size}px);
}
#apps {
flex: 1;
overflow: hidden;
}
#footer {
height: ${footer.size}px;
background-color: ${footer.backgroundColor};
}
</style>
</head>
<body>
<header id="header"></header>
<div id="content">
<aside id="sidebar-left"></aside>
<main id="apps"></main>
</div>
<footer id="footer"></footer>
<script src="/__qiankun_entry__.js"></script>
</body>
</html>
`;
};
const injectEntryScript = (html: string) => {
const lines = html.split('\n');
// 如果找得到`</body>`的话就把脚本注入到它前面,没有的话就放最后一行了
const bodyEndTagLineIndex = lines.findIndex(c => c.includes('</body>'));
// 尽量和`</body>`这一行的前置空格数量对齐,长得好看些
const [leadingWhiteSpaces] = /^ */.exec((lines[bodyEndTagLineIndex] || '')) ?? [''];
lines.splice(
bodyEndTagLineIndex < 0 ? lines.length : bodyEndTagLineIndex,
0,
leadingWhiteSpaces + '<script src="/__qiankun_entry__.js"></script>'
);
return lines.join('\n');
};
const customTemplate = async (appName: string, template: string) => {
if (template.startsWith('/')) {
const templateContent = await fs.readFile(template, 'utf-8');
const appNameInjected = templateContent.replace(/\{appName\}/g, appName);
return injectEntryScript(appNameInjected);
}
return injectEntryScript(template);
};
export default async (appName: string, {template}: Options = {}) => {
return typeof template === 'string' ? customTemplate(appName, template) : defaultTemplate(appName, template);
};