1 | "use strict";
|
2 |
|
3 | Object.defineProperty(exports, "__esModule", {
|
4 | value: true
|
5 | });
|
6 | exports.default = void 0;
|
7 |
|
8 | var _utils = require("@parcel/utils");
|
9 |
|
10 | var _logger = require("@parcel/logger");
|
11 |
|
12 | var _diagnostic = _interopRequireWildcard(require("@parcel/diagnostic"));
|
13 |
|
14 | var _stream = require("stream");
|
15 |
|
16 | var _nullthrows = _interopRequireDefault(require("nullthrows"));
|
17 |
|
18 | var _path = _interopRequireDefault(require("path"));
|
19 |
|
20 | var _url = _interopRequireDefault(require("url"));
|
21 |
|
22 | var _Bundle = require("./public/Bundle");
|
23 |
|
24 | var _BundleGraph = _interopRequireWildcard(require("./public/BundleGraph"));
|
25 |
|
26 | var _PluginOptions = _interopRequireDefault(require("./public/PluginOptions"));
|
27 |
|
28 | var _constants = require("./constants");
|
29 |
|
30 | function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
|
31 |
|
32 | function _getRequireWildcardCache() { if (typeof WeakMap !== "function") return null; var cache = new WeakMap(); _getRequireWildcardCache = function () { return cache; }; return cache; }
|
33 |
|
34 | function _interopRequireWildcard(obj) { if (obj && obj.__esModule) { return obj; } if (obj === null || typeof obj !== "object" && typeof obj !== "function") { return { default: obj }; } var cache = _getRequireWildcardCache(); if (cache && cache.has(obj)) { return cache.get(obj); } var newObj = {}; var hasPropertyDescriptor = Object.defineProperty && Object.getOwnPropertyDescriptor; for (var key in obj) { if (Object.prototype.hasOwnProperty.call(obj, key)) { var desc = hasPropertyDescriptor ? Object.getOwnPropertyDescriptor(obj, key) : null; if (desc && (desc.get || desc.set)) { Object.defineProperty(newObj, key, desc); } else { newObj[key] = obj[key]; } } } newObj.default = obj; if (cache) { cache.set(obj, newObj); } return newObj; }
|
35 |
|
36 | function _defineProperty(obj, key, value) { if (key in obj) { Object.defineProperty(obj, key, { value: value, enumerable: true, configurable: true, writable: true }); } else { obj[key] = value; } return obj; }
|
37 |
|
38 | class PackagerRunner {
|
39 | constructor({
|
40 | config,
|
41 | farm,
|
42 | options,
|
43 | report
|
44 | }) {
|
45 | _defineProperty(this, "config", void 0);
|
46 |
|
47 | _defineProperty(this, "options", void 0);
|
48 |
|
49 | _defineProperty(this, "farm", void 0);
|
50 |
|
51 | _defineProperty(this, "pluginOptions", void 0);
|
52 |
|
53 | _defineProperty(this, "distDir", void 0);
|
54 |
|
55 | _defineProperty(this, "distExists", void 0);
|
56 |
|
57 | _defineProperty(this, "report", void 0);
|
58 |
|
59 | _defineProperty(this, "writeBundleFromWorker", void 0);
|
60 |
|
61 | this.config = config;
|
62 | this.options = options;
|
63 | this.pluginOptions = new _PluginOptions.default(this.options);
|
64 | this.farm = farm;
|
65 | this.report = report;
|
66 | this.writeBundleFromWorker = farm ? farm.createHandle('runPackage') : () => {
|
67 | throw new Error('Cannot call PackagerRunner.writeBundleFromWorker() in a worker');
|
68 | };
|
69 | }
|
70 |
|
71 | async writeBundles(bundleGraph) {
|
72 | let farm = (0, _nullthrows.default)(this.farm);
|
73 | let {
|
74 | ref,
|
75 | dispose
|
76 | } = await farm.createSharedReference(bundleGraph);
|
77 | let promises = [];
|
78 |
|
79 | for (let bundle of bundleGraph.getBundles()) {
|
80 |
|
81 | if (bundle.isInline) {
|
82 | continue;
|
83 | }
|
84 |
|
85 | promises.push(this.writeBundle(bundle, bundleGraph, ref).then(stats => {
|
86 | bundle.stats = stats;
|
87 | }));
|
88 | }
|
89 |
|
90 | await Promise.all(promises);
|
91 | await dispose();
|
92 | }
|
93 |
|
94 | async writeBundle(bundle, bundleGraph, bundleGraphReference) {
|
95 | let start = Date.now();
|
96 | let cacheKey = await this.getCacheKey(bundle, bundleGraph);
|
97 | let {
|
98 | size
|
99 | } = (await this.writeBundleFromCache({
|
100 | bundle,
|
101 | bundleGraph,
|
102 | cacheKey
|
103 | })) || (await this.writeBundleFromWorker({
|
104 | bundle,
|
105 | cacheKey,
|
106 | bundleGraphReference,
|
107 | options: this.options,
|
108 | config: this.config
|
109 | }));
|
110 | return {
|
111 | time: Date.now() - start,
|
112 | size
|
113 | };
|
114 | }
|
115 |
|
116 | async writeBundleFromCache({
|
117 | bundle,
|
118 | bundleGraph,
|
119 | cacheKey
|
120 | }) {
|
121 | if (this.options.disableCache) {
|
122 | return;
|
123 | }
|
124 |
|
125 | let cacheResult = await this.readFromCache(cacheKey);
|
126 |
|
127 | if (cacheResult == null) {
|
128 | return;
|
129 | }
|
130 |
|
131 | let {
|
132 | contents,
|
133 | map
|
134 | } = cacheResult;
|
135 | let {
|
136 | size
|
137 | } = await this.writeToDist({
|
138 | bundle,
|
139 | bundleGraph,
|
140 | contents,
|
141 | map
|
142 | });
|
143 | return {
|
144 | size
|
145 | };
|
146 | }
|
147 |
|
148 | async packageAndWriteBundle(bundle, bundleGraph, cacheKey) {
|
149 | let start = Date.now();
|
150 | let {
|
151 | contents,
|
152 | map
|
153 | } = await this.getBundleResult(bundle, bundleGraph, cacheKey);
|
154 | let {
|
155 | size
|
156 | } = await this.writeToDist({
|
157 | bundle,
|
158 | bundleGraph,
|
159 | contents,
|
160 | map
|
161 | });
|
162 | return {
|
163 | time: Date.now() - start,
|
164 | size
|
165 | };
|
166 | }
|
167 |
|
168 | async getBundleResult(bundle, bundleGraph, cacheKey) {
|
169 | let result;
|
170 |
|
171 | if (!cacheKey && !this.options.disableCache) {
|
172 | cacheKey = await this.getCacheKey(bundle, bundleGraph);
|
173 | let cacheResult = await this.readFromCache(cacheKey);
|
174 |
|
175 | if (cacheResult) {
|
176 |
|
177 | return {
|
178 | contents: cacheResult.contents,
|
179 | map: cacheResult.map
|
180 | };
|
181 | }
|
182 | }
|
183 |
|
184 | let packaged = await this.package(bundle, bundleGraph);
|
185 | let res = await this.optimize(bundle, bundleGraph, packaged.contents, packaged.map);
|
186 | let map = res.map ? await this.generateSourceMap(bundle, res.map) : null;
|
187 | result = {
|
188 | contents: res.contents,
|
189 | map
|
190 | };
|
191 |
|
192 | if (cacheKey != null) {
|
193 | await this.writeToCache(cacheKey, result.contents, map);
|
194 |
|
195 | if (result.contents instanceof _stream.Readable) {
|
196 | return {
|
197 | contents: this.options.cache.getStream(getContentKey(cacheKey)),
|
198 | map: result.map
|
199 | };
|
200 | }
|
201 | }
|
202 |
|
203 | return result;
|
204 | }
|
205 |
|
206 | async package(internalBundle, bundleGraph) {
|
207 | let bundle = new _Bundle.NamedBundle(internalBundle, bundleGraph, this.options);
|
208 | this.report({
|
209 | type: 'buildProgress',
|
210 | phase: 'packaging',
|
211 | bundle
|
212 | });
|
213 | let packager = await this.config.getPackager(bundle.filePath);
|
214 |
|
215 | try {
|
216 | return await packager.plugin.package({
|
217 | bundle,
|
218 | bundleGraph: new _BundleGraph.default(bundleGraph, this.options),
|
219 | getSourceMapReference: map => {
|
220 | return bundle.isInline || bundle.target.sourceMap && bundle.target.sourceMap.inline ? this.generateSourceMap((0, _Bundle.bundleToInternalBundle)(bundle), map) : _path.default.basename(bundle.filePath) + '.map';
|
221 | },
|
222 | options: this.pluginOptions,
|
223 | logger: new _logger.PluginLogger({
|
224 | origin: packager.name
|
225 | }),
|
226 | getInlineBundleContents: (bundle, bundleGraph) => {
|
227 | if (!bundle.isInline) {
|
228 | throw new Error('Bundle is not inline and unable to retrieve contents');
|
229 | }
|
230 |
|
231 | return this.getBundleResult((0, _Bundle.bundleToInternalBundle)(bundle), (0, _BundleGraph.bundleGraphToInternalBundleGraph)(bundleGraph));
|
232 | }
|
233 | });
|
234 | } catch (e) {
|
235 | throw new _diagnostic.default({
|
236 | diagnostic: (0, _diagnostic.errorToDiagnostic)(e, packager.name)
|
237 | });
|
238 | }
|
239 | }
|
240 |
|
241 | async optimize(internalBundle, bundleGraph, contents, map) {
|
242 | let bundle = new _Bundle.NamedBundle(internalBundle, bundleGraph, this.options);
|
243 | let optimizers = await this.config.getOptimizers(bundle.filePath, internalBundle.pipeline);
|
244 |
|
245 | if (!optimizers.length) {
|
246 | return {
|
247 | contents,
|
248 | map
|
249 | };
|
250 | }
|
251 |
|
252 | this.report({
|
253 | type: 'buildProgress',
|
254 | phase: 'optimizing',
|
255 | bundle
|
256 | });
|
257 | let optimized = {
|
258 | contents,
|
259 | map
|
260 | };
|
261 |
|
262 | for (let optimizer of optimizers) {
|
263 | try {
|
264 | optimized = await optimizer.plugin.optimize({
|
265 | bundle,
|
266 | contents: optimized.contents,
|
267 | map: optimized.map,
|
268 | options: this.pluginOptions,
|
269 | logger: new _logger.PluginLogger({
|
270 | origin: optimizer.name
|
271 | })
|
272 | });
|
273 | } catch (e) {
|
274 | throw new _diagnostic.default({
|
275 | diagnostic: (0, _diagnostic.errorToDiagnostic)(e, optimizer.name)
|
276 | });
|
277 | }
|
278 | }
|
279 |
|
280 | return optimized;
|
281 | }
|
282 |
|
283 | generateSourceMap(bundle, map) {
|
284 |
|
285 | let filePath = (0, _nullthrows.default)(bundle.filePath);
|
286 |
|
287 | let sourceRoot = _path.default.relative(_path.default.dirname(filePath), this.options.projectRoot);
|
288 |
|
289 | let inlineSources = false;
|
290 |
|
291 | if (bundle.target) {
|
292 | if (bundle.target.sourceMap && bundle.target.sourceMap.sourceRoot !== undefined) {
|
293 | sourceRoot = bundle.target.sourceMap.sourceRoot;
|
294 | } else if (bundle.target.env.context === 'browser' && this.options.mode !== 'production') {
|
295 | sourceRoot = '/__parcel_source_root';
|
296 | }
|
297 |
|
298 | if (bundle.target.sourceMap && bundle.target.sourceMap.inlineSources !== undefined) {
|
299 | inlineSources = bundle.target.sourceMap.inlineSources;
|
300 | } else if (bundle.target.env.context !== 'node') {
|
301 |
|
302 | inlineSources = this.options.mode === 'production';
|
303 | }
|
304 | }
|
305 |
|
306 | return map.stringify({
|
307 | file: _path.default.basename(filePath + '.map'),
|
308 | fs: this.options.inputFS,
|
309 | rootDir: this.options.projectRoot,
|
310 | sourceRoot: !inlineSources ? _url.default.format(_url.default.parse(sourceRoot + '/')) : undefined,
|
311 | inlineSources,
|
312 | inlineMap: bundle.isInline || bundle.target.sourceMap && bundle.target.sourceMap.inline
|
313 | });
|
314 | }
|
315 |
|
316 | getCacheKey(bundle, bundleGraph) {
|
317 | let filePath = (0, _nullthrows.default)(bundle.filePath);
|
318 |
|
319 | let packager = this.config.getPackagerName(filePath);
|
320 | let optimizers = this.config.getOptimizerNames(filePath);
|
321 | let deps = Promise.all([packager, ...optimizers].map(async pkg => {
|
322 | let {
|
323 | pkg: resolvedPkg
|
324 | } = await this.options.packageManager.resolve(`${pkg}/package.json`, `${this.config.filePath}/index`);
|
325 | let version = (0, _nullthrows.default)(resolvedPkg).version;
|
326 | return [pkg, version];
|
327 | }));
|
328 |
|
329 | let {
|
330 | minify,
|
331 | scopeHoist,
|
332 | sourceMaps
|
333 | } = this.options;
|
334 | return (0, _utils.md5FromObject)({
|
335 | parcelVersion: _constants.PARCEL_VERSION,
|
336 | deps,
|
337 | opts: {
|
338 | minify,
|
339 | scopeHoist,
|
340 | sourceMaps
|
341 | },
|
342 | hash: bundleGraph.getHash(bundle)
|
343 | });
|
344 | }
|
345 |
|
346 | async readFromCache(cacheKey) {
|
347 | let contentKey = getContentKey(cacheKey);
|
348 | let mapKey = getMapKey(cacheKey);
|
349 | let contentExists = await this.options.cache.blobExists(contentKey);
|
350 |
|
351 | if (!contentExists) {
|
352 | return null;
|
353 | }
|
354 |
|
355 | let mapExists = await this.options.cache.blobExists(mapKey);
|
356 | return {
|
357 | contents: this.options.cache.getStream(contentKey),
|
358 | map: mapExists ? this.options.cache.getStream(mapKey) : null
|
359 | };
|
360 | }
|
361 |
|
362 | async writeToDist({
|
363 | bundle,
|
364 | bundleGraph,
|
365 | contents,
|
366 | map
|
367 | }) {
|
368 | let {
|
369 | inputFS,
|
370 | outputFS
|
371 | } = this.options;
|
372 | let filePath = (0, _nullthrows.default)(bundle.filePath);
|
373 |
|
374 | let dir = _path.default.dirname(filePath);
|
375 |
|
376 | await outputFS.mkdirp(dir);
|
377 |
|
378 |
|
379 |
|
380 | let publicBundle = new _Bundle.NamedBundle(bundle, bundleGraph, this.options);
|
381 | let writeOptions = publicBundle.env.isBrowser() ? undefined : {
|
382 | mode: (await inputFS.stat((0, _nullthrows.default)(publicBundle.getMainEntry()).filePath)).mode
|
383 | };
|
384 | let size;
|
385 |
|
386 | if (contents instanceof _stream.Readable) {
|
387 | size = await writeFileStream(outputFS, filePath, contents, writeOptions);
|
388 | } else {
|
389 | await outputFS.writeFile(filePath, contents, writeOptions);
|
390 | size = contents.length;
|
391 | }
|
392 |
|
393 | if (map != null) {
|
394 | if (map instanceof _stream.Readable) {
|
395 | await writeFileStream(outputFS, filePath + '.map', map);
|
396 | } else {
|
397 | await outputFS.writeFile(filePath + '.map', map);
|
398 | }
|
399 | }
|
400 |
|
401 | return {
|
402 | size
|
403 | };
|
404 | }
|
405 |
|
406 | async writeToCache(cacheKey, contents, map) {
|
407 | let contentKey = getContentKey(cacheKey);
|
408 | await this.options.cache.setStream(contentKey, (0, _utils.blobToStream)(contents));
|
409 |
|
410 | if (map != null) {
|
411 | let mapKey = getMapKey(cacheKey);
|
412 | await this.options.cache.setStream(mapKey, (0, _utils.blobToStream)(map));
|
413 | }
|
414 | }
|
415 |
|
416 | }
|
417 |
|
418 | exports.default = PackagerRunner;
|
419 |
|
420 | function writeFileStream(fs, filePath, stream, options) {
|
421 | return new Promise((resolve, reject) => {
|
422 | let fsStream = fs.createWriteStream(filePath, options);
|
423 | stream.pipe(fsStream)
|
424 | .on('finish', () => resolve(fsStream.bytesWritten)).on('error', reject);
|
425 | });
|
426 | }
|
427 |
|
428 | function getContentKey(cacheKey) {
|
429 | return (0, _utils.md5FromString)(`${cacheKey}:content`);
|
430 | }
|
431 |
|
432 | function getMapKey(cacheKey) {
|
433 | return (0, _utils.md5FromString)(`${cacheKey}:map`);
|
434 | } |
\ | No newline at end of file |