@qse/edu-scripts 0.0.0-beta.5 → 0.0.0-beta.7
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/asset/rspack-dev-server-client.js +534 -0
- package/dist/cli.mjs +9 -8
- package/package.json +2 -2
- package/src/build.ts +1 -0
- package/src/cli.ts +1 -0
- package/src/commit-dist.ts +1 -4
- package/src/config/paths.ts +1 -2
- package/src/config/plugins/mock-server/index.ts +0 -3
- package/src/config/webpackConfig.ts +6 -4
- package/src/deploy.ts +1 -1
- package/src/start.ts +4 -3
- package/src/utils/FileSizeReporter.ts +13 -12
- package/asset/ws-utils-createSocketURL.js +0 -140
|
@@ -0,0 +1,534 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* The following code is modified based on
|
|
3
|
+
* https://github.com/webpack/webpack-dev-server
|
|
4
|
+
*
|
|
5
|
+
* MIT Licensed
|
|
6
|
+
* Author Tobias Koppers @sokra
|
|
7
|
+
* Copyright (c) JS Foundation and other contributors
|
|
8
|
+
* https://github.com/webpack/webpack-dev-server/blob/main/LICENSE
|
|
9
|
+
*/
|
|
10
|
+
var __assign =
|
|
11
|
+
(this && this.__assign) ||
|
|
12
|
+
function () {
|
|
13
|
+
__assign =
|
|
14
|
+
Object.assign ||
|
|
15
|
+
function (t) {
|
|
16
|
+
for (var s, i = 1, n = arguments.length; i < n; i++) {
|
|
17
|
+
s = arguments[i]
|
|
18
|
+
for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p)) t[p] = s[p]
|
|
19
|
+
}
|
|
20
|
+
return t
|
|
21
|
+
}
|
|
22
|
+
return __assign.apply(this, arguments)
|
|
23
|
+
}
|
|
24
|
+
// @ts-expect-error: No type definitions available for '@rspack/core/hot/emitter.js'
|
|
25
|
+
import hotEmitter from '@rspack/core/hot/emitter.js'
|
|
26
|
+
/* Rspack dev server runtime client */
|
|
27
|
+
// @ts-expect-error: No type definitions available for '@rspack/core/hot/log.js'
|
|
28
|
+
import webpackHotLog from '@rspack/core/hot/log.js'
|
|
29
|
+
import { createOverlay, formatProblem } from '@rspack/dev-server/client/overlay.js'
|
|
30
|
+
import socket from '@rspack/dev-server/client/socket.js'
|
|
31
|
+
import { defineProgressElement, isProgressSupported } from '@rspack/dev-server/client/progress.js'
|
|
32
|
+
import { log, setLogLevel } from '@rspack/dev-server/client/utils/log.js'
|
|
33
|
+
import sendMessage from '@rspack/dev-server/client/utils/sendMessage.js'
|
|
34
|
+
var decodeOverlayOptions = function (overlayOptions) {
|
|
35
|
+
if (typeof overlayOptions === 'object') {
|
|
36
|
+
;['warnings', 'errors', 'runtimeErrors'].forEach(function (property) {
|
|
37
|
+
if (typeof overlayOptions[property] === 'string') {
|
|
38
|
+
var overlayFilterFunctionString = decodeURIComponent(overlayOptions[property])
|
|
39
|
+
overlayOptions[property] = new Function(
|
|
40
|
+
'message',
|
|
41
|
+
'var callback = '.concat(
|
|
42
|
+
overlayFilterFunctionString,
|
|
43
|
+
'\n\t\t\t\treturn callback(message)'
|
|
44
|
+
)
|
|
45
|
+
)
|
|
46
|
+
}
|
|
47
|
+
})
|
|
48
|
+
}
|
|
49
|
+
}
|
|
50
|
+
var parseURL = function (resourceQuery) {
|
|
51
|
+
var result = {}
|
|
52
|
+
if (typeof resourceQuery === 'string' && resourceQuery !== '') {
|
|
53
|
+
var searchParams = resourceQuery.slice(1).split('&')
|
|
54
|
+
for (var i = 0; i < searchParams.length; i++) {
|
|
55
|
+
var pair = searchParams[i].split('=')
|
|
56
|
+
result[pair[0]] = decodeURIComponent(pair[1])
|
|
57
|
+
}
|
|
58
|
+
} else {
|
|
59
|
+
// Else, get the url from the <script> this file was called with.
|
|
60
|
+
var scriptSource = getCurrentScriptSource()
|
|
61
|
+
var scriptSourceURL = void 0
|
|
62
|
+
try {
|
|
63
|
+
// The placeholder `baseURL` with `window.location.href`,
|
|
64
|
+
// is to allow parsing of path-relative or protocol-relative URLs,
|
|
65
|
+
// and will have no effect if `scriptSource` is a fully valid URL.
|
|
66
|
+
scriptSourceURL = new URL(scriptSource, self.location.href)
|
|
67
|
+
} catch (error) {
|
|
68
|
+
// URL parsing failed, do nothing.
|
|
69
|
+
// We will still proceed to see if we can recover using `resourceQuery`
|
|
70
|
+
}
|
|
71
|
+
if (scriptSourceURL) {
|
|
72
|
+
result = scriptSourceURL
|
|
73
|
+
result['fromCurrentScript'] = 'true'
|
|
74
|
+
}
|
|
75
|
+
}
|
|
76
|
+
return result
|
|
77
|
+
}
|
|
78
|
+
var status = {
|
|
79
|
+
isUnloading: false,
|
|
80
|
+
currentHash: __webpack_hash__,
|
|
81
|
+
}
|
|
82
|
+
var getCurrentScriptSource = function () {
|
|
83
|
+
// `document.currentScript` is the most accurate way to find the current script,
|
|
84
|
+
// but is not supported in all browsers.
|
|
85
|
+
if (document.currentScript) {
|
|
86
|
+
return document.currentScript.getAttribute('src')
|
|
87
|
+
}
|
|
88
|
+
// Fallback to getting all scripts running in the document.
|
|
89
|
+
var scriptElements = document.scripts || []
|
|
90
|
+
var scriptElementsWithSrc = Array.prototype.filter.call(scriptElements, function (element) {
|
|
91
|
+
return element.getAttribute('src')
|
|
92
|
+
})
|
|
93
|
+
if (scriptElementsWithSrc.length > 0) {
|
|
94
|
+
var currentScript = scriptElementsWithSrc[scriptElementsWithSrc.length - 1]
|
|
95
|
+
return currentScript.getAttribute('src')
|
|
96
|
+
}
|
|
97
|
+
// Fail as there was no script to use.
|
|
98
|
+
throw new Error('[webpack-dev-server] Failed to get current script source.')
|
|
99
|
+
}
|
|
100
|
+
var parsedResourceQuery = parseURL(__resourceQuery)
|
|
101
|
+
var enabledFeatures = {
|
|
102
|
+
'Hot Module Replacement': false,
|
|
103
|
+
'Live Reloading': false,
|
|
104
|
+
Progress: false,
|
|
105
|
+
Overlay: false,
|
|
106
|
+
}
|
|
107
|
+
var options = {
|
|
108
|
+
hot: false,
|
|
109
|
+
liveReload: false,
|
|
110
|
+
progress: false,
|
|
111
|
+
overlay: false,
|
|
112
|
+
}
|
|
113
|
+
if (parsedResourceQuery.hot === 'true') {
|
|
114
|
+
options.hot = true
|
|
115
|
+
enabledFeatures['Hot Module Replacement'] = true
|
|
116
|
+
}
|
|
117
|
+
if (parsedResourceQuery['live-reload'] === 'true') {
|
|
118
|
+
options.liveReload = true
|
|
119
|
+
enabledFeatures['Live Reloading'] = true
|
|
120
|
+
}
|
|
121
|
+
if (parsedResourceQuery.progress === 'true') {
|
|
122
|
+
options.progress = true
|
|
123
|
+
enabledFeatures.Progress = true
|
|
124
|
+
}
|
|
125
|
+
if (parsedResourceQuery.overlay) {
|
|
126
|
+
try {
|
|
127
|
+
options.overlay = JSON.parse(parsedResourceQuery.overlay)
|
|
128
|
+
} catch (e) {
|
|
129
|
+
log.error('Error parsing overlay options from resource query:', e)
|
|
130
|
+
}
|
|
131
|
+
// Fill in default "true" params for partially-specified objects.
|
|
132
|
+
if (typeof options.overlay === 'object') {
|
|
133
|
+
options.overlay = __assign(
|
|
134
|
+
{ errors: true, warnings: true, runtimeErrors: true },
|
|
135
|
+
options.overlay
|
|
136
|
+
)
|
|
137
|
+
decodeOverlayOptions(options.overlay)
|
|
138
|
+
}
|
|
139
|
+
enabledFeatures.Overlay = options.overlay !== false
|
|
140
|
+
}
|
|
141
|
+
if (parsedResourceQuery.logging) {
|
|
142
|
+
options.logging = parsedResourceQuery.logging
|
|
143
|
+
}
|
|
144
|
+
if (typeof parsedResourceQuery.reconnect !== 'undefined') {
|
|
145
|
+
options.reconnect = Number(parsedResourceQuery.reconnect)
|
|
146
|
+
}
|
|
147
|
+
var setAllLogLevel = function (level) {
|
|
148
|
+
// This is needed because the HMR logger operate separately from dev server logger
|
|
149
|
+
webpackHotLog.setLogLevel(level === 'verbose' || level === 'log' ? 'info' : level)
|
|
150
|
+
setLogLevel(level)
|
|
151
|
+
}
|
|
152
|
+
if (options.logging) {
|
|
153
|
+
setAllLogLevel(options.logging)
|
|
154
|
+
}
|
|
155
|
+
var logEnabledFeatures = function (features) {
|
|
156
|
+
var listEnabledFeatures = Object.keys(features)
|
|
157
|
+
if (!features || listEnabledFeatures.length === 0) {
|
|
158
|
+
return
|
|
159
|
+
}
|
|
160
|
+
var logString = 'Server started:'
|
|
161
|
+
// Server started: Hot Module Replacement enabled, Live Reloading enabled, Overlay disabled.
|
|
162
|
+
for (var i = 0; i < listEnabledFeatures.length; i++) {
|
|
163
|
+
var key = listEnabledFeatures[i]
|
|
164
|
+
logString += ' '.concat(key, ' ').concat(features[key] ? 'enabled' : 'disabled', ',')
|
|
165
|
+
}
|
|
166
|
+
// replace last comma with a period
|
|
167
|
+
logString = logString.slice(0, -1).concat('.')
|
|
168
|
+
log.info(logString)
|
|
169
|
+
}
|
|
170
|
+
logEnabledFeatures(enabledFeatures)
|
|
171
|
+
self.addEventListener('beforeunload', function () {
|
|
172
|
+
status.isUnloading = true
|
|
173
|
+
})
|
|
174
|
+
var overlay =
|
|
175
|
+
typeof window !== 'undefined'
|
|
176
|
+
? createOverlay(
|
|
177
|
+
typeof options.overlay === 'object'
|
|
178
|
+
? {
|
|
179
|
+
trustedTypesPolicyName: options.overlay.trustedTypesPolicyName,
|
|
180
|
+
catchRuntimeError: options.overlay.runtimeErrors,
|
|
181
|
+
}
|
|
182
|
+
: {
|
|
183
|
+
trustedTypesPolicyName: false,
|
|
184
|
+
catchRuntimeError: options.overlay,
|
|
185
|
+
}
|
|
186
|
+
)
|
|
187
|
+
: { send: function () {} }
|
|
188
|
+
var reloadApp = function (_a, currentStatus) {
|
|
189
|
+
var hot = _a.hot,
|
|
190
|
+
liveReload = _a.liveReload
|
|
191
|
+
if (currentStatus.isUnloading) {
|
|
192
|
+
return
|
|
193
|
+
}
|
|
194
|
+
var currentHash = currentStatus.currentHash,
|
|
195
|
+
previousHash = currentStatus.previousHash
|
|
196
|
+
var isInitial = currentHash.indexOf(previousHash) >= 0
|
|
197
|
+
if (isInitial) {
|
|
198
|
+
return
|
|
199
|
+
}
|
|
200
|
+
function applyReload(rootWindow, intervalId) {
|
|
201
|
+
clearInterval(intervalId)
|
|
202
|
+
log.info('App updated. Reloading...')
|
|
203
|
+
rootWindow.location.reload()
|
|
204
|
+
}
|
|
205
|
+
var search = self.location.search.toLowerCase()
|
|
206
|
+
var allowToHot = search.indexOf('webpack-dev-server-hot=false') === -1
|
|
207
|
+
var allowToLiveReload = search.indexOf('webpack-dev-server-live-reload=false') === -1
|
|
208
|
+
if (hot && allowToHot) {
|
|
209
|
+
log.info('App hot update...')
|
|
210
|
+
hotEmitter.emit('webpackHotUpdate', currentStatus.currentHash)
|
|
211
|
+
if (typeof self !== 'undefined' && self.window) {
|
|
212
|
+
// broadcast update to window
|
|
213
|
+
self.postMessage('webpackHotUpdate'.concat(currentStatus.currentHash), '*')
|
|
214
|
+
}
|
|
215
|
+
}
|
|
216
|
+
// allow refreshing the page only if liveReload isn't disabled
|
|
217
|
+
else if (liveReload && allowToLiveReload) {
|
|
218
|
+
var rootWindow_1 = self
|
|
219
|
+
// use parent window for reload (in case we're in an iframe with no valid src)
|
|
220
|
+
var intervalId_1 = self.setInterval(function () {
|
|
221
|
+
if (rootWindow_1.location.protocol !== 'about:') {
|
|
222
|
+
// reload immediately if protocol is valid
|
|
223
|
+
applyReload(rootWindow_1, intervalId_1)
|
|
224
|
+
} else {
|
|
225
|
+
rootWindow_1 = rootWindow_1.parent
|
|
226
|
+
if (rootWindow_1.parent === rootWindow_1) {
|
|
227
|
+
// if parent equals current window we've reached the root which would continue forever, so trigger a reload anyways
|
|
228
|
+
applyReload(rootWindow_1, intervalId_1)
|
|
229
|
+
}
|
|
230
|
+
}
|
|
231
|
+
})
|
|
232
|
+
}
|
|
233
|
+
}
|
|
234
|
+
var ansiRegex = new RegExp(
|
|
235
|
+
[
|
|
236
|
+
'[\\u001B\\u009B][[\\]()#;?]*(?:(?:(?:(?:;[-a-zA-Z\\d\\/#&.:=?%@~_]+)*|[a-zA-Z\\d]+(?:;[-a-zA-Z\\d\\/#&.:=?%@~_]*)*)?\\u0007)',
|
|
237
|
+
'(?:(?:\\d{1,4}(?:;\\d{0,4})*)?[\\dA-PR-TZcf-nq-uy=><~]))',
|
|
238
|
+
].join('|'),
|
|
239
|
+
'g'
|
|
240
|
+
)
|
|
241
|
+
/**
|
|
242
|
+
*
|
|
243
|
+
* Strip [ANSI escape codes](https://en.wikipedia.org/wiki/ANSI_escape_code) from a string.
|
|
244
|
+
* Adapted from code originally released by Sindre Sorhus
|
|
245
|
+
* Licensed the MIT License
|
|
246
|
+
*
|
|
247
|
+
*/
|
|
248
|
+
var stripAnsi = function (string) {
|
|
249
|
+
if (typeof string !== 'string') {
|
|
250
|
+
throw new TypeError('Expected a `string`, got `'.concat(typeof string, '`'))
|
|
251
|
+
}
|
|
252
|
+
return string.replace(ansiRegex, '')
|
|
253
|
+
}
|
|
254
|
+
var onSocketMessage = {
|
|
255
|
+
hot: function () {
|
|
256
|
+
if (parsedResourceQuery.hot === 'false') {
|
|
257
|
+
return
|
|
258
|
+
}
|
|
259
|
+
options.hot = true
|
|
260
|
+
},
|
|
261
|
+
liveReload: function () {
|
|
262
|
+
if (parsedResourceQuery['live-reload'] === 'false') {
|
|
263
|
+
return
|
|
264
|
+
}
|
|
265
|
+
options.liveReload = true
|
|
266
|
+
},
|
|
267
|
+
invalid: function () {
|
|
268
|
+
log.info('App updated. Recompiling...')
|
|
269
|
+
// Fixes #1042. overlay doesn't clear if errors are fixed but warnings remain.
|
|
270
|
+
if (options.overlay) {
|
|
271
|
+
overlay.send({ type: 'DISMISS' })
|
|
272
|
+
}
|
|
273
|
+
sendMessage('Invalid')
|
|
274
|
+
},
|
|
275
|
+
hash: function hash(_hash) {
|
|
276
|
+
if (!_hash) {
|
|
277
|
+
return
|
|
278
|
+
}
|
|
279
|
+
status.previousHash = status.currentHash
|
|
280
|
+
status.currentHash = _hash
|
|
281
|
+
},
|
|
282
|
+
logging: setAllLogLevel,
|
|
283
|
+
overlay: function (value) {
|
|
284
|
+
if (typeof document === 'undefined') {
|
|
285
|
+
return
|
|
286
|
+
}
|
|
287
|
+
options.overlay = value
|
|
288
|
+
decodeOverlayOptions(options.overlay)
|
|
289
|
+
},
|
|
290
|
+
reconnect: function (value) {
|
|
291
|
+
if (parsedResourceQuery.reconnect === 'false') {
|
|
292
|
+
return
|
|
293
|
+
}
|
|
294
|
+
options.reconnect = value
|
|
295
|
+
},
|
|
296
|
+
progress: function (value) {
|
|
297
|
+
options.progress = value
|
|
298
|
+
},
|
|
299
|
+
'progress-update': function progressUpdate(data) {
|
|
300
|
+
if (options.progress) {
|
|
301
|
+
log.info(
|
|
302
|
+
''
|
|
303
|
+
.concat(data.pluginName ? '['.concat(data.pluginName, '] ') : '')
|
|
304
|
+
.concat(data.percent, '% - ')
|
|
305
|
+
.concat(data.msg, '.')
|
|
306
|
+
)
|
|
307
|
+
}
|
|
308
|
+
if (isProgressSupported()) {
|
|
309
|
+
if (typeof options.progress === 'string') {
|
|
310
|
+
var progress = document.querySelector('wds-progress')
|
|
311
|
+
if (!progress) {
|
|
312
|
+
defineProgressElement()
|
|
313
|
+
progress = document.createElement('wds-progress')
|
|
314
|
+
document.body.appendChild(progress)
|
|
315
|
+
}
|
|
316
|
+
progress.setAttribute('progress', data.percent.toString())
|
|
317
|
+
progress.setAttribute('type', options.progress)
|
|
318
|
+
}
|
|
319
|
+
}
|
|
320
|
+
sendMessage('Progress', data)
|
|
321
|
+
},
|
|
322
|
+
'still-ok': function stillOk() {
|
|
323
|
+
log.info('Nothing changed.')
|
|
324
|
+
if (options.overlay) {
|
|
325
|
+
overlay.send({ type: 'DISMISS' })
|
|
326
|
+
}
|
|
327
|
+
sendMessage('StillOk')
|
|
328
|
+
},
|
|
329
|
+
ok: function () {
|
|
330
|
+
sendMessage('Ok')
|
|
331
|
+
if (options.overlay) {
|
|
332
|
+
overlay.send({ type: 'DISMISS' })
|
|
333
|
+
}
|
|
334
|
+
reloadApp(options, status)
|
|
335
|
+
},
|
|
336
|
+
'static-changed': function staticChanged(file) {
|
|
337
|
+
log.info(
|
|
338
|
+
''.concat(
|
|
339
|
+
file ? '"'.concat(file, '"') : 'Content',
|
|
340
|
+
' from static directory was changed. Reloading...'
|
|
341
|
+
)
|
|
342
|
+
)
|
|
343
|
+
self.location.reload()
|
|
344
|
+
},
|
|
345
|
+
warnings: function (warnings, params) {
|
|
346
|
+
log.warn('Warnings while compiling.')
|
|
347
|
+
var printableWarnings = warnings.map(function (error) {
|
|
348
|
+
var _a = formatProblem('warning', error),
|
|
349
|
+
header = _a.header,
|
|
350
|
+
body = _a.body
|
|
351
|
+
return ''.concat(header, '\n').concat(stripAnsi(body))
|
|
352
|
+
})
|
|
353
|
+
sendMessage('Warnings', printableWarnings)
|
|
354
|
+
for (var i = 0; i < printableWarnings.length; i++) {
|
|
355
|
+
log.warn(printableWarnings[i])
|
|
356
|
+
}
|
|
357
|
+
var overlayWarningsSetting =
|
|
358
|
+
typeof options.overlay === 'boolean'
|
|
359
|
+
? options.overlay
|
|
360
|
+
: options.overlay && options.overlay.warnings
|
|
361
|
+
if (overlayWarningsSetting) {
|
|
362
|
+
var warningsToDisplay =
|
|
363
|
+
typeof overlayWarningsSetting === 'function'
|
|
364
|
+
? warnings.filter(overlayWarningsSetting)
|
|
365
|
+
: warnings
|
|
366
|
+
if (warningsToDisplay.length) {
|
|
367
|
+
overlay.send({
|
|
368
|
+
type: 'BUILD_ERROR',
|
|
369
|
+
level: 'warning',
|
|
370
|
+
messages: warnings,
|
|
371
|
+
})
|
|
372
|
+
}
|
|
373
|
+
}
|
|
374
|
+
if (params && params.preventReloading) {
|
|
375
|
+
return
|
|
376
|
+
}
|
|
377
|
+
reloadApp(options, status)
|
|
378
|
+
},
|
|
379
|
+
errors: function (errors) {
|
|
380
|
+
log.error('Errors while compiling. Reload prevented.')
|
|
381
|
+
var printableErrors = errors.map(function (error) {
|
|
382
|
+
var _a = formatProblem('error', error),
|
|
383
|
+
header = _a.header,
|
|
384
|
+
body = _a.body
|
|
385
|
+
return ''.concat(header, '\n').concat(stripAnsi(body))
|
|
386
|
+
})
|
|
387
|
+
sendMessage('Errors', printableErrors)
|
|
388
|
+
for (var i = 0; i < printableErrors.length; i++) {
|
|
389
|
+
log.error(printableErrors[i])
|
|
390
|
+
}
|
|
391
|
+
var overlayErrorsSettings =
|
|
392
|
+
typeof options.overlay === 'boolean'
|
|
393
|
+
? options.overlay
|
|
394
|
+
: options.overlay && options.overlay.errors
|
|
395
|
+
if (overlayErrorsSettings) {
|
|
396
|
+
var errorsToDisplay =
|
|
397
|
+
typeof overlayErrorsSettings === 'function' ? errors.filter(overlayErrorsSettings) : errors
|
|
398
|
+
if (errorsToDisplay.length) {
|
|
399
|
+
overlay.send({
|
|
400
|
+
type: 'BUILD_ERROR',
|
|
401
|
+
level: 'error',
|
|
402
|
+
messages: errors,
|
|
403
|
+
})
|
|
404
|
+
}
|
|
405
|
+
}
|
|
406
|
+
},
|
|
407
|
+
error: function (error) {
|
|
408
|
+
log.error(error)
|
|
409
|
+
},
|
|
410
|
+
close: function () {
|
|
411
|
+
log.info('Disconnected!')
|
|
412
|
+
if (options.overlay) {
|
|
413
|
+
overlay.send({ type: 'DISMISS' })
|
|
414
|
+
}
|
|
415
|
+
sendMessage('Close')
|
|
416
|
+
},
|
|
417
|
+
}
|
|
418
|
+
var formatURL = function (objURL) {
|
|
419
|
+
var protocol = objURL.protocol || ''
|
|
420
|
+
if (protocol && protocol.substr(-1) !== ':') {
|
|
421
|
+
protocol += ':'
|
|
422
|
+
}
|
|
423
|
+
var auth = objURL.auth || ''
|
|
424
|
+
if (auth) {
|
|
425
|
+
auth = encodeURIComponent(auth)
|
|
426
|
+
auth = auth.replace(/%3A/i, ':')
|
|
427
|
+
auth += '@'
|
|
428
|
+
}
|
|
429
|
+
var host = ''
|
|
430
|
+
if (objURL.hostname) {
|
|
431
|
+
host =
|
|
432
|
+
auth +
|
|
433
|
+
(objURL.hostname.indexOf(':') === -1 ? objURL.hostname : '['.concat(objURL.hostname, ']'))
|
|
434
|
+
if (objURL.port) {
|
|
435
|
+
host += ':'.concat(objURL.port)
|
|
436
|
+
}
|
|
437
|
+
}
|
|
438
|
+
var pathname = objURL.pathname || ''
|
|
439
|
+
if (objURL.slashes) {
|
|
440
|
+
host = '//'.concat(host || '')
|
|
441
|
+
if (pathname && pathname.charAt(0) !== '/') {
|
|
442
|
+
pathname = '/'.concat(pathname)
|
|
443
|
+
}
|
|
444
|
+
} else if (!host) {
|
|
445
|
+
host = ''
|
|
446
|
+
}
|
|
447
|
+
var search = objURL.search || ''
|
|
448
|
+
if (search && search.charAt(0) !== '?') {
|
|
449
|
+
search = '?'.concat(search)
|
|
450
|
+
}
|
|
451
|
+
var hash = objURL.hash || ''
|
|
452
|
+
if (hash && hash.charAt(0) !== '#') {
|
|
453
|
+
hash = '#'.concat(hash)
|
|
454
|
+
}
|
|
455
|
+
pathname = pathname.replace(/[?#]/g, function (match) {
|
|
456
|
+
return encodeURIComponent(match)
|
|
457
|
+
})
|
|
458
|
+
search = search.replace('#', '%23')
|
|
459
|
+
return ''.concat(protocol).concat(host).concat(pathname).concat(search).concat(hash)
|
|
460
|
+
}
|
|
461
|
+
var createSocketURL = function (parsedURL) {
|
|
462
|
+
var hostname = parsedURL.hostname
|
|
463
|
+
// Node.js module parses it as `::`
|
|
464
|
+
// `new URL(urlString, [baseURLString])` parses it as '[::]'
|
|
465
|
+
var isInAddrAny = hostname === '0.0.0.0' || hostname === '::' || hostname === '[::]'
|
|
466
|
+
// why do we need this check?
|
|
467
|
+
// hostname n/a for file protocol (example, when using electron, ionic)
|
|
468
|
+
// see: https://github.com/webpack/webpack-dev-server/pull/384
|
|
469
|
+
if (isInAddrAny && self.location.hostname && self.location.protocol.indexOf('http') === 0) {
|
|
470
|
+
hostname = self.location.hostname
|
|
471
|
+
}
|
|
472
|
+
var socketURLProtocol = parsedURL.protocol || self.location.protocol
|
|
473
|
+
// When https is used in the app, secure web sockets are always necessary because the browser doesn't accept non-secure web sockets.
|
|
474
|
+
if (
|
|
475
|
+
socketURLProtocol === 'auto:' ||
|
|
476
|
+
(hostname && isInAddrAny && self.location.protocol === 'https:')
|
|
477
|
+
) {
|
|
478
|
+
socketURLProtocol = self.location.protocol
|
|
479
|
+
}
|
|
480
|
+
socketURLProtocol = socketURLProtocol.replace(/^(?:http|.+-extension|file)/i, 'ws')
|
|
481
|
+
var socketURLAuth = ''
|
|
482
|
+
// `new URL(urlString, [baseURLstring])` doesn't have `auth` property
|
|
483
|
+
// Parse authentication credentials in case we need them
|
|
484
|
+
if (parsedURL.username) {
|
|
485
|
+
socketURLAuth = parsedURL.username
|
|
486
|
+
// Since HTTP basic authentication does not allow empty username,
|
|
487
|
+
// we only include password if the username is not empty.
|
|
488
|
+
if (parsedURL.password) {
|
|
489
|
+
// Result: <username>:<password>
|
|
490
|
+
socketURLAuth = socketURLAuth.concat(':', parsedURL.password)
|
|
491
|
+
}
|
|
492
|
+
}
|
|
493
|
+
// In case the host is a raw IPv6 address, it can be enclosed in
|
|
494
|
+
// the brackets as the brackets are needed in the final URL string.
|
|
495
|
+
// Need to remove those as url.format blindly adds its own set of brackets
|
|
496
|
+
// if the host string contains colons. That would lead to non-working
|
|
497
|
+
// double brackets (e.g. [[::]]) host
|
|
498
|
+
//
|
|
499
|
+
// All of these web socket url params are optionally passed in through resourceQuery,
|
|
500
|
+
// so we need to fall back to the default if they are not provided
|
|
501
|
+
var socketURLHostname = (hostname || self.location.hostname || 'localhost').replace(
|
|
502
|
+
/^\[(.*)\]$/,
|
|
503
|
+
'$1'
|
|
504
|
+
)
|
|
505
|
+
var socketURLPort = parsedURL.port
|
|
506
|
+
if (!socketURLPort || socketURLPort === '0') {
|
|
507
|
+
socketURLPort = self.location.port
|
|
508
|
+
}
|
|
509
|
+
// If path is provided it'll be passed in via the resourceQuery as a
|
|
510
|
+
// query param so it has to be parsed out of the querystring in order for the
|
|
511
|
+
// client to open the socket to the correct location.
|
|
512
|
+
var socketURLPathname = '/ws'
|
|
513
|
+
if (parsedURL.pathname && !parsedURL.fromCurrentScript) {
|
|
514
|
+
socketURLPathname = parsedURL.pathname
|
|
515
|
+
|
|
516
|
+
if (hostname.indexOf('zhidianbao.cn') > -1 || hostname.indexOf('qsban.cn') > -1) {
|
|
517
|
+
var ctx = self.location.pathname.split('/')[1]
|
|
518
|
+
if (ctx) {
|
|
519
|
+
socketURLPathname = '/' + ctx + socketURLPathname
|
|
520
|
+
}
|
|
521
|
+
}
|
|
522
|
+
}
|
|
523
|
+
return formatURL({
|
|
524
|
+
protocol: socketURLProtocol,
|
|
525
|
+
auth: socketURLAuth,
|
|
526
|
+
hostname: socketURLHostname,
|
|
527
|
+
port: socketURLPort,
|
|
528
|
+
pathname: socketURLPathname,
|
|
529
|
+
slashes: true,
|
|
530
|
+
})
|
|
531
|
+
}
|
|
532
|
+
var socketURL = createSocketURL(parsedResourceQuery)
|
|
533
|
+
socket(socketURL, onSocketMessage, options.reconnect)
|
|
534
|
+
export { getCurrentScriptSource, parseURL, createSocketURL }
|
package/dist/cli.mjs
CHANGED
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
2
|
import { createRequire } from "node:module";
|
|
3
|
+
import "@swc-node/register/esm-register";
|
|
3
4
|
import fs from "fs-extra";
|
|
4
5
|
import path from "path";
|
|
5
6
|
import { globby, globbySync } from "globby";
|
|
@@ -58,9 +59,8 @@ const paths = {
|
|
|
58
59
|
jsconfig: resolveApp("jsconfig.json"),
|
|
59
60
|
package: resolveApp("package.json"),
|
|
60
61
|
tailwind: resolveApp("tailwind.config.js"),
|
|
61
|
-
indexJS: resolveApp("src", "index.js"),
|
|
62
62
|
pages: resolveApp("src", "pages"),
|
|
63
|
-
override: resolveApp("edu-scripts.override.js"),
|
|
63
|
+
override: getExistPath(resolveApp("edu-scripts.override.js"), resolveApp("edu-scripts.override.ts")),
|
|
64
64
|
indexHTML: globbySync("./public/*.html", { absolute: true }),
|
|
65
65
|
src: resolveApp("src"),
|
|
66
66
|
public: resolveApp("public"),
|
|
@@ -453,8 +453,9 @@ function getWebpackConfig(args, override) {
|
|
|
453
453
|
].filter(Boolean) }] },
|
|
454
454
|
plugins: [
|
|
455
455
|
qseCDN.isUseCommon && new rspack.DllReferencePlugin({ manifest: fs.readJsonSync(paths.resolveOwn("asset", "dll", "libcommon3-manifest.json")) }),
|
|
456
|
-
new rspack.NormalModuleReplacementPlugin(
|
|
457
|
-
|
|
456
|
+
new rspack.NormalModuleReplacementPlugin(/@rspack\/dev-server\/client\/index\.js/, (resource) => {
|
|
457
|
+
const myClientPath = paths.resolveOwn("asset", "rspack-dev-server-client.js");
|
|
458
|
+
resource.request = resource.request.replace(/.*dev-server\/client\/index\.js/, myClientPath);
|
|
458
459
|
}),
|
|
459
460
|
new rspack.IgnorePlugin({
|
|
460
461
|
resourceRegExp: /^\.\/locale$/,
|
|
@@ -533,7 +534,6 @@ function getWebpackConfig(args, override) {
|
|
|
533
534
|
//#endregion
|
|
534
535
|
//#region src/config/plugins/mock-server/index.ts
|
|
535
536
|
const require$1 = createRequire(import.meta.url);
|
|
536
|
-
const { register } = require$1("@swc-node/register/register");
|
|
537
537
|
let mockCache = {};
|
|
538
538
|
let isSetup = false;
|
|
539
539
|
const setupMock = debounce(function setupMock() {
|
|
@@ -628,7 +628,6 @@ const mockMiddlewave = function mockMiddlewave(req, res, next) {
|
|
|
628
628
|
};
|
|
629
629
|
function setupMockServer(middelwaves, _devServer) {
|
|
630
630
|
if (!fs.existsSync(paths.mock)) return;
|
|
631
|
-
register();
|
|
632
631
|
middelwaves.unshift({
|
|
633
632
|
name: "edu-scripts-mock-middelwave",
|
|
634
633
|
middleware: mockMiddlewave
|
|
@@ -742,6 +741,7 @@ async function start(args) {
|
|
|
742
741
|
process.env.BABEL_ENV = "development";
|
|
743
742
|
process.env.BROWSERSLIST = "chrome >= 70";
|
|
744
743
|
process.env.WEBPACK_DEV_SERVER_BASE_PORT = "3000";
|
|
744
|
+
process.env.BROWSERSLIST_IGNORE_OLD_DATA = "true";
|
|
745
745
|
const basePort = process.env.WEBPACK_DEV_SERVER_BASE_PORT;
|
|
746
746
|
const port = await RspackDevServer.getFreePort(args.port || process.env.PORT);
|
|
747
747
|
if (!(args.port || process.env.PORT) && +port !== +basePort) console.log(chalk.bgYellow(`${basePort} 端口已被占用,现切换到 ${port} 端口运行`));
|
|
@@ -865,6 +865,7 @@ async function build(args) {
|
|
|
865
865
|
process.env.NODE_ENV = "production";
|
|
866
866
|
process.env.BABEL_ENV = "production";
|
|
867
867
|
process.env.BROWSERSLIST = ">0.2%, iOS>=9, ie 11, chrome>=49, not op_mini all";
|
|
868
|
+
process.env.BROWSERSLIST_IGNORE_OLD_DATA = "true";
|
|
868
869
|
if (args.analyze) process.env.ANALYZE = "1";
|
|
869
870
|
if (args.outputHtml) process.env.OUTPUT_HTML = "1";
|
|
870
871
|
const previousSizeMap = await measureFileSizesBeforeBuild(paths.dist);
|
|
@@ -1034,7 +1035,7 @@ async function normalDeploy(args) {
|
|
|
1034
1035
|
try {
|
|
1035
1036
|
await sftp.fastGet(remoteLogFile, tmpLogFile);
|
|
1036
1037
|
content = await fs.readFile(tmpLogFile, "utf-8");
|
|
1037
|
-
} catch
|
|
1038
|
+
} catch {}
|
|
1038
1039
|
content = updateLogContent(content, info);
|
|
1039
1040
|
await fs.writeFile(tmpLogFile, content);
|
|
1040
1041
|
await sftp.fastPut(tmpLogFile, remoteLogFile);
|
|
@@ -1302,7 +1303,7 @@ function copyDistToRepo(info) {
|
|
|
1302
1303
|
exec(`svn co ${info.distBranchDirURL} ${tmpdir}`);
|
|
1303
1304
|
try {
|
|
1304
1305
|
exec(`svn rm * --force -q`, { cwd: tmpdir });
|
|
1305
|
-
} catch
|
|
1306
|
+
} catch {}
|
|
1306
1307
|
fs.copySync(paths.dist, tmpdir);
|
|
1307
1308
|
exec(`svn add * --force --auto-props --parents --depth infinity -q`, { cwd: tmpdir });
|
|
1308
1309
|
exec(`svn ci -m "${`[edu-scripts] commit ${info.branch} dist #${info.revision} @${info.author}`}"`, { cwd: tmpdir });
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@qse/edu-scripts",
|
|
3
|
-
"version": "0.0.0-beta.
|
|
3
|
+
"version": "0.0.0-beta.7",
|
|
4
4
|
"author": "Kinoko",
|
|
5
5
|
"license": "MIT",
|
|
6
6
|
"type": "module",
|
|
@@ -35,7 +35,7 @@
|
|
|
35
35
|
"typings": "dist/index.d.mts",
|
|
36
36
|
"dependencies": {
|
|
37
37
|
"@babel/core": "~7.29.0",
|
|
38
|
-
"@qse/ssh-sftp": "^1.
|
|
38
|
+
"@qse/ssh-sftp": "^1.3.0",
|
|
39
39
|
"@rsdoctor/rspack-plugin": "^1.5.2",
|
|
40
40
|
"@rspack/core": "^1.7.6",
|
|
41
41
|
"@rspack/dev-server": "^1.2.1",
|
package/src/build.ts
CHANGED
|
@@ -18,6 +18,7 @@ export default async function build(args: BuildArgs) {
|
|
|
18
18
|
process.env.NODE_ENV = 'production'
|
|
19
19
|
process.env.BABEL_ENV = 'production'
|
|
20
20
|
process.env.BROWSERSLIST = '>0.2%, iOS>=9, ie 11, chrome>=49, not op_mini all'
|
|
21
|
+
process.env.BROWSERSLIST_IGNORE_OLD_DATA = 'true'
|
|
21
22
|
|
|
22
23
|
if (args.analyze) {
|
|
23
24
|
process.env.ANALYZE = '1'
|
package/src/cli.ts
CHANGED
package/src/commit-dist.ts
CHANGED
|
@@ -61,10 +61,7 @@ function copyDistToRepo(info: WorkingCopyInfo) {
|
|
|
61
61
|
|
|
62
62
|
try {
|
|
63
63
|
exec(`svn rm * --force -q`, { cwd: tmpdir })
|
|
64
|
-
} catch
|
|
65
|
-
// 如果目录为空,svn rm 会报错,忽略即可
|
|
66
|
-
}
|
|
67
|
-
|
|
64
|
+
} catch {}
|
|
68
65
|
fs.copySync(paths.dist, tmpdir)
|
|
69
66
|
|
|
70
67
|
exec(`svn add * --force --auto-props --parents --depth infinity -q`, { cwd: tmpdir })
|
package/src/config/paths.ts
CHANGED
|
@@ -40,9 +40,8 @@ const paths = {
|
|
|
40
40
|
jsconfig: resolveApp('jsconfig.json'),
|
|
41
41
|
package: resolveApp('package.json'),
|
|
42
42
|
tailwind: resolveApp('tailwind.config.js'),
|
|
43
|
-
indexJS: resolveApp('src', 'index.js'),
|
|
44
43
|
pages: resolveApp('src', 'pages'),
|
|
45
|
-
override: resolveApp('edu-scripts.override.js'),
|
|
44
|
+
override: getExistPath(resolveApp('edu-scripts.override.js'), resolveApp('edu-scripts.override.ts')),
|
|
46
45
|
indexHTML: globbySync('./public/*.html', { absolute: true }),
|
|
47
46
|
src: resolveApp('src'),
|
|
48
47
|
public: resolveApp('public'),
|
|
@@ -11,7 +11,6 @@ import { pathToRegexp, type Key } from 'path-to-regexp'
|
|
|
11
11
|
import { createRequire } from 'node:module'
|
|
12
12
|
import { resolveModule } from '@/utils/resolveModule'
|
|
13
13
|
const require = createRequire(import.meta.url)
|
|
14
|
-
const { register } = require('@swc-node/register/register')
|
|
15
14
|
|
|
16
15
|
let mockCache: Record<string, { handler: any; method: string; path: string }> = {}
|
|
17
16
|
let isSetup = false
|
|
@@ -129,8 +128,6 @@ type Middlewares = Parameters<
|
|
|
129
128
|
function setupMockServer(middelwaves: Middlewares, _devServer: any) {
|
|
130
129
|
if (!fs.existsSync(paths.mock)) return
|
|
131
130
|
|
|
132
|
-
register()
|
|
133
|
-
|
|
134
131
|
middelwaves.unshift({
|
|
135
132
|
name: 'edu-scripts-mock-middelwave',
|
|
136
133
|
middleware: mockMiddlewave as any,
|
|
@@ -398,11 +398,13 @@ export default function getWebpackConfig(args: any, override: CustomConfiguratio
|
|
|
398
398
|
new rspack.DllReferencePlugin({
|
|
399
399
|
manifest: fs.readJsonSync(paths.resolveOwn('asset', 'dll', 'libcommon3-manifest.json')),
|
|
400
400
|
}),
|
|
401
|
-
new rspack.NormalModuleReplacementPlugin(
|
|
402
|
-
|
|
403
|
-
|
|
401
|
+
new rspack.NormalModuleReplacementPlugin(
|
|
402
|
+
/@rspack\/dev-server\/client\/index\.js/,
|
|
403
|
+
(resource) => {
|
|
404
|
+
const myClientPath = paths.resolveOwn('asset', 'rspack-dev-server-client.js')
|
|
405
|
+
resource.request = resource.request.replace(/.*dev-server\/client\/index\.js/, myClientPath)
|
|
404
406
|
}
|
|
405
|
-
|
|
407
|
+
),
|
|
406
408
|
new rspack.IgnorePlugin({
|
|
407
409
|
resourceRegExp: /^\.\/locale$/,
|
|
408
410
|
contextRegExp: /moment$/,
|
package/src/deploy.ts
CHANGED
|
@@ -96,7 +96,7 @@ async function normalDeploy(args: DeployArgs) {
|
|
|
96
96
|
try {
|
|
97
97
|
await sftp.fastGet(remoteLogFile, tmpLogFile)
|
|
98
98
|
content = await fs.readFile(tmpLogFile, 'utf-8')
|
|
99
|
-
} catch
|
|
99
|
+
} catch {}
|
|
100
100
|
content = updateLogContent(content, info)
|
|
101
101
|
await fs.writeFile(tmpLogFile, content)
|
|
102
102
|
await sftp.fastPut(tmpLogFile, remoteLogFile)
|
package/src/start.ts
CHANGED
|
@@ -11,6 +11,7 @@ export default async function start(args: StartArgs) {
|
|
|
11
11
|
process.env.BABEL_ENV = 'development'
|
|
12
12
|
process.env.BROWSERSLIST = 'chrome >= 70'
|
|
13
13
|
process.env.WEBPACK_DEV_SERVER_BASE_PORT = '3000'
|
|
14
|
+
process.env.BROWSERSLIST_IGNORE_OLD_DATA = 'true'
|
|
14
15
|
|
|
15
16
|
const basePort = process.env.WEBPACK_DEV_SERVER_BASE_PORT
|
|
16
17
|
// @ts-ignore
|
|
@@ -24,15 +25,15 @@ export default async function start(args: StartArgs) {
|
|
|
24
25
|
const config = getConfig(args)
|
|
25
26
|
const compiler = rspack(config)
|
|
26
27
|
const middleware = rspack.lazyCompilationMiddleware(compiler)
|
|
27
|
-
const oldSetupMiddlewares = config.devServer
|
|
28
|
-
config.devServer
|
|
28
|
+
const oldSetupMiddlewares = config.devServer!.setupMiddlewares
|
|
29
|
+
config.devServer!.setupMiddlewares = (middlewares: any, devServer: any) => {
|
|
29
30
|
if (oldSetupMiddlewares) {
|
|
30
31
|
middlewares = oldSetupMiddlewares(middlewares, devServer)
|
|
31
32
|
}
|
|
32
33
|
middlewares.unshift(middleware)
|
|
33
34
|
return middlewares
|
|
34
35
|
}
|
|
35
|
-
const devServer = new RspackDevServer(config.devServer
|
|
36
|
+
const devServer = new RspackDevServer(config.devServer!, compiler)
|
|
36
37
|
devServer.start()
|
|
37
38
|
;['SIGINT', 'SIGTERM'].forEach(function (sig) {
|
|
38
39
|
process.on(sig, function () {
|
|
@@ -13,17 +13,15 @@ import filesize from 'filesize'
|
|
|
13
13
|
import recursive from 'recursive-readdir'
|
|
14
14
|
import stripAnsi from 'strip-ansi'
|
|
15
15
|
import { gzipSizeSync } from 'gzip-size'
|
|
16
|
+
import type { Stats } from '@rspack/core'
|
|
16
17
|
|
|
17
18
|
interface SizeMap {
|
|
18
19
|
root: string
|
|
19
20
|
sizes: Record<string, number>
|
|
20
21
|
}
|
|
21
22
|
|
|
22
|
-
interface WebpackStats {
|
|
23
|
-
stats?:
|
|
24
|
-
toJson: (options: { all: boolean; assets: boolean }) => {
|
|
25
|
-
assets: Array<{ name: string }>
|
|
26
|
-
}
|
|
23
|
+
interface WebpackStats extends Stats {
|
|
24
|
+
stats?: Stats[]
|
|
27
25
|
}
|
|
28
26
|
|
|
29
27
|
function canReadAsset(asset: string): boolean {
|
|
@@ -48,7 +46,7 @@ function printFileSizesAfterBuild(
|
|
|
48
46
|
.map((stats) =>
|
|
49
47
|
stats
|
|
50
48
|
.toJson({ all: false, assets: true })
|
|
51
|
-
.assets
|
|
49
|
+
.assets!.filter((asset) => canReadAsset(asset.name))
|
|
52
50
|
.map((asset) => {
|
|
53
51
|
const fileContents = fs.readFileSync(path.join(root, asset.name))
|
|
54
52
|
const size = gzipSizeSync(fileContents)
|
|
@@ -143,12 +141,15 @@ function measureFileSizesBeforeBuild(buildFolder: string): Promise<SizeMap> {
|
|
|
143
141
|
recursive(buildFolder, (err: any, fileNames: any) => {
|
|
144
142
|
let sizes: Record<string, number> | undefined
|
|
145
143
|
if (!err && fileNames) {
|
|
146
|
-
sizes = fileNames.filter(canReadAsset).reduce(
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
144
|
+
sizes = fileNames.filter(canReadAsset).reduce(
|
|
145
|
+
(memo: any, fileName: any) => {
|
|
146
|
+
const contents = fs.readFileSync(fileName)
|
|
147
|
+
const key = removeFileNameHash(buildFolder, fileName)
|
|
148
|
+
memo[key] = gzipSizeSync(contents)
|
|
149
|
+
return memo
|
|
150
|
+
},
|
|
151
|
+
{} as Record<string, number>
|
|
152
|
+
)
|
|
152
153
|
}
|
|
153
154
|
resolve({
|
|
154
155
|
root: buildFolder,
|
|
@@ -1,140 +0,0 @@
|
|
|
1
|
-
/* eslint-disable no-restricted-globals */
|
|
2
|
-
|
|
3
|
-
/**
|
|
4
|
-
* @param {{ protocol?: string, auth?: string, hostname?: string, port?: string, pathname?: string, search?: string, hash?: string, slashes?: boolean }} objURL
|
|
5
|
-
* @returns {string}
|
|
6
|
-
*/
|
|
7
|
-
function format(objURL) {
|
|
8
|
-
var protocol = objURL.protocol || ''
|
|
9
|
-
if (protocol && protocol.substr(-1) !== ':') {
|
|
10
|
-
protocol += ':'
|
|
11
|
-
}
|
|
12
|
-
var auth = objURL.auth || ''
|
|
13
|
-
if (auth) {
|
|
14
|
-
auth = encodeURIComponent(auth)
|
|
15
|
-
auth = auth.replace(/%3A/i, ':')
|
|
16
|
-
auth += '@'
|
|
17
|
-
}
|
|
18
|
-
var host = ''
|
|
19
|
-
if (objURL.hostname) {
|
|
20
|
-
host =
|
|
21
|
-
auth +
|
|
22
|
-
(objURL.hostname.indexOf(':') === -1 ? objURL.hostname : '['.concat(objURL.hostname, ']'))
|
|
23
|
-
if (objURL.port) {
|
|
24
|
-
host += ':'.concat(objURL.port)
|
|
25
|
-
}
|
|
26
|
-
}
|
|
27
|
-
var pathname = objURL.pathname || ''
|
|
28
|
-
if (objURL.slashes) {
|
|
29
|
-
host = '//'.concat(host || '')
|
|
30
|
-
if (pathname && pathname.charAt(0) !== '/') {
|
|
31
|
-
pathname = '/'.concat(pathname)
|
|
32
|
-
}
|
|
33
|
-
} else if (!host) {
|
|
34
|
-
host = ''
|
|
35
|
-
}
|
|
36
|
-
var search = objURL.search || ''
|
|
37
|
-
if (search && search.charAt(0) !== '?') {
|
|
38
|
-
search = '?'.concat(search)
|
|
39
|
-
}
|
|
40
|
-
var hash = objURL.hash || ''
|
|
41
|
-
if (hash && hash.charAt(0) !== '#') {
|
|
42
|
-
hash = '#'.concat(hash)
|
|
43
|
-
}
|
|
44
|
-
pathname = pathname.replace(
|
|
45
|
-
/[?#]/g,
|
|
46
|
-
/**
|
|
47
|
-
* @param {string} match
|
|
48
|
-
* @returns {string}
|
|
49
|
-
*/
|
|
50
|
-
function (match) {
|
|
51
|
-
return encodeURIComponent(match)
|
|
52
|
-
}
|
|
53
|
-
)
|
|
54
|
-
search = search.replace('#', '%23')
|
|
55
|
-
return ''.concat(protocol).concat(host).concat(pathname).concat(search).concat(hash)
|
|
56
|
-
}
|
|
57
|
-
|
|
58
|
-
/**
|
|
59
|
-
* @param {URL & { fromCurrentScript?: boolean }} parsedURL
|
|
60
|
-
* @returns {string}
|
|
61
|
-
*/
|
|
62
|
-
function createSocketURL(parsedURL) {
|
|
63
|
-
var hostname = parsedURL.hostname
|
|
64
|
-
|
|
65
|
-
// Node.js module parses it as `::`
|
|
66
|
-
// `new URL(urlString, [baseURLString])` parses it as '[::]'
|
|
67
|
-
var isInAddrAny = hostname === '0.0.0.0' || hostname === '::' || hostname === '[::]'
|
|
68
|
-
|
|
69
|
-
// why do we need this check?
|
|
70
|
-
// hostname n/a for file protocol (example, when using electron, ionic)
|
|
71
|
-
// see: https://github.com/webpack/webpack-dev-server/pull/384
|
|
72
|
-
if (isInAddrAny && self.location.hostname && self.location.protocol.indexOf('http') === 0) {
|
|
73
|
-
hostname = self.location.hostname
|
|
74
|
-
}
|
|
75
|
-
var socketURLProtocol = parsedURL.protocol || self.location.protocol
|
|
76
|
-
|
|
77
|
-
// When https is used in the app, secure web sockets are always necessary because the browser doesn't accept non-secure web sockets.
|
|
78
|
-
if (
|
|
79
|
-
socketURLProtocol === 'auto:' ||
|
|
80
|
-
(hostname && isInAddrAny && self.location.protocol === 'https:')
|
|
81
|
-
) {
|
|
82
|
-
socketURLProtocol = self.location.protocol
|
|
83
|
-
}
|
|
84
|
-
socketURLProtocol = socketURLProtocol.replace(/^(?:http|.+-extension|file)/i, 'ws')
|
|
85
|
-
var socketURLAuth = ''
|
|
86
|
-
|
|
87
|
-
// `new URL(urlString, [baseURLstring])` doesn't have `auth` property
|
|
88
|
-
// Parse authentication credentials in case we need them
|
|
89
|
-
if (parsedURL.username) {
|
|
90
|
-
socketURLAuth = parsedURL.username
|
|
91
|
-
|
|
92
|
-
// Since HTTP basic authentication does not allow empty username,
|
|
93
|
-
// we only include password if the username is not empty.
|
|
94
|
-
if (parsedURL.password) {
|
|
95
|
-
// Result: <username>:<password>
|
|
96
|
-
socketURLAuth = socketURLAuth.concat(':', parsedURL.password)
|
|
97
|
-
}
|
|
98
|
-
}
|
|
99
|
-
|
|
100
|
-
// In case the host is a raw IPv6 address, it can be enclosed in
|
|
101
|
-
// the brackets as the brackets are needed in the final URL string.
|
|
102
|
-
// Need to remove those as url.format blindly adds its own set of brackets
|
|
103
|
-
// if the host string contains colons. That would lead to non-working
|
|
104
|
-
// double brackets (e.g. [[::]]) host
|
|
105
|
-
//
|
|
106
|
-
// All of these web socket url params are optionally passed in through resourceQuery,
|
|
107
|
-
// so we need to fall back to the default if they are not provided
|
|
108
|
-
var socketURLHostname = (hostname || self.location.hostname || 'localhost').replace(
|
|
109
|
-
/^\[(.*)\]$/,
|
|
110
|
-
'$1'
|
|
111
|
-
)
|
|
112
|
-
var socketURLPort = parsedURL.port
|
|
113
|
-
if (!socketURLPort || socketURLPort === '0') {
|
|
114
|
-
socketURLPort = self.location.port
|
|
115
|
-
}
|
|
116
|
-
|
|
117
|
-
// If path is provided it'll be passed in via the resourceQuery as a
|
|
118
|
-
// query param so it has to be parsed out of the querystring in order for the
|
|
119
|
-
// client to open the socket to the correct location.
|
|
120
|
-
var socketURLPathname = '/ws'
|
|
121
|
-
if (parsedURL.pathname && !parsedURL.fromCurrentScript) {
|
|
122
|
-
socketURLPathname = parsedURL.pathname
|
|
123
|
-
|
|
124
|
-
if (hostname.indexOf('zhidianbao.cn') > -1 || hostname.indexOf('qsban.cn') > -1) {
|
|
125
|
-
var ctx = self.location.pathname.split('/')[1]
|
|
126
|
-
if (ctx) {
|
|
127
|
-
socketURLPathname = '/' + ctx + socketURLPathname
|
|
128
|
-
}
|
|
129
|
-
}
|
|
130
|
-
}
|
|
131
|
-
return format({
|
|
132
|
-
protocol: socketURLProtocol,
|
|
133
|
-
auth: socketURLAuth,
|
|
134
|
-
hostname: socketURLHostname,
|
|
135
|
-
port: socketURLPort,
|
|
136
|
-
pathname: socketURLPathname,
|
|
137
|
-
slashes: true,
|
|
138
|
-
})
|
|
139
|
-
}
|
|
140
|
-
export default createSocketURL
|