webpack-dev-service 0.10.0 → 0.10.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/cjs/client/client.cjs +128 -0
- package/cjs/client/events.cjs +64 -0
- package/cjs/client/hot.cjs +111 -0
- package/cjs/client/index.cjs +15 -0
- package/cjs/client/main.cjs +59 -0
- package/cjs/client/ui/overlay.cjs +233 -0
- package/cjs/client/ui/progress.cjs +92 -0
- package/cjs/client/ui/utils.cjs +136 -0
- package/cjs/server/compose.cjs +56 -0
- package/cjs/server/dev/Service.cjs +269 -0
- package/cjs/server/dev/index.cjs +60 -0
- package/cjs/server/dev/middleware.cjs +96 -0
- package/cjs/server/dev/utils/fs.cjs +29 -0
- package/cjs/server/dev/utils/hash.cjs +46 -0
- package/cjs/server/dev/utils/http.cjs +227 -0
- package/cjs/server/dev/utils/path.cjs +46 -0
- package/cjs/server/dev/utils/paths.cjs +59 -0
- package/cjs/server/dev/utils/ready.cjs +23 -0
- package/cjs/server/dev/utils/setupHooks.cjs +106 -0
- package/cjs/server/dev/utils/setupOutputFileSystem.cjs +31 -0
- package/cjs/server/dev/utils/setupWatching.cjs +43 -0
- package/cjs/server/dev/utils/setupWriteToDisk.cjs +54 -0
- package/cjs/server/hot/Socket.cjs +185 -0
- package/cjs/server/hot/index.cjs +34 -0
- package/cjs/server/hot/utils.cjs +100 -0
- package/cjs/server/index.cjs +1 -1
- package/cjs/server/schema.cjs +127 -0
- package/cjs/server/utils.cjs +45 -0
- package/esm/client/client.js +126 -0
- package/esm/client/events.js +60 -0
- package/esm/client/hot.js +106 -0
- package/esm/client/index.js +10 -0
- package/esm/client/main.js +57 -0
- package/esm/client/ui/overlay.js +231 -0
- package/esm/client/ui/progress.js +90 -0
- package/esm/client/ui/utils.js +123 -0
- package/esm/server/compose.js +54 -0
- package/esm/server/dev/Service.js +260 -0
- package/esm/server/dev/index.js +58 -0
- package/esm/server/dev/middleware.js +94 -0
- package/esm/server/dev/utils/fs.js +27 -0
- package/esm/server/dev/utils/hash.js +44 -0
- package/esm/server/dev/utils/http.js +216 -0
- package/esm/server/dev/utils/path.js +42 -0
- package/esm/server/dev/utils/paths.js +57 -0
- package/esm/server/dev/utils/ready.js +21 -0
- package/esm/server/dev/utils/setupHooks.js +98 -0
- package/esm/server/dev/utils/setupOutputFileSystem.js +29 -0
- package/esm/server/dev/utils/setupWatching.js +41 -0
- package/esm/server/dev/utils/setupWriteToDisk.js +52 -0
- package/esm/server/hot/Socket.js +176 -0
- package/esm/server/hot/index.js +32 -0
- package/esm/server/hot/utils.js +93 -0
- package/esm/server/index.js +37 -0
- package/esm/server/schema.js +125 -0
- package/esm/server/utils.js +37 -0
- package/package.json +4 -4
|
@@ -0,0 +1,106 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @package webpack-dev-service
|
|
3
|
+
* @license MIT
|
|
4
|
+
* @version 0.10.2
|
|
5
|
+
* @author nuintun <nuintun@qq.com>
|
|
6
|
+
* @description A koa 2 middleware for webpack development and hot reloading.
|
|
7
|
+
* @see https://github.com/nuintun/webpack-dev-service#readme
|
|
8
|
+
*/
|
|
9
|
+
|
|
10
|
+
/**
|
|
11
|
+
* @module hot
|
|
12
|
+
*/
|
|
13
|
+
// Last error.
|
|
14
|
+
let error;
|
|
15
|
+
// Last update hash.
|
|
16
|
+
let hash = __webpack_hash__;
|
|
17
|
+
// HMR status.
|
|
18
|
+
let status = 'idle';
|
|
19
|
+
/**
|
|
20
|
+
* @function isUpdateAvailable
|
|
21
|
+
* @description Is there a newer version of this code available.
|
|
22
|
+
*/
|
|
23
|
+
function isUpdateAvailable() {
|
|
24
|
+
// __webpack_hash__ is the hash of the current compilation.
|
|
25
|
+
// It's a global variable injected by webpack.
|
|
26
|
+
return hash !== __webpack_hash__;
|
|
27
|
+
}
|
|
28
|
+
/**
|
|
29
|
+
* @function setHash
|
|
30
|
+
* @description Set webpack hash.
|
|
31
|
+
* @param value - The new hash value.
|
|
32
|
+
*/
|
|
33
|
+
function setHash(value) {
|
|
34
|
+
hash = value;
|
|
35
|
+
}
|
|
36
|
+
/**
|
|
37
|
+
* @function setStatus
|
|
38
|
+
* @description Set hot status.
|
|
39
|
+
* @param value The new status of the hot update.
|
|
40
|
+
*/
|
|
41
|
+
function setStatus(value) {
|
|
42
|
+
status = value;
|
|
43
|
+
}
|
|
44
|
+
// Initialize status.
|
|
45
|
+
if (import.meta.webpackHot) {
|
|
46
|
+
setStatus(import.meta.webpackHot.status());
|
|
47
|
+
}
|
|
48
|
+
/**
|
|
49
|
+
* @function applyUpdate
|
|
50
|
+
* @description Apply update.
|
|
51
|
+
* @param hmr Whether to enable HMR.
|
|
52
|
+
* @param fallback Fallback function when HMR fail.
|
|
53
|
+
*/
|
|
54
|
+
function applyUpdate(hmr, fallback) {
|
|
55
|
+
// Update available.
|
|
56
|
+
if (isUpdateAvailable()) {
|
|
57
|
+
// HMR enabled.
|
|
58
|
+
if (hmr && import.meta.webpackHot) {
|
|
59
|
+
switch (status) {
|
|
60
|
+
case 'idle':
|
|
61
|
+
// Set status.
|
|
62
|
+
setStatus('check');
|
|
63
|
+
// Auto check and apply updates.
|
|
64
|
+
import.meta.webpackHot
|
|
65
|
+
.check(true)
|
|
66
|
+
.then(updated => {
|
|
67
|
+
// Update status.
|
|
68
|
+
setStatus(import.meta.webpackHot.status());
|
|
69
|
+
// When updated modules is available,
|
|
70
|
+
// it indicates server is ready to serve new bundle.
|
|
71
|
+
if (updated) {
|
|
72
|
+
// While update completed, do it again until no update available.
|
|
73
|
+
applyUpdate(hmr, fallback);
|
|
74
|
+
}
|
|
75
|
+
})
|
|
76
|
+
.catch(exception => {
|
|
77
|
+
// Get status.
|
|
78
|
+
const status = import.meta.webpackHot.status();
|
|
79
|
+
// Update status.
|
|
80
|
+
switch (status) {
|
|
81
|
+
case 'fail':
|
|
82
|
+
case 'abort':
|
|
83
|
+
setStatus(status);
|
|
84
|
+
default:
|
|
85
|
+
setStatus('fail');
|
|
86
|
+
}
|
|
87
|
+
// Cache error.
|
|
88
|
+
error = exception;
|
|
89
|
+
// Call fallback.
|
|
90
|
+
fallback(error);
|
|
91
|
+
});
|
|
92
|
+
break;
|
|
93
|
+
case 'fail':
|
|
94
|
+
case 'abort':
|
|
95
|
+
// Call fallback.
|
|
96
|
+
fallback(error);
|
|
97
|
+
break;
|
|
98
|
+
}
|
|
99
|
+
} else {
|
|
100
|
+
// HMR disabled.
|
|
101
|
+
fallback();
|
|
102
|
+
}
|
|
103
|
+
}
|
|
104
|
+
}
|
|
105
|
+
|
|
106
|
+
export { applyUpdate, isUpdateAvailable, setHash, setStatus };
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @package webpack-dev-service
|
|
3
|
+
* @license MIT
|
|
4
|
+
* @version 0.10.2
|
|
5
|
+
* @author nuintun <nuintun@qq.com>
|
|
6
|
+
* @description A koa 2 middleware for webpack development and hot reloading.
|
|
7
|
+
* @see https://github.com/nuintun/webpack-dev-service#readme
|
|
8
|
+
*/
|
|
9
|
+
|
|
10
|
+
export { off, on } from './events.js';
|
|
@@ -0,0 +1,57 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @package webpack-dev-service
|
|
3
|
+
* @license MIT
|
|
4
|
+
* @version 0.10.2
|
|
5
|
+
* @author nuintun <nuintun@qq.com>
|
|
6
|
+
* @description A koa 2 middleware for webpack development and hot reloading.
|
|
7
|
+
* @see https://github.com/nuintun/webpack-dev-service#readme
|
|
8
|
+
*/
|
|
9
|
+
|
|
10
|
+
import createClient from './client.js';
|
|
11
|
+
|
|
12
|
+
/**
|
|
13
|
+
* @module main
|
|
14
|
+
*/
|
|
15
|
+
const isTLS = protocol => {
|
|
16
|
+
return protocol === 'https:';
|
|
17
|
+
};
|
|
18
|
+
const getCurrentScript = () => {
|
|
19
|
+
const { currentScript } = document;
|
|
20
|
+
if (currentScript) {
|
|
21
|
+
return currentScript;
|
|
22
|
+
}
|
|
23
|
+
};
|
|
24
|
+
const getProtocol = (params, protocol) => {
|
|
25
|
+
switch (params.get('wss')) {
|
|
26
|
+
case 'true':
|
|
27
|
+
return 'wss:';
|
|
28
|
+
case 'false':
|
|
29
|
+
return 'ws:';
|
|
30
|
+
default:
|
|
31
|
+
return isTLS(protocol) ? 'wss:' : 'ws:';
|
|
32
|
+
}
|
|
33
|
+
};
|
|
34
|
+
const getOrigin = params => {
|
|
35
|
+
const { location } = self;
|
|
36
|
+
const script = getCurrentScript();
|
|
37
|
+
if (script) {
|
|
38
|
+
const url = new URL(script.src, location.href);
|
|
39
|
+
const protocol = getProtocol(params, url.protocol);
|
|
40
|
+
return `${protocol}//${url.host}`;
|
|
41
|
+
}
|
|
42
|
+
const protocol = getProtocol(params, location.protocol);
|
|
43
|
+
return `${protocol}//${location.host}`;
|
|
44
|
+
};
|
|
45
|
+
const getOptions = () => {
|
|
46
|
+
const params = new URLSearchParams(__resourceQuery);
|
|
47
|
+
return {
|
|
48
|
+
origin: getOrigin(params),
|
|
49
|
+
hmr: params.get('hmr') !== 'false',
|
|
50
|
+
path: params.get('path') || '/hot',
|
|
51
|
+
name: params.get('name') || 'webpack',
|
|
52
|
+
reload: params.get('reload') !== 'false',
|
|
53
|
+
overlay: params.get('overlay') !== 'false',
|
|
54
|
+
progress: params.get('progress') !== 'false'
|
|
55
|
+
};
|
|
56
|
+
};
|
|
57
|
+
createClient(getOptions());
|
|
@@ -0,0 +1,231 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @package webpack-dev-service
|
|
3
|
+
* @license MIT
|
|
4
|
+
* @version 0.10.2
|
|
5
|
+
* @author nuintun <nuintun@qq.com>
|
|
6
|
+
* @description A koa 2 middleware for webpack development and hot reloading.
|
|
7
|
+
* @see https://github.com/nuintun/webpack-dev-service#readme
|
|
8
|
+
*/
|
|
9
|
+
|
|
10
|
+
import { getRootElement, injectCSS, appendHTML, ansiToHTML } from './utils.js';
|
|
11
|
+
|
|
12
|
+
/**
|
|
13
|
+
* @module overlay
|
|
14
|
+
* @see https://github.com/shellscape/webpack-plugin-serve
|
|
15
|
+
*/
|
|
16
|
+
const OVERLAY = 'wds-overlay';
|
|
17
|
+
const CSS = `
|
|
18
|
+
.${OVERLAY} {
|
|
19
|
+
top:0;
|
|
20
|
+
left: 0;
|
|
21
|
+
right: 0;
|
|
22
|
+
bottom: 0;
|
|
23
|
+
display: flex;
|
|
24
|
+
position: fixed;
|
|
25
|
+
font-size: 16px;
|
|
26
|
+
overflow: hidden;
|
|
27
|
+
font-style: normal;
|
|
28
|
+
font-weight: normal;
|
|
29
|
+
z-index: 2147483646;
|
|
30
|
+
flex-direction: column;
|
|
31
|
+
box-sizing: border-box;
|
|
32
|
+
transform-origin: center;
|
|
33
|
+
background: rgba(0, 0, 0, .85);
|
|
34
|
+
transform: scale(0) translateZ(0);
|
|
35
|
+
transition: transform .25s ease-out;
|
|
36
|
+
font-family: Consolas, "Lucida Console", monospace;
|
|
37
|
+
}
|
|
38
|
+
.${OVERLAY}-show {
|
|
39
|
+
transform: scale(1) translateZ(0);
|
|
40
|
+
}
|
|
41
|
+
.${OVERLAY}-close {
|
|
42
|
+
top: 16px;
|
|
43
|
+
right: 16px;
|
|
44
|
+
width: 16px;
|
|
45
|
+
height: 16px;
|
|
46
|
+
cursor: pointer;
|
|
47
|
+
position: absolute;
|
|
48
|
+
border-radius: 16px;
|
|
49
|
+
background: #ff5f58;
|
|
50
|
+
display: inline-block;
|
|
51
|
+
transform-origin: center;
|
|
52
|
+
box-shadow: #ff5f58 0 0 6px;
|
|
53
|
+
transform: rotate(0) translateZ(0);
|
|
54
|
+
transition: transform .25s ease-in-out;
|
|
55
|
+
}
|
|
56
|
+
.${OVERLAY}-close:before,
|
|
57
|
+
.${OVERLAY}-close:after {
|
|
58
|
+
top: 7px;
|
|
59
|
+
left: 3px;
|
|
60
|
+
content: "";
|
|
61
|
+
width: 10px;
|
|
62
|
+
height: 2px;
|
|
63
|
+
position: absolute;
|
|
64
|
+
background-color: white;
|
|
65
|
+
transform-origin: center;
|
|
66
|
+
}
|
|
67
|
+
.${OVERLAY}-close:before {
|
|
68
|
+
transform: rotate(45deg);
|
|
69
|
+
}
|
|
70
|
+
.${OVERLAY}-close:after {
|
|
71
|
+
transform: rotate(-45deg);
|
|
72
|
+
}
|
|
73
|
+
.${OVERLAY}-close:hover {
|
|
74
|
+
transform: rotate(180deg) translateZ(0);
|
|
75
|
+
}
|
|
76
|
+
.${OVERLAY}-title {
|
|
77
|
+
margin: 0;
|
|
78
|
+
color: #fff;
|
|
79
|
+
line-height: 16px;
|
|
80
|
+
text-align: center;
|
|
81
|
+
background: #282d35;
|
|
82
|
+
border-radius: 0 0 4px 4px;
|
|
83
|
+
padding: 16px 48px 16px 16px;
|
|
84
|
+
}
|
|
85
|
+
.${OVERLAY}-name {
|
|
86
|
+
font-weight: bold;
|
|
87
|
+
font-style: normal;
|
|
88
|
+
text-transform: uppercase;
|
|
89
|
+
}
|
|
90
|
+
.${OVERLAY}-errors-title,
|
|
91
|
+
.${OVERLAY}-warnings-title {
|
|
92
|
+
color: #ff5f58;
|
|
93
|
+
padding-left: 8px;
|
|
94
|
+
font-style: normal;
|
|
95
|
+
}
|
|
96
|
+
.${OVERLAY}-warnings-title {
|
|
97
|
+
color: #ffbd2e;
|
|
98
|
+
}
|
|
99
|
+
.${OVERLAY}-issues {
|
|
100
|
+
padding: 0 16px;
|
|
101
|
+
overflow-y: auto;
|
|
102
|
+
scrollbar-width: none;
|
|
103
|
+
-ms-overflow-style: none;
|
|
104
|
+
-ms-scroll-chaining: none;
|
|
105
|
+
overscroll-behavior: contain;
|
|
106
|
+
-webkit-overflow-scrolling: touch;
|
|
107
|
+
}
|
|
108
|
+
.${OVERLAY}-issues::-webkit-scrollbar {
|
|
109
|
+
display: none;
|
|
110
|
+
}
|
|
111
|
+
.${OVERLAY}-errors,
|
|
112
|
+
.${OVERLAY}-warnings {
|
|
113
|
+
color: #ddd;
|
|
114
|
+
padding: 16px;
|
|
115
|
+
margin: 16px 0;
|
|
116
|
+
display: block;
|
|
117
|
+
line-height: 1.2;
|
|
118
|
+
border-radius: 4px;
|
|
119
|
+
background: #282d35;
|
|
120
|
+
}
|
|
121
|
+
.${OVERLAY}-errors > section + section,
|
|
122
|
+
.${OVERLAY}-warnings > section + section {
|
|
123
|
+
margin: 16px 0 0;
|
|
124
|
+
}
|
|
125
|
+
.${OVERLAY}-errors > section > em,
|
|
126
|
+
.${OVERLAY}-warnings > section > em {
|
|
127
|
+
line-height: 1;
|
|
128
|
+
color: #641e16;
|
|
129
|
+
padding: 4px 8px;
|
|
130
|
+
font-style: normal;
|
|
131
|
+
border-radius: 4px;
|
|
132
|
+
font-weight: normal;
|
|
133
|
+
background: #ff5f58;
|
|
134
|
+
display: inline-block;
|
|
135
|
+
text-transform: uppercase;
|
|
136
|
+
}
|
|
137
|
+
.${OVERLAY}-warnings > section > em {
|
|
138
|
+
color: #3e2723;
|
|
139
|
+
background: #ffbd2e;
|
|
140
|
+
}
|
|
141
|
+
.${OVERLAY}-errors > section > pre,
|
|
142
|
+
.${OVERLAY}-warnings > section > pre {
|
|
143
|
+
margin: 0;
|
|
144
|
+
font-size: 14px;
|
|
145
|
+
font-family: inherit;
|
|
146
|
+
padding: 8px 0 0 16px;
|
|
147
|
+
white-space: pre-wrap;
|
|
148
|
+
overflow-wrap: anywhere;
|
|
149
|
+
}
|
|
150
|
+
.${OVERLAY}-errors > section > pre a,
|
|
151
|
+
.${OVERLAY}-warnings > section > pre a,
|
|
152
|
+
.${OVERLAY}-errors > section > pre span,
|
|
153
|
+
.${OVERLAY}-warnings > section > pre span {
|
|
154
|
+
display: inline-flex;
|
|
155
|
+
}
|
|
156
|
+
.${OVERLAY}-hidden {
|
|
157
|
+
display: none;
|
|
158
|
+
}
|
|
159
|
+
`;
|
|
160
|
+
const DEFAULT_NAME = 'webpack';
|
|
161
|
+
const HTML = `
|
|
162
|
+
<div class="${OVERLAY}">
|
|
163
|
+
<i class="${OVERLAY}-close"></i>
|
|
164
|
+
<div class="${OVERLAY}-title">
|
|
165
|
+
<em class="${OVERLAY}-name"></em>
|
|
166
|
+
<em class="${OVERLAY}-errors-title"></em>
|
|
167
|
+
<em class="${OVERLAY}-warnings-title"></em>
|
|
168
|
+
</div>
|
|
169
|
+
<aside class="${OVERLAY}-issues">
|
|
170
|
+
<article class="${OVERLAY}-errors ${OVERLAY}-hidden"></article>
|
|
171
|
+
<article class="${OVERLAY}-warnings ${OVERLAY}-hidden"></article>
|
|
172
|
+
</aside>
|
|
173
|
+
</div>
|
|
174
|
+
`;
|
|
175
|
+
class Overlay {
|
|
176
|
+
constructor(name) {
|
|
177
|
+
this.hidden = true;
|
|
178
|
+
const root = getRootElement(OVERLAY);
|
|
179
|
+
injectCSS(CSS, root);
|
|
180
|
+
const [dialog] = appendHTML(HTML, root);
|
|
181
|
+
this.dialog = dialog;
|
|
182
|
+
this.name = dialog.querySelector(`.${OVERLAY}-name`);
|
|
183
|
+
this.close = dialog.querySelector(`.${OVERLAY}-close`);
|
|
184
|
+
this.errorsList = dialog.querySelector(`.${OVERLAY}-errors`);
|
|
185
|
+
this.warningsList = dialog.querySelector(`.${OVERLAY}-warnings`);
|
|
186
|
+
this.errorsTitle = dialog.querySelector(`.${OVERLAY}-errors-title`);
|
|
187
|
+
this.warningsTitle = dialog.querySelector(`.${OVERLAY}-warnings-title`);
|
|
188
|
+
this.name.innerHTML = `⭕ ${name || DEFAULT_NAME}`;
|
|
189
|
+
this.close.addEventListener('click', () => {
|
|
190
|
+
this.hide();
|
|
191
|
+
});
|
|
192
|
+
}
|
|
193
|
+
setIssues(type, issues) {
|
|
194
|
+
const count = issues.length;
|
|
195
|
+
const hidden = `${OVERLAY}-hidden`;
|
|
196
|
+
const problemMaps = {
|
|
197
|
+
errors: ['Error', this.errorsTitle, this.errorsList],
|
|
198
|
+
warnings: ['Warning', this.warningsTitle, this.warningsList]
|
|
199
|
+
};
|
|
200
|
+
const [name, problemTitle, problemList] = problemMaps[type];
|
|
201
|
+
if (count > 0) {
|
|
202
|
+
let html = '';
|
|
203
|
+
problemTitle.innerText = `${count} ${name}(s)`;
|
|
204
|
+
for (const { moduleName, chunkName, message } of issues) {
|
|
205
|
+
const details = ansiToHTML(message);
|
|
206
|
+
const filename = moduleName || chunkName || 'unknown';
|
|
207
|
+
html += `<section><em>${name}</em> in ${filename}<pre>${details}</pre></section>`;
|
|
208
|
+
}
|
|
209
|
+
problemList.innerHTML = html;
|
|
210
|
+
problemList.classList.remove(hidden);
|
|
211
|
+
problemTitle.classList.remove(hidden);
|
|
212
|
+
} else {
|
|
213
|
+
problemList.classList.add(hidden);
|
|
214
|
+
problemTitle.classList.add(hidden);
|
|
215
|
+
}
|
|
216
|
+
}
|
|
217
|
+
show() {
|
|
218
|
+
if (this.hidden) {
|
|
219
|
+
this.hidden = false;
|
|
220
|
+
this.dialog.classList.add(`${OVERLAY}-show`);
|
|
221
|
+
}
|
|
222
|
+
}
|
|
223
|
+
hide() {
|
|
224
|
+
if (!this.hidden) {
|
|
225
|
+
this.hidden = true;
|
|
226
|
+
this.dialog.classList.remove(`${OVERLAY}-show`);
|
|
227
|
+
}
|
|
228
|
+
}
|
|
229
|
+
}
|
|
230
|
+
|
|
231
|
+
export { Overlay as default };
|
|
@@ -0,0 +1,90 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @package webpack-dev-service
|
|
3
|
+
* @license MIT
|
|
4
|
+
* @version 0.10.2
|
|
5
|
+
* @author nuintun <nuintun@qq.com>
|
|
6
|
+
* @description A koa 2 middleware for webpack development and hot reloading.
|
|
7
|
+
* @see https://github.com/nuintun/webpack-dev-service#readme
|
|
8
|
+
*/
|
|
9
|
+
|
|
10
|
+
import { getRootElement, injectCSS, appendHTML } from './utils.js';
|
|
11
|
+
|
|
12
|
+
/**
|
|
13
|
+
* @module progress
|
|
14
|
+
* @see https://github.com/shellscape/webpack-plugin-serve
|
|
15
|
+
* @see https://www.zhangxinxu.com/wordpress/2015/07/svg-circle-loading
|
|
16
|
+
*/
|
|
17
|
+
const PROGRESS = 'wds-progress';
|
|
18
|
+
const PERIMETER = 2 * Math.PI * 44;
|
|
19
|
+
const CSS = `
|
|
20
|
+
.${PROGRESS} {
|
|
21
|
+
width: 48px;
|
|
22
|
+
right: 16px;
|
|
23
|
+
height: 48px;
|
|
24
|
+
bottom: 16px;
|
|
25
|
+
display: block;
|
|
26
|
+
font-size: 16px;
|
|
27
|
+
position: fixed;
|
|
28
|
+
cursor: default;
|
|
29
|
+
user-select: none;
|
|
30
|
+
font-style: normal;
|
|
31
|
+
font-weight: normal;
|
|
32
|
+
z-index: 2147483647;
|
|
33
|
+
transform-origin: center;
|
|
34
|
+
transform: scale(0) translateZ(0);
|
|
35
|
+
transition: transform .25s ease-out;
|
|
36
|
+
}
|
|
37
|
+
.${PROGRESS}-show {
|
|
38
|
+
transform: scale(1) translateZ(0);
|
|
39
|
+
}
|
|
40
|
+
.${PROGRESS}-track {
|
|
41
|
+
stroke: #badfac;
|
|
42
|
+
stroke-width: 8;
|
|
43
|
+
stroke-linecap: round;
|
|
44
|
+
fill: rgba(0, 0, 0, 0);
|
|
45
|
+
stroke-dasharray: ${PERIMETER};
|
|
46
|
+
stroke-dashoffset: ${PERIMETER};
|
|
47
|
+
transition: stroke-dashoffset .25s linear;
|
|
48
|
+
transform: matrix(0, -1, 1, 0, 0, 96) translateZ(0);
|
|
49
|
+
}
|
|
50
|
+
`;
|
|
51
|
+
const HTML = `
|
|
52
|
+
<svg class="${PROGRESS}" x="0" y="0" viewBox="0 0 96 96">
|
|
53
|
+
<circle fill="#282d35" cx="50%" cy="50%" r="44" />
|
|
54
|
+
<circle class="${PROGRESS}-track" cx="50%" cy="50%" r="44" />
|
|
55
|
+
<path fill="#fff" d="m48,83.213561l-31.122918,-17.60678l0,-35.21356l31.122918,-17.60678l31.122918,17.60678l0,35.21356l-31.122918,17.60678z" />
|
|
56
|
+
<path fill="#8ed6fb" d="m22.434956,31.608089l24.537982,-13.880011l0,10.810563l-15.288554,8.410172l-9.249428,-5.340723zm-1.678513,1.520052l0,29.027711l8.979458,-5.182262l0,-18.657318l-8.979458,-5.188131zm52.908373,-1.520052l-24.537982,-13.880011l0,10.810563l15.288554,8.410172l9.249428,-5.340723zm1.678513,1.520052l0,29.027711l-8.979458,-5.182262l0,-18.657318l8.979458,-5.188131zm-1.050538,30.905767l-25.165957,14.238016l0,-10.452558l16.121941,-8.867948l0.123247,-0.070427l8.920768,5.152918zm-52.485811,0l25.165957,14.238016l0,-10.452558l-16.121941,-8.867948l-0.123247,-0.070427l-8.920768,5.152918z" />
|
|
57
|
+
<path fill="#1c78c0" d="m49.126834,30.997721l15.083141,8.292793l0,16.432994l-15.083141,-8.709487l0,-16.016301zm-2.153896,0l-15.083141,8.292793l0,16.432994l15.083141,-8.709487l0,-16.016301zm16.215844,26.62732l-15.141831,8.328007l-15.141831,-8.328007l15.141831,-8.744701l15.141831,8.744701z" />
|
|
58
|
+
</svg>
|
|
59
|
+
`;
|
|
60
|
+
class Progress {
|
|
61
|
+
constructor() {
|
|
62
|
+
this.hidden = true;
|
|
63
|
+
const root = getRootElement(PROGRESS);
|
|
64
|
+
injectCSS(CSS, root);
|
|
65
|
+
[this.svg] = appendHTML(HTML, root);
|
|
66
|
+
this.track = this.svg.querySelector(`.${PROGRESS}-track`);
|
|
67
|
+
}
|
|
68
|
+
update(value) {
|
|
69
|
+
value = Math.max(0, Math.min(100, value));
|
|
70
|
+
this.track.style.strokeDashoffset = (((100 - value) / 100) * PERIMETER).toString();
|
|
71
|
+
}
|
|
72
|
+
show() {
|
|
73
|
+
if (this.hidden) {
|
|
74
|
+
this.hidden = false;
|
|
75
|
+
clearTimeout(this.timer);
|
|
76
|
+
this.svg.classList.add(`${PROGRESS}-show`);
|
|
77
|
+
}
|
|
78
|
+
}
|
|
79
|
+
hide() {
|
|
80
|
+
if (!this.hidden) {
|
|
81
|
+
this.hidden = true;
|
|
82
|
+
this.timer = self.setTimeout(() => {
|
|
83
|
+
this.update(0);
|
|
84
|
+
this.svg.classList.remove(`${PROGRESS}-show`);
|
|
85
|
+
}, 300);
|
|
86
|
+
}
|
|
87
|
+
}
|
|
88
|
+
}
|
|
89
|
+
|
|
90
|
+
export { Progress as default };
|
|
@@ -0,0 +1,123 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @package webpack-dev-service
|
|
3
|
+
* @license MIT
|
|
4
|
+
* @version 0.10.2
|
|
5
|
+
* @author nuintun <nuintun@qq.com>
|
|
6
|
+
* @description A koa 2 middleware for webpack development and hot reloading.
|
|
7
|
+
* @see https://github.com/nuintun/webpack-dev-service#readme
|
|
8
|
+
*/
|
|
9
|
+
|
|
10
|
+
import Ansi from '@nuintun/ansi';
|
|
11
|
+
|
|
12
|
+
/**
|
|
13
|
+
* @module utils
|
|
14
|
+
*/
|
|
15
|
+
const ansi = new Ansi();
|
|
16
|
+
function escapeHTML(text) {
|
|
17
|
+
return text.replace(/[&<>"']/gm, match => {
|
|
18
|
+
switch (match) {
|
|
19
|
+
case '&':
|
|
20
|
+
return '&';
|
|
21
|
+
case '<':
|
|
22
|
+
return '<';
|
|
23
|
+
case '>':
|
|
24
|
+
return '>';
|
|
25
|
+
case '"':
|
|
26
|
+
return '"';
|
|
27
|
+
case "'":
|
|
28
|
+
return ''';
|
|
29
|
+
default:
|
|
30
|
+
return match;
|
|
31
|
+
}
|
|
32
|
+
});
|
|
33
|
+
}
|
|
34
|
+
function blockToHTML({ style, value, url }) {
|
|
35
|
+
const styles = [];
|
|
36
|
+
const textDecorations = [];
|
|
37
|
+
if (style.dim) {
|
|
38
|
+
styles.push(`opacity: 0.5`);
|
|
39
|
+
}
|
|
40
|
+
if (style.bold) {
|
|
41
|
+
styles.push(`font-weight: bold`);
|
|
42
|
+
}
|
|
43
|
+
if (style.italic) {
|
|
44
|
+
styles.push(`font-style: italic`);
|
|
45
|
+
}
|
|
46
|
+
if (style.inverse) {
|
|
47
|
+
styles.push(`filter: invert(1)`);
|
|
48
|
+
}
|
|
49
|
+
if (style.hidden) {
|
|
50
|
+
styles.push(`visibility: hidden`);
|
|
51
|
+
}
|
|
52
|
+
if (style.blink) {
|
|
53
|
+
textDecorations.push('blink');
|
|
54
|
+
}
|
|
55
|
+
if (style.overline) {
|
|
56
|
+
textDecorations.push('overline');
|
|
57
|
+
}
|
|
58
|
+
if (style.underline) {
|
|
59
|
+
textDecorations.push('underline');
|
|
60
|
+
}
|
|
61
|
+
if (style.strikethrough) {
|
|
62
|
+
textDecorations.push('line-through');
|
|
63
|
+
}
|
|
64
|
+
const { color, background } = style;
|
|
65
|
+
if (color) {
|
|
66
|
+
styles.push(`color: rgb(${color})`);
|
|
67
|
+
}
|
|
68
|
+
if (background) {
|
|
69
|
+
styles.push(`background-color: rgb(${background})`);
|
|
70
|
+
}
|
|
71
|
+
if (textDecorations.length > 0) {
|
|
72
|
+
styles.push(`text-decoration: ${textDecorations.join(' ')}`);
|
|
73
|
+
}
|
|
74
|
+
const escapedValue = escapeHTML(value);
|
|
75
|
+
const href = url ? JSON.stringify(new URL(url).toString()) : null;
|
|
76
|
+
if (styles.length <= 0) {
|
|
77
|
+
if (!href) {
|
|
78
|
+
return escapedValue;
|
|
79
|
+
}
|
|
80
|
+
return `<a href=${href} target="_blank">${escapedValue}</a>`;
|
|
81
|
+
}
|
|
82
|
+
const inlineStyle = JSON.stringify(`${styles.join('; ')};`);
|
|
83
|
+
if (!href) {
|
|
84
|
+
return `<span style=${inlineStyle}>${escapedValue}</span>`;
|
|
85
|
+
}
|
|
86
|
+
return `<a style=${inlineStyle} href=${href} target="_blank">${escapedValue}</a>`;
|
|
87
|
+
}
|
|
88
|
+
function ansiToHTML(text) {
|
|
89
|
+
let html = '';
|
|
90
|
+
ansi.write(text, block => {
|
|
91
|
+
html += blockToHTML(block);
|
|
92
|
+
});
|
|
93
|
+
ansi.flush(block => {
|
|
94
|
+
html += blockToHTML(block);
|
|
95
|
+
});
|
|
96
|
+
return html;
|
|
97
|
+
}
|
|
98
|
+
function getRootElement(tagName) {
|
|
99
|
+
const stage = document.createElement(tagName);
|
|
100
|
+
const root = stage.attachShadow({ mode: 'closed' });
|
|
101
|
+
document.body.appendChild(stage);
|
|
102
|
+
return root;
|
|
103
|
+
}
|
|
104
|
+
function injectCSS(css, root = document.body, styleElement = document.createElement('style')) {
|
|
105
|
+
styleElement.appendChild(document.createTextNode(css.trim()));
|
|
106
|
+
if (!root.contains(styleElement)) {
|
|
107
|
+
root.appendChild(styleElement);
|
|
108
|
+
}
|
|
109
|
+
return styleElement;
|
|
110
|
+
}
|
|
111
|
+
function appendHTML(html, root = document.body) {
|
|
112
|
+
const nodes = [];
|
|
113
|
+
const parser = new DOMParser();
|
|
114
|
+
const fragment = document.createDocumentFragment();
|
|
115
|
+
const { body } = parser.parseFromString(html.trim(), 'text/html');
|
|
116
|
+
while (body.firstChild) {
|
|
117
|
+
nodes.push(fragment.appendChild(body.firstChild));
|
|
118
|
+
}
|
|
119
|
+
root.appendChild(fragment);
|
|
120
|
+
return nodes;
|
|
121
|
+
}
|
|
122
|
+
|
|
123
|
+
export { ansiToHTML, appendHTML, blockToHTML, escapeHTML, getRootElement, injectCSS };
|
|
@@ -0,0 +1,54 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @package webpack-dev-service
|
|
3
|
+
* @license MIT
|
|
4
|
+
* @version 0.10.2
|
|
5
|
+
* @author nuintun <nuintun@qq.com>
|
|
6
|
+
* @description A koa 2 middleware for webpack development and hot reloading.
|
|
7
|
+
* @see https://github.com/nuintun/webpack-dev-service#readme
|
|
8
|
+
*/
|
|
9
|
+
|
|
10
|
+
/**
|
|
11
|
+
* @module compose
|
|
12
|
+
*/
|
|
13
|
+
/**
|
|
14
|
+
* @function dispatch
|
|
15
|
+
* @param middlewares 中间件数组
|
|
16
|
+
* @param index 要执行的中间件索引
|
|
17
|
+
* @param stack 调用栈信息
|
|
18
|
+
* @param context 执行上下文
|
|
19
|
+
* @param [next] 下一个中间件
|
|
20
|
+
*/
|
|
21
|
+
async function dispatch(middlewares, index, stack, context, next) {
|
|
22
|
+
if (index <= stack.index) {
|
|
23
|
+
throw new Error('next() called multiple times');
|
|
24
|
+
}
|
|
25
|
+
stack.index = index;
|
|
26
|
+
const { length } = middlewares;
|
|
27
|
+
if (index < length) {
|
|
28
|
+
const middleware = middlewares[index];
|
|
29
|
+
await middleware(context, () => {
|
|
30
|
+
return dispatch(middlewares, index + 1, stack, context, next);
|
|
31
|
+
});
|
|
32
|
+
} else if (next) {
|
|
33
|
+
await next();
|
|
34
|
+
}
|
|
35
|
+
}
|
|
36
|
+
/**
|
|
37
|
+
* @function compose
|
|
38
|
+
* @description 生成融合中间件
|
|
39
|
+
* @param middlewares 中间件数组
|
|
40
|
+
*/
|
|
41
|
+
function compose(...middlewares) {
|
|
42
|
+
/**
|
|
43
|
+
* @function middleware
|
|
44
|
+
* @description 融合中间件
|
|
45
|
+
* @param context 执行上下文
|
|
46
|
+
* @param [next] 下一个中间件
|
|
47
|
+
*/
|
|
48
|
+
return (context, next) => {
|
|
49
|
+
const stack = { index: -1 };
|
|
50
|
+
return dispatch(middlewares, 0, stack, context, next);
|
|
51
|
+
};
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
export { compose };
|