xhs-mp-compiler-cli 1.3.4 → 1.4.0-beta.1
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/dist/compiler.d.ts +15 -11
- package/dist/compiler.js +96 -40
- package/dist/compilerImpl.d.ts +1 -0
- package/dist/{compilerCP.js → compilerImpl.js} +29 -42
- package/dist/compilerImplChildProcess.js +33 -0
- package/dist/compilerImplThreadWorker.d.ts +1 -0
- package/dist/compilerImplThreadWorker.js +30 -0
- package/dist/compilerImplWebWorker.d.ts +6 -0
- package/dist/compilerImplWebWorker.js +25 -0
- package/dist/dev-server/compatibleAPI.d.ts +25 -0
- package/dist/dev-server/compatibleAPI.js +56 -0
- package/dist/dev-server/escapeHtml.d.ts +5 -0
- package/dist/dev-server/escapeHtml.js +50 -0
- package/dist/dev-server/etag.d.ts +10 -0
- package/dist/dev-server/etag.js +69 -0
- package/dist/dev-server/getFilenameFromUrl.d.ts +9 -0
- package/dist/dev-server/getFilenameFromUrl.js +102 -0
- package/dist/dev-server/getPaths.d.ts +6 -0
- package/dist/dev-server/getPaths.js +20 -0
- package/dist/dev-server/index.d.ts +98 -0
- package/dist/dev-server/index.js +90 -0
- package/dist/dev-server/memorize.d.ts +7 -0
- package/dist/dev-server/memorize.js +23 -0
- package/dist/dev-server/middleware.d.ts +2 -0
- package/dist/dev-server/middleware.js +477 -0
- package/dist/dev-server/ready.d.ts +4 -0
- package/dist/dev-server/ready.js +11 -0
- package/dist/index.d.ts +3 -3
- package/dist/index.js +5 -5
- package/dist/packs/mp-pack/index.js +0 -1
- package/dist/packs/webpack/dev-server/index.js +1 -0
- package/dist/packs/webpack/index.d.ts +1 -1
- package/dist/packs/webpack/index.js +3 -4
- package/dist/packs/webpack/webpack.d.ts +1 -1
- package/dist/packs/webpack/webpack.js +6 -2
- package/dist/presets/configs/miniprogram/render/index.d.ts +2 -3
- package/dist/presets/configs/miniprogram/render/index.js +2 -2
- package/dist/presets/configs/miniprogram/service/index.js +1 -0
- package/dist/sharedFs.d.ts +2 -0
- package/dist/sharedFs.js +4 -0
- package/dist/utils/workerPool.d.ts +29 -0
- package/dist/utils/workerPool.js +115 -0
- package/package.json +26 -12
- /package/dist/{compilerCP.d.ts → compilerImplChildProcess.d.ts} +0 -0
|
@@ -0,0 +1,477 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
|
|
3
|
+
function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
|
|
4
|
+
return new (P || (P = Promise))(function (resolve, reject) {
|
|
5
|
+
function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
|
|
6
|
+
function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
|
|
7
|
+
function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
|
|
8
|
+
step((generator = generator.apply(thisArg, _arguments || [])).next());
|
|
9
|
+
});
|
|
10
|
+
};
|
|
11
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
12
|
+
const path = require('path');
|
|
13
|
+
const mime = require('mime-types');
|
|
14
|
+
const onFinishedStream = require('on-finished');
|
|
15
|
+
const getFilenameFromUrl = require('./getFilenameFromUrl');
|
|
16
|
+
const { setStatusCode, send, pipe, createReadStreamOrReadFileSync } = require('./compatibleAPI');
|
|
17
|
+
const ready = require('./ready');
|
|
18
|
+
const parseTokenList = require('./parseTokenList');
|
|
19
|
+
const memorize = require('./memorize');
|
|
20
|
+
const BYTES_RANGE_REGEXP = /^ *bytes/i;
|
|
21
|
+
function getValueContentRangeHeader(type, size, range) {
|
|
22
|
+
return `${type} ${range ? `${range.start}-${range.end}` : '*'}/${size}`;
|
|
23
|
+
}
|
|
24
|
+
function parseHttpDate(date) {
|
|
25
|
+
const timestamp = date && Date.parse(date);
|
|
26
|
+
// istanbul ignore next: guard against date.js Date.parse patching
|
|
27
|
+
return typeof timestamp === 'number' ? timestamp : NaN;
|
|
28
|
+
}
|
|
29
|
+
const CACHE_CONTROL_NO_CACHE_REGEXP = /(?:^|,)\s*?no-cache\s*?(?:,|$)/;
|
|
30
|
+
function destroyStream(stream, suppress) {
|
|
31
|
+
if (typeof stream.destroy === 'function') {
|
|
32
|
+
stream.destroy();
|
|
33
|
+
}
|
|
34
|
+
if (typeof stream.close === 'function') {
|
|
35
|
+
// Node.js core bug workaround
|
|
36
|
+
stream.on('open', function onOpenClose() {
|
|
37
|
+
// @ts-ignore
|
|
38
|
+
if (typeof this.fd === 'number') {
|
|
39
|
+
// actually close down the fd
|
|
40
|
+
this.close();
|
|
41
|
+
}
|
|
42
|
+
});
|
|
43
|
+
}
|
|
44
|
+
if (typeof stream.addListener === 'function' && suppress) {
|
|
45
|
+
stream.removeAllListeners('error');
|
|
46
|
+
stream.addListener('error', () => { });
|
|
47
|
+
}
|
|
48
|
+
}
|
|
49
|
+
const statuses = {
|
|
50
|
+
400: 'Bad Request',
|
|
51
|
+
403: 'Forbidden',
|
|
52
|
+
404: 'Not Found',
|
|
53
|
+
416: 'Range Not Satisfiable',
|
|
54
|
+
500: 'Internal Server Error'
|
|
55
|
+
};
|
|
56
|
+
const parseRangeHeaders = memorize((value) => {
|
|
57
|
+
const [len, rangeHeader] = value.split('|');
|
|
58
|
+
// eslint-disable-next-line global-require
|
|
59
|
+
return require('range-parser')(Number(len), rangeHeader, {
|
|
60
|
+
combine: true
|
|
61
|
+
});
|
|
62
|
+
});
|
|
63
|
+
function wrapper(context) {
|
|
64
|
+
return function middleware(req, res, next) {
|
|
65
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
66
|
+
const acceptedMethods = context.options.methods || ['GET', 'HEAD'];
|
|
67
|
+
// fixes #282. credit @cexoso. in certain edge situations res.locals is undefined.
|
|
68
|
+
// eslint-disable-next-line no-param-reassign
|
|
69
|
+
res.locals = res.locals || {};
|
|
70
|
+
function goNext() {
|
|
71
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
72
|
+
if (!context.options.serverSideRender) {
|
|
73
|
+
return next();
|
|
74
|
+
}
|
|
75
|
+
return new Promise(resolve => {
|
|
76
|
+
ready(context, () => {
|
|
77
|
+
res.locals.webpack = { devMiddleware: context };
|
|
78
|
+
resolve(next());
|
|
79
|
+
}, req);
|
|
80
|
+
});
|
|
81
|
+
});
|
|
82
|
+
}
|
|
83
|
+
if (req.method && !acceptedMethods.includes(req.method)) {
|
|
84
|
+
yield goNext();
|
|
85
|
+
return;
|
|
86
|
+
}
|
|
87
|
+
function sendError(status, options) {
|
|
88
|
+
// eslint-disable-next-line global-require
|
|
89
|
+
const escapeHtml = require('./escapeHtml');
|
|
90
|
+
const content = statuses[status] || String(status);
|
|
91
|
+
let document = Buffer.from(`<!DOCTYPE html>
|
|
92
|
+
<html lang="en">
|
|
93
|
+
<head>
|
|
94
|
+
<meta charset="utf-8">
|
|
95
|
+
<title>Error</title>
|
|
96
|
+
</head>
|
|
97
|
+
<body>
|
|
98
|
+
<pre>${escapeHtml(content)}</pre>
|
|
99
|
+
</body>
|
|
100
|
+
</html>`, 'utf-8');
|
|
101
|
+
// Clear existing headers
|
|
102
|
+
const headers = res.getHeaderNames();
|
|
103
|
+
for (let i = 0; i < headers.length; i++) {
|
|
104
|
+
res.removeHeader(headers[i]);
|
|
105
|
+
}
|
|
106
|
+
if (options && options.headers) {
|
|
107
|
+
const keys = Object.keys(options.headers);
|
|
108
|
+
for (let i = 0; i < keys.length; i++) {
|
|
109
|
+
const key = keys[i];
|
|
110
|
+
const value = options.headers[key];
|
|
111
|
+
if (typeof value !== 'undefined') {
|
|
112
|
+
res.setHeader(key, value);
|
|
113
|
+
}
|
|
114
|
+
}
|
|
115
|
+
}
|
|
116
|
+
// Send basic response
|
|
117
|
+
setStatusCode(res, status);
|
|
118
|
+
res.setHeader('Content-Type', 'text/html; charset=utf-8');
|
|
119
|
+
res.setHeader('Content-Security-Policy', "default-src 'none'");
|
|
120
|
+
res.setHeader('X-Content-Type-Options', 'nosniff');
|
|
121
|
+
let byteLength = Buffer.byteLength(document);
|
|
122
|
+
if (options && options.modifyResponseData) {
|
|
123
|
+
;
|
|
124
|
+
({ data: document, byteLength } = options.modifyResponseData(req, res, document, byteLength));
|
|
125
|
+
}
|
|
126
|
+
res.setHeader('Content-Length', byteLength);
|
|
127
|
+
res.end(document);
|
|
128
|
+
}
|
|
129
|
+
function isConditionalGET() {
|
|
130
|
+
return (req.headers['if-match'] ||
|
|
131
|
+
req.headers['if-unmodified-since'] ||
|
|
132
|
+
req.headers['if-none-match'] ||
|
|
133
|
+
req.headers['if-modified-since']);
|
|
134
|
+
}
|
|
135
|
+
function isPreconditionFailure() {
|
|
136
|
+
// if-match
|
|
137
|
+
const ifMatch = req.headers['if-match'];
|
|
138
|
+
// A recipient MUST ignore If-Unmodified-Since if the request contains
|
|
139
|
+
// an If-Match header field; the condition in If-Match is considered to
|
|
140
|
+
// be a more accurate replacement for the condition in
|
|
141
|
+
// If-Unmodified-Since, and the two are only combined for the sake of
|
|
142
|
+
// interoperating with older intermediaries that might not implement If-Match.
|
|
143
|
+
if (ifMatch) {
|
|
144
|
+
const etag = res.getHeader('ETag');
|
|
145
|
+
return (!etag ||
|
|
146
|
+
(ifMatch !== '*' &&
|
|
147
|
+
parseTokenList(ifMatch).every(match => match !== etag && match !== `W/${etag}` && `W/${match}` !== etag)));
|
|
148
|
+
}
|
|
149
|
+
// if-unmodified-since
|
|
150
|
+
const ifUnmodifiedSince = req.headers['if-unmodified-since'];
|
|
151
|
+
if (ifUnmodifiedSince) {
|
|
152
|
+
const unmodifiedSince = parseHttpDate(ifUnmodifiedSince);
|
|
153
|
+
// A recipient MUST ignore the If-Unmodified-Since header field if the
|
|
154
|
+
// received field-value is not a valid HTTP-date.
|
|
155
|
+
if (!isNaN(unmodifiedSince)) {
|
|
156
|
+
const lastModified = parseHttpDate(/** @type {string} */ res.getHeader('Last-Modified'));
|
|
157
|
+
return isNaN(lastModified) || lastModified > unmodifiedSince;
|
|
158
|
+
}
|
|
159
|
+
}
|
|
160
|
+
return false;
|
|
161
|
+
}
|
|
162
|
+
function isCachable() {
|
|
163
|
+
return (res.statusCode >= 200 && res.statusCode < 300) || res.statusCode === 304;
|
|
164
|
+
}
|
|
165
|
+
function isFresh(resHeaders) {
|
|
166
|
+
// Always return stale when Cache-Control: no-cache to support end-to-end reload requests
|
|
167
|
+
// https://tools.ietf.org/html/rfc2616#section-14.9.4
|
|
168
|
+
const cacheControl = req.headers['cache-control'];
|
|
169
|
+
if (cacheControl && CACHE_CONTROL_NO_CACHE_REGEXP.test(cacheControl)) {
|
|
170
|
+
return false;
|
|
171
|
+
}
|
|
172
|
+
// fields
|
|
173
|
+
const noneMatch = req.headers['if-none-match'];
|
|
174
|
+
const modifiedSince = req.headers['if-modified-since'];
|
|
175
|
+
// unconditional request
|
|
176
|
+
if (!noneMatch && !modifiedSince) {
|
|
177
|
+
return false;
|
|
178
|
+
}
|
|
179
|
+
// if-none-match
|
|
180
|
+
if (noneMatch && noneMatch !== '*') {
|
|
181
|
+
if (!resHeaders.etag) {
|
|
182
|
+
return false;
|
|
183
|
+
}
|
|
184
|
+
const matches = parseTokenList(noneMatch);
|
|
185
|
+
let etagStale = true;
|
|
186
|
+
for (let i = 0; i < matches.length; i++) {
|
|
187
|
+
const match = matches[i];
|
|
188
|
+
if (match === resHeaders.etag ||
|
|
189
|
+
match === `W/${resHeaders.etag}` ||
|
|
190
|
+
`W/${match}` === resHeaders.etag) {
|
|
191
|
+
etagStale = false;
|
|
192
|
+
break;
|
|
193
|
+
}
|
|
194
|
+
}
|
|
195
|
+
if (etagStale) {
|
|
196
|
+
return false;
|
|
197
|
+
}
|
|
198
|
+
}
|
|
199
|
+
// A recipient MUST ignore If-Modified-Since if the request contains an If-None-Match header field;
|
|
200
|
+
// the condition in If-None-Match is considered to be a more accurate replacement for the condition in If-Modified-Since,
|
|
201
|
+
// and the two are only combined for the sake of interoperating with older intermediaries that might not implement If-None-Match.
|
|
202
|
+
if (noneMatch) {
|
|
203
|
+
return true;
|
|
204
|
+
}
|
|
205
|
+
// if-modified-since
|
|
206
|
+
if (modifiedSince) {
|
|
207
|
+
const lastModified = resHeaders['last-modified'];
|
|
208
|
+
// A recipient MUST ignore the If-Modified-Since header field if the
|
|
209
|
+
// received field-value is not a valid HTTP-date, or if the request
|
|
210
|
+
// method is neither GET nor HEAD.
|
|
211
|
+
const modifiedStale = !lastModified || !(parseHttpDate(lastModified) <= parseHttpDate(modifiedSince));
|
|
212
|
+
if (modifiedStale) {
|
|
213
|
+
return false;
|
|
214
|
+
}
|
|
215
|
+
}
|
|
216
|
+
return true;
|
|
217
|
+
}
|
|
218
|
+
function isRangeFresh() {
|
|
219
|
+
const ifRange =
|
|
220
|
+
/** @type {string | undefined} */
|
|
221
|
+
req.headers['if-range'];
|
|
222
|
+
if (!ifRange) {
|
|
223
|
+
return true;
|
|
224
|
+
}
|
|
225
|
+
// if-range as etag
|
|
226
|
+
if (ifRange.indexOf('"') !== -1) {
|
|
227
|
+
const etag = res.getHeader('ETag');
|
|
228
|
+
if (!etag) {
|
|
229
|
+
return true;
|
|
230
|
+
}
|
|
231
|
+
return Boolean(etag && ifRange.indexOf(etag) !== -1);
|
|
232
|
+
}
|
|
233
|
+
// if-range as modified date
|
|
234
|
+
const lastModified = res.getHeader('Last-Modified');
|
|
235
|
+
if (!lastModified) {
|
|
236
|
+
return true;
|
|
237
|
+
}
|
|
238
|
+
return parseHttpDate(lastModified) <= parseHttpDate(ifRange);
|
|
239
|
+
}
|
|
240
|
+
function getRangeHeader() {
|
|
241
|
+
const rage = req.headers.range;
|
|
242
|
+
if (rage && BYTES_RANGE_REGEXP.test(rage)) {
|
|
243
|
+
return rage;
|
|
244
|
+
}
|
|
245
|
+
// eslint-disable-next-line no-undefined
|
|
246
|
+
return undefined;
|
|
247
|
+
}
|
|
248
|
+
function getOffsetAndLenFromRange(range) {
|
|
249
|
+
const offset = range.start;
|
|
250
|
+
const len = range.end - range.start + 1;
|
|
251
|
+
return [offset, len];
|
|
252
|
+
}
|
|
253
|
+
function calcStartAndEnd(offset, len) {
|
|
254
|
+
const start = offset;
|
|
255
|
+
const end = Math.max(offset, offset + len - 1);
|
|
256
|
+
return [start, end];
|
|
257
|
+
}
|
|
258
|
+
function processRequest() {
|
|
259
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
260
|
+
const extra = {};
|
|
261
|
+
const filename = getFilenameFromUrl(context, req.url, extra);
|
|
262
|
+
if (extra.errorCode) {
|
|
263
|
+
if (extra.errorCode === 403) {
|
|
264
|
+
context.logger.error(`Malicious path "${filename}".`);
|
|
265
|
+
}
|
|
266
|
+
sendError(extra.errorCode, {
|
|
267
|
+
modifyResponseData: context.options.modifyResponseData
|
|
268
|
+
});
|
|
269
|
+
return;
|
|
270
|
+
}
|
|
271
|
+
if (!filename) {
|
|
272
|
+
yield goNext();
|
|
273
|
+
return;
|
|
274
|
+
}
|
|
275
|
+
const { size } = extra.stats;
|
|
276
|
+
let len = size;
|
|
277
|
+
let offset = 0;
|
|
278
|
+
// Send logic
|
|
279
|
+
let { headers } = context.options;
|
|
280
|
+
if (typeof headers === 'function') {
|
|
281
|
+
headers = headers(req, res, context);
|
|
282
|
+
}
|
|
283
|
+
const allHeaders = [];
|
|
284
|
+
if (typeof headers !== 'undefined') {
|
|
285
|
+
if (!Array.isArray(headers)) {
|
|
286
|
+
// eslint-disable-next-line guard-for-in
|
|
287
|
+
for (const name in headers) {
|
|
288
|
+
allHeaders.push({ key: name, value: headers[name] });
|
|
289
|
+
}
|
|
290
|
+
headers = allHeaders;
|
|
291
|
+
}
|
|
292
|
+
headers.forEach(header => {
|
|
293
|
+
res.setHeader(header.key, header.value);
|
|
294
|
+
});
|
|
295
|
+
}
|
|
296
|
+
if (!res.getHeader('Content-Type')) {
|
|
297
|
+
// content-type name(like application/javascript; charset=utf-8) or false
|
|
298
|
+
const contentType = mime.contentType(path.extname(filename));
|
|
299
|
+
// Only set content-type header if media type is known
|
|
300
|
+
// https://tools.ietf.org/html/rfc7231#section-3.1.1.5
|
|
301
|
+
if (contentType) {
|
|
302
|
+
res.setHeader('Content-Type', contentType);
|
|
303
|
+
}
|
|
304
|
+
else if (context.options.mimeTypeDefault) {
|
|
305
|
+
res.setHeader('Content-Type', context.options.mimeTypeDefault);
|
|
306
|
+
}
|
|
307
|
+
}
|
|
308
|
+
if (!res.getHeader('Accept-Ranges')) {
|
|
309
|
+
res.setHeader('Accept-Ranges', 'bytes');
|
|
310
|
+
}
|
|
311
|
+
if (context.options.lastModified && !res.getHeader('Last-Modified')) {
|
|
312
|
+
const modified = extra.stats.mtime.toUTCString();
|
|
313
|
+
res.setHeader('Last-Modified', modified);
|
|
314
|
+
}
|
|
315
|
+
let start;
|
|
316
|
+
let end;
|
|
317
|
+
let bufferOrStream;
|
|
318
|
+
let byteLength;
|
|
319
|
+
const rangeHeader = getRangeHeader();
|
|
320
|
+
if (context.options.etag && !res.getHeader('ETag')) {
|
|
321
|
+
let value;
|
|
322
|
+
// TODO cache etag generation?
|
|
323
|
+
if (context.options.etag === 'weak') {
|
|
324
|
+
value = extra.stats;
|
|
325
|
+
}
|
|
326
|
+
else {
|
|
327
|
+
if (rangeHeader) {
|
|
328
|
+
const parsedRanges = parseRangeHeaders(`${size}|${rangeHeader}`);
|
|
329
|
+
if (parsedRanges !== -2 && parsedRanges !== -1 && parsedRanges.length === 1) {
|
|
330
|
+
;
|
|
331
|
+
[offset, len] = getOffsetAndLenFromRange(parsedRanges[0]);
|
|
332
|
+
}
|
|
333
|
+
}
|
|
334
|
+
;
|
|
335
|
+
[start, end] = calcStartAndEnd(offset, len);
|
|
336
|
+
try {
|
|
337
|
+
const result = createReadStreamOrReadFileSync(filename, context.outputFileSystem, start, end);
|
|
338
|
+
value = result.bufferOrStream;
|
|
339
|
+
({ bufferOrStream, byteLength } = result);
|
|
340
|
+
}
|
|
341
|
+
catch (_err) {
|
|
342
|
+
// Ignore here
|
|
343
|
+
}
|
|
344
|
+
}
|
|
345
|
+
if (value) {
|
|
346
|
+
// eslint-disable-next-line global-require
|
|
347
|
+
const result = yield require('./etag')(value);
|
|
348
|
+
// Because we already read stream, we can cache buffer to avoid extra read from fs
|
|
349
|
+
if (result.buffer) {
|
|
350
|
+
bufferOrStream = result.buffer;
|
|
351
|
+
}
|
|
352
|
+
res.setHeader('ETag', result.hash);
|
|
353
|
+
}
|
|
354
|
+
}
|
|
355
|
+
// Conditional GET support
|
|
356
|
+
if (isConditionalGET()) {
|
|
357
|
+
if (isPreconditionFailure()) {
|
|
358
|
+
sendError(412, {
|
|
359
|
+
modifyResponseData: context.options.modifyResponseData
|
|
360
|
+
});
|
|
361
|
+
return;
|
|
362
|
+
}
|
|
363
|
+
// For Koa
|
|
364
|
+
if (res.statusCode === 404) {
|
|
365
|
+
setStatusCode(res, 200);
|
|
366
|
+
}
|
|
367
|
+
if (isCachable() &&
|
|
368
|
+
isFresh({
|
|
369
|
+
etag: res.getHeader('ETag'),
|
|
370
|
+
'last-modified': res.getHeader('Last-Modified')
|
|
371
|
+
})) {
|
|
372
|
+
setStatusCode(res, 304);
|
|
373
|
+
// Remove content header fields
|
|
374
|
+
res.removeHeader('Content-Encoding');
|
|
375
|
+
res.removeHeader('Content-Language');
|
|
376
|
+
res.removeHeader('Content-Length');
|
|
377
|
+
res.removeHeader('Content-Range');
|
|
378
|
+
res.removeHeader('Content-Type');
|
|
379
|
+
res.end();
|
|
380
|
+
return;
|
|
381
|
+
}
|
|
382
|
+
}
|
|
383
|
+
if (rangeHeader) {
|
|
384
|
+
let parsedRanges = parseRangeHeaders(`${size}|${rangeHeader}`);
|
|
385
|
+
// If-Range support
|
|
386
|
+
if (!isRangeFresh()) {
|
|
387
|
+
parsedRanges = [];
|
|
388
|
+
}
|
|
389
|
+
if (parsedRanges === -1) {
|
|
390
|
+
context.logger.error("Unsatisfiable range for 'Range' header.");
|
|
391
|
+
res.setHeader('Content-Range', getValueContentRangeHeader('bytes', size));
|
|
392
|
+
sendError(416, {
|
|
393
|
+
headers: {
|
|
394
|
+
'Content-Range': res.getHeader('Content-Range')
|
|
395
|
+
},
|
|
396
|
+
modifyResponseData: context.options.modifyResponseData
|
|
397
|
+
});
|
|
398
|
+
return;
|
|
399
|
+
}
|
|
400
|
+
else if (parsedRanges === -2) {
|
|
401
|
+
context.logger.error("A malformed 'Range' header was provided. A regular response will be sent for this request.");
|
|
402
|
+
}
|
|
403
|
+
else if (parsedRanges.length > 1) {
|
|
404
|
+
context.logger.error("A 'Range' header with multiple ranges was provided. Multiple ranges are not supported, so a regular response will be sent for this request.");
|
|
405
|
+
}
|
|
406
|
+
if (parsedRanges !== -2 && parsedRanges.length === 1) {
|
|
407
|
+
// Content-Range
|
|
408
|
+
setStatusCode(res, 206);
|
|
409
|
+
res.setHeader('Content-Range', getValueContentRangeHeader('bytes', size, parsedRanges[0]));
|
|
410
|
+
[offset, len] = getOffsetAndLenFromRange(parsedRanges[0]);
|
|
411
|
+
}
|
|
412
|
+
}
|
|
413
|
+
// When strong Etag generation is enabled we already read file, so we can skip extra fs call
|
|
414
|
+
if (!bufferOrStream) {
|
|
415
|
+
;
|
|
416
|
+
[start, end] = calcStartAndEnd(offset, len);
|
|
417
|
+
try {
|
|
418
|
+
;
|
|
419
|
+
({ bufferOrStream, byteLength } = createReadStreamOrReadFileSync(filename, context.outputFileSystem, start, end));
|
|
420
|
+
}
|
|
421
|
+
catch (_ignoreError) {
|
|
422
|
+
yield goNext();
|
|
423
|
+
return;
|
|
424
|
+
}
|
|
425
|
+
}
|
|
426
|
+
if (context.options.modifyResponseData) {
|
|
427
|
+
;
|
|
428
|
+
({ data: bufferOrStream, byteLength } = context.options.modifyResponseData(req, res, bufferOrStream, byteLength));
|
|
429
|
+
}
|
|
430
|
+
res.setHeader('Content-Length', byteLength);
|
|
431
|
+
if (req.method === 'HEAD') {
|
|
432
|
+
// For Koa
|
|
433
|
+
if (res.statusCode === 404) {
|
|
434
|
+
setStatusCode(res, 200);
|
|
435
|
+
}
|
|
436
|
+
res.end();
|
|
437
|
+
return;
|
|
438
|
+
}
|
|
439
|
+
const isPipeSupports = typeof bufferOrStream.pipe === 'function';
|
|
440
|
+
if (!isPipeSupports) {
|
|
441
|
+
send(res, bufferOrStream);
|
|
442
|
+
return;
|
|
443
|
+
}
|
|
444
|
+
// Cleanup
|
|
445
|
+
const cleanup = () => {
|
|
446
|
+
destroyStream(bufferOrStream, true);
|
|
447
|
+
};
|
|
448
|
+
// Error handling
|
|
449
|
+
bufferOrStream.on('error', error => {
|
|
450
|
+
// clean up stream early
|
|
451
|
+
cleanup();
|
|
452
|
+
// Handle Error
|
|
453
|
+
switch (error.code) {
|
|
454
|
+
case 'ENAMETOOLONG':
|
|
455
|
+
case 'ENOENT':
|
|
456
|
+
case 'ENOTDIR':
|
|
457
|
+
sendError(404, {
|
|
458
|
+
modifyResponseData: context.options.modifyResponseData
|
|
459
|
+
});
|
|
460
|
+
break;
|
|
461
|
+
default:
|
|
462
|
+
sendError(500, {
|
|
463
|
+
modifyResponseData: context.options.modifyResponseData
|
|
464
|
+
});
|
|
465
|
+
break;
|
|
466
|
+
}
|
|
467
|
+
});
|
|
468
|
+
pipe(res, bufferOrStream);
|
|
469
|
+
// Response finished, cleanup
|
|
470
|
+
onFinishedStream(res, cleanup);
|
|
471
|
+
});
|
|
472
|
+
}
|
|
473
|
+
ready(context, processRequest, req);
|
|
474
|
+
});
|
|
475
|
+
};
|
|
476
|
+
}
|
|
477
|
+
exports.default = wrapper;
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
function ready(context, callback, req) {
|
|
3
|
+
if (context.state) {
|
|
4
|
+
callback(context.stats);
|
|
5
|
+
return;
|
|
6
|
+
}
|
|
7
|
+
const name = (req && req.url) || callback.name;
|
|
8
|
+
context.logger.info(`wait until bundle finished${name ? `: ${name}` : ""}`);
|
|
9
|
+
context.callbacks.push(callback);
|
|
10
|
+
}
|
|
11
|
+
module.exports = ready;
|
package/dist/index.d.ts
CHANGED
|
@@ -3,12 +3,12 @@ import { COMPILE_ENTRY } from './config/constant.config';
|
|
|
3
3
|
import { Project } from 'xhs-mp-project';
|
|
4
4
|
import EventEmitter from 'events';
|
|
5
5
|
import { Logger } from 'xhs-mp-utils';
|
|
6
|
-
import {
|
|
6
|
+
import { getProjectCompilerClass } from './compiler';
|
|
7
7
|
interface ILibFeatures {
|
|
8
8
|
supportV2?: boolean;
|
|
9
9
|
supportVdom?: boolean;
|
|
10
10
|
}
|
|
11
|
-
export { COMPILE_ENTRY,
|
|
11
|
+
export { COMPILE_ENTRY, getProjectCompilerClass, };
|
|
12
12
|
export type ICompileOpts = {
|
|
13
13
|
logger?: any;
|
|
14
14
|
compileDir?: string;
|
|
@@ -50,7 +50,7 @@ export interface ISubPackages {
|
|
|
50
50
|
root: string;
|
|
51
51
|
pages: string;
|
|
52
52
|
}
|
|
53
|
-
export declare class
|
|
53
|
+
export declare class ProjectCompiler extends EventEmitter {
|
|
54
54
|
projectPath: string;
|
|
55
55
|
compilerProps: ICompilerProps;
|
|
56
56
|
project: Project;
|
package/dist/index.js
CHANGED
|
@@ -12,7 +12,7 @@ var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
|
12
12
|
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
13
13
|
};
|
|
14
14
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
15
|
-
exports.
|
|
15
|
+
exports.ProjectCompiler = exports.getProjectCompilerClass = exports.COMPILE_ENTRY = void 0;
|
|
16
16
|
const constant_config_1 = require("./config/constant.config");
|
|
17
17
|
Object.defineProperty(exports, "COMPILE_ENTRY", { enumerable: true, get: function () { return constant_config_1.COMPILE_ENTRY; } });
|
|
18
18
|
const xhs_mp_project_1 = require("xhs-mp-project");
|
|
@@ -24,8 +24,8 @@ const zip_1 = require("./utils/zip");
|
|
|
24
24
|
const project_1 = require("./utils/project");
|
|
25
25
|
const dir_config_1 = require("./config/dir.config");
|
|
26
26
|
const compiler_1 = require("./compiler");
|
|
27
|
-
Object.defineProperty(exports, "
|
|
28
|
-
class
|
|
27
|
+
Object.defineProperty(exports, "getProjectCompilerClass", { enumerable: true, get: function () { return compiler_1.getProjectCompilerClass; } });
|
|
28
|
+
class ProjectCompiler extends events_1.default {
|
|
29
29
|
constructor(props) {
|
|
30
30
|
super();
|
|
31
31
|
this.compilerImplMap = {};
|
|
@@ -203,7 +203,7 @@ class Compiler extends events_1.default {
|
|
|
203
203
|
};
|
|
204
204
|
this.removeDistDir(entryType);
|
|
205
205
|
this.removeCacheDir(entryType);
|
|
206
|
-
const CompilerClass = (0, compiler_1.
|
|
206
|
+
const CompilerClass = (0, compiler_1.getProjectCompilerClass)(compilerType);
|
|
207
207
|
const compilerImpl = new CompilerClass(options, {
|
|
208
208
|
logger: this.logger,
|
|
209
209
|
nodeJsPath
|
|
@@ -453,4 +453,4 @@ class Compiler extends events_1.default {
|
|
|
453
453
|
delete this.compilerImplMap[entryType];
|
|
454
454
|
}
|
|
455
455
|
}
|
|
456
|
-
exports.
|
|
456
|
+
exports.ProjectCompiler = ProjectCompiler;
|
|
@@ -9,7 +9,6 @@ const path_1 = __importDefault(require("path"));
|
|
|
9
9
|
const xhs_mp_pack_1 = require("xhs-mp-pack");
|
|
10
10
|
const apm_1 = require("../../utils/apm");
|
|
11
11
|
const createCompiler = (startConfig) => {
|
|
12
|
-
const { action, enableDevServer } = startConfig;
|
|
13
12
|
const mppack = new xhs_mp_pack_1.MPPack(startConfig);
|
|
14
13
|
const compilerOptions = {
|
|
15
14
|
project: mppack.project,
|
|
@@ -19,6 +19,7 @@ const openBrowser_1 = __importDefault(require("./lib/openBrowser"));
|
|
|
19
19
|
const presets_1 = require("../../../presets");
|
|
20
20
|
const devServer = (config) => __awaiter(void 0, void 0, void 0, function* () {
|
|
21
21
|
const { packSetting } = config;
|
|
22
|
+
// @ts-ignore
|
|
22
23
|
const { devServerPort, distDir } = packSetting;
|
|
23
24
|
const webpackConfigs = (0, presets_1.createConfigs)(config);
|
|
24
25
|
const compiler = (0, webpack_1.default)(webpackConfigs);
|
|
@@ -6,7 +6,6 @@ Object.defineProperty(exports, "__esModule", { value: true });
|
|
|
6
6
|
exports.createCompiler = void 0;
|
|
7
7
|
const path_1 = __importDefault(require("path"));
|
|
8
8
|
const fs_extra_1 = __importDefault(require("fs-extra"));
|
|
9
|
-
const dev_server_1 = __importDefault(require("./dev-server"));
|
|
10
9
|
const projectConfig_1 = require("../../utils/projectConfig");
|
|
11
10
|
const common_1 = require("../../utils/common");
|
|
12
11
|
const types_1 = require("../../types");
|
|
@@ -88,9 +87,9 @@ const createCompiler = (startConfig) => {
|
|
|
88
87
|
// cli的node_modules路径
|
|
89
88
|
(_d = (_c = config.resolve) === null || _c === void 0 ? void 0 : _c.modules) === null || _d === void 0 ? void 0 : _d.push(path_1.default.resolve(__dirname, '../../../'));
|
|
90
89
|
});
|
|
91
|
-
if (action === 'dev' && enableDevServer) {
|
|
92
|
-
|
|
93
|
-
}
|
|
90
|
+
// if (action === 'dev' && enableDevServer) {
|
|
91
|
+
// return webpackDevServer(compilerOptions)
|
|
92
|
+
// }
|
|
94
93
|
return new webpack_1.WebPack(webpackConfig, compilerOptions);
|
|
95
94
|
};
|
|
96
95
|
exports.createCompiler = createCompiler;
|
|
@@ -10,7 +10,7 @@ export declare class WebPack extends AbstractMPPack {
|
|
|
10
10
|
packSetting: MPPackSetting;
|
|
11
11
|
hadWatch: boolean;
|
|
12
12
|
constructor(configs: any, options: IPresetOptions);
|
|
13
|
-
handleProgress: (
|
|
13
|
+
handleProgress: (percentage: any, status: any, info: any) => void;
|
|
14
14
|
get hooks(): any;
|
|
15
15
|
watch(config: any, callback?: any): Promise<unknown>;
|
|
16
16
|
changeCompileOptions(config: any): void;
|
|
@@ -25,8 +25,12 @@ class WebPack extends xhs_mp_pack_1.AbstractMPPack {
|
|
|
25
25
|
this.compiler = null;
|
|
26
26
|
this.watcher = null;
|
|
27
27
|
this.hadWatch = false;
|
|
28
|
-
this.handleProgress =
|
|
29
|
-
this.emit('progress',
|
|
28
|
+
this.handleProgress = (percentage, status, info) => {
|
|
29
|
+
this.emit('progress', {
|
|
30
|
+
percentage,
|
|
31
|
+
status,
|
|
32
|
+
info
|
|
33
|
+
});
|
|
30
34
|
};
|
|
31
35
|
this.project = options.project;
|
|
32
36
|
this.packSetting = options.packSetting;
|
|
@@ -1,5 +1,4 @@
|
|
|
1
1
|
import { Config } from '../../../../packs';
|
|
2
2
|
import { IPresetOptions } from '../../../../types';
|
|
3
|
-
declare const getRenderEntry: (options: IPresetOptions) => () => {};
|
|
4
|
-
declare const presetRender: (chain: Config, options: IPresetOptions) => void;
|
|
5
|
-
export { getRenderEntry, presetRender };
|
|
3
|
+
export declare const getRenderEntry: (options: IPresetOptions) => () => {};
|
|
4
|
+
export declare const presetRender: (chain: Config, options: IPresetOptions) => void;
|
|
@@ -13,8 +13,8 @@ const renderChunkPlugin_1 = __importDefault(require("./renderChunkPlugin"));
|
|
|
13
13
|
const types_1 = require("../../../../types");
|
|
14
14
|
const InjectorPlugin_1 = require("../../../plugins/InjectorPlugin");
|
|
15
15
|
const getRenderEntry = (options) => () => {
|
|
16
|
-
const
|
|
17
|
-
return
|
|
16
|
+
const entries = Object.assign(Object.assign({}, (0, render_1.getRenderEntry)(options)), (0, component_1.getComponentEntry)(options));
|
|
17
|
+
return entries;
|
|
18
18
|
};
|
|
19
19
|
exports.getRenderEntry = getRenderEntry;
|
|
20
20
|
const presetRender = (chain, options) => {
|