UNPKG

33.7 kBJavaScriptView Raw
1"use strict";
2
3var _interopRequireDefault = require("@babel/runtime/helpers/interopRequireDefault");
4
5var _slicedToArray2 = _interopRequireDefault(require("@babel/runtime/helpers/slicedToArray"));
6
7var _asyncToGenerator2 = _interopRequireDefault(require("@babel/runtime/helpers/asyncToGenerator"));
8
9const fs = require('@parcel/fs');
10
11const Resolver = require('./Resolver');
12
13const Parser = require('./Parser');
14
15const WorkerFarm = require('@parcel/workers');
16
17const Path = require('path');
18
19const Bundle = require('./Bundle');
20
21const Watcher = require('@parcel/watcher');
22
23const FSCache = require('./FSCache');
24
25const HMRServer = require('./HMRServer');
26
27const Server = require('./Server');
28
29const _require = require('events'),
30 EventEmitter = _require.EventEmitter;
31
32const logger = require('@parcel/logger');
33
34const PackagerRegistry = require('./packagers');
35
36const localRequire = require('./utils/localRequire');
37
38const config = require('./utils/config');
39
40const loadEnv = require('./utils/env');
41
42const PromiseQueue = require('./utils/PromiseQueue');
43
44const installPackage = require('./utils/installPackage');
45
46const bundleReport = require('./utils/bundleReport');
47
48const prettifyTime = require('./utils/prettifyTime');
49
50const getRootDir = require('./utils/getRootDir');
51
52const _require2 = require('./utils/glob'),
53 glob = _require2.glob,
54 isGlob = _require2.isGlob;
55/**
56 * The Bundler is the main entry point. It resolves and loads assets,
57 * creates the bundle tree, and manages the worker farm, cache, and file watcher.
58 */
59
60
61class Bundler extends EventEmitter {
62 constructor(entryFiles, options = {}) {
63 super();
64 entryFiles = this.normalizeEntries(entryFiles);
65 this.watchedGlobs = entryFiles.filter(entry => isGlob(entry));
66 this.entryFiles = this.findEntryFiles(entryFiles);
67 this.options = this.normalizeOptions(options);
68 this.resolver = new Resolver(this.options);
69 this.parser = new Parser(this.options);
70 this.packagers = new PackagerRegistry(this.options);
71 this.cache = this.options.cache ? new FSCache(this.options) : null;
72 this.delegate = options.delegate || {};
73 this.bundleLoaders = {};
74 this.addBundleLoader('wasm', {
75 browser: require.resolve('./builtins/loaders/browser/wasm-loader'),
76 node: require.resolve('./builtins/loaders/node/wasm-loader')
77 });
78 this.addBundleLoader('css', {
79 browser: require.resolve('./builtins/loaders/browser/css-loader'),
80 node: require.resolve('./builtins/loaders/node/css-loader')
81 });
82 this.addBundleLoader('js', {
83 browser: require.resolve('./builtins/loaders/browser/js-loader'),
84 node: require.resolve('./builtins/loaders/node/js-loader')
85 });
86 this.addBundleLoader('html', {
87 browser: require.resolve('./builtins/loaders/browser/html-loader'),
88 node: require.resolve('./builtins/loaders/node/html-loader')
89 });
90 this.pending = false;
91 this.loadedAssets = new Map();
92 this.watchedAssets = new Map();
93 this.farm = null;
94 this.watcher = null;
95 this.hmr = null;
96 this.bundleHashes = null;
97 this.error = null;
98 this.buildQueue = new PromiseQueue(this.processAsset.bind(this));
99 this.rebuildTimeout = null;
100 logger.setOptions(this.options);
101 }
102
103 normalizeEntries(entryFiles) {
104 // Support passing a single file
105 if (entryFiles && !Array.isArray(entryFiles)) {
106 entryFiles = [entryFiles];
107 } // If no entry files provided, resolve the entry point from the current directory.
108
109
110 if (!entryFiles || entryFiles.length === 0) {
111 entryFiles = [process.cwd()];
112 }
113
114 return entryFiles;
115 }
116
117 findEntryFiles(entryFiles) {
118 // Match files as globs
119 return entryFiles.reduce((p, m) => p.concat(glob.sync(m)), []).map(f => Path.resolve(f));
120 }
121
122 normalizeOptions(options) {
123 const isProduction = options.production || process.env.NODE_ENV === 'production';
124 const publicURL = options.publicUrl || options.publicURL || '/';
125 const watch = typeof options.watch === 'boolean' ? options.watch : !isProduction;
126 const target = options.target || 'browser';
127 const hmr = target === 'node' ? false : typeof options.hmr === 'boolean' ? options.hmr : watch;
128 const scopeHoist = options.scopeHoist !== undefined ? options.scopeHoist : false;
129 return {
130 production: isProduction,
131 outDir: Path.resolve(options.outDir || 'dist'),
132 outFile: options.outFile || '',
133 publicURL: publicURL,
134 watch: watch,
135 cache: typeof options.cache === 'boolean' ? options.cache : true,
136 cacheDir: Path.resolve(options.cacheDir || '.cache'),
137 killWorkers: typeof options.killWorkers === 'boolean' ? options.killWorkers : true,
138 minify: typeof options.minify === 'boolean' ? options.minify : isProduction,
139 target: target,
140 bundleNodeModules: typeof options.bundleNodeModules === 'boolean' ? options.bundleNodeModules : target === 'browser',
141 hmr: hmr,
142 https: options.https || false,
143 logLevel: isNaN(options.logLevel) ? 3 : options.logLevel,
144 entryFiles: this.entryFiles,
145 hmrPort: options.hmrPort || 0,
146 rootDir: getRootDir(this.entryFiles),
147 sourceMaps: (typeof options.sourceMaps === 'boolean' ? options.sourceMaps : true) && !scopeHoist,
148 hmrHostname: options.hmrHostname || options.host || (options.target === 'electron' ? 'localhost' : ''),
149 detailedReport: options.detailedReport || false,
150 global: options.global,
151 autoinstall: typeof options.autoInstall === 'boolean' ? options.autoInstall : process.env.PARCEL_AUTOINSTALL === 'false' ? false : !isProduction,
152 scopeHoist: scopeHoist,
153 contentHash: typeof options.contentHash === 'boolean' ? options.contentHash : isProduction,
154 throwErrors: typeof options.throwErrors === 'boolean' ? options.throwErrors : true
155 };
156 }
157
158 addAssetType(extension, path) {
159 if (typeof path !== 'string') {
160 throw new Error('Asset type should be a module path.');
161 }
162
163 if (this.farm) {
164 throw new Error('Asset types must be added before bundling.');
165 }
166
167 this.parser.registerExtension(extension, path);
168 }
169
170 addPackager(type, packager) {
171 if (this.farm) {
172 throw new Error('Packagers must be added before bundling.');
173 }
174
175 this.packagers.add(type, packager);
176 }
177
178 addBundleLoader(type, paths) {
179 if (typeof paths === 'string') {
180 paths = {
181 node: paths,
182 browser: paths
183 };
184 } else if (typeof paths !== 'object') {
185 throw new Error('Bundle loaders should be an object.');
186 }
187
188 for (const target in paths) {
189 if (target !== 'node' && target !== 'browser') {
190 throw new Error(`Unknown bundle loader target "${target}".`);
191 }
192
193 if (typeof paths[target] !== 'string') {
194 throw new Error('Bundle loader should be a string.');
195 }
196 }
197
198 if (this.farm) {
199 throw new Error('Bundle loaders must be added before bundling.');
200 }
201
202 this.bundleLoaders[type] = paths;
203 }
204
205 loadPlugins() {
206 var _this = this;
207
208 return (0, _asyncToGenerator2.default)(function* () {
209 let relative = Path.join(_this.options.rootDir, 'index');
210 let pkg = yield config.load(relative, ['package.json']);
211
212 if (!pkg) {
213 return;
214 }
215
216 let lastDep;
217
218 try {
219 let deps = Object.assign({}, pkg.dependencies, pkg.devDependencies);
220
221 for (let dep in deps) {
222 lastDep = dep;
223 const pattern = /^(@.*\/)?parcel-plugin-.+/;
224
225 if (pattern.test(dep)) {
226 let plugin = yield localRequire(dep, relative);
227 yield plugin(_this);
228 }
229 }
230 } catch (err) {
231 logger.warn(`Plugin ${lastDep} failed to initialize: ${err.stack || err.message || err}`);
232 }
233 })();
234 }
235
236 bundle() {
237 var _this2 = this;
238
239 return (0, _asyncToGenerator2.default)(function* () {
240 // If another bundle is already pending, wait for that one to finish and retry.
241 if (_this2.pending) {
242 return new Promise((resolve, reject) => {
243 _this2.once('buildEnd', () => {
244 _this2.bundle().then(resolve, reject);
245 });
246 });
247 }
248
249 let isInitialBundle = !_this2.entryAssets;
250 let startTime = Date.now();
251 let initialised = !isInitialBundle;
252 _this2.pending = true;
253 _this2.error = null;
254 logger.clear();
255 logger.progress('Building...');
256
257 try {
258 // Start worker farm, watcher, etc. if needed
259 yield _this2.start(); // Emit start event, after bundler is initialised
260
261 _this2.emit('buildStart', _this2.entryFiles); // If this is the initial bundle, ensure the output directory exists, and resolve the main asset.
262
263
264 if (isInitialBundle) {
265 yield fs.mkdirp(_this2.options.outDir);
266 _this2.entryAssets = new Set();
267 var _iteratorNormalCompletion = true;
268 var _didIteratorError = false;
269 var _iteratorError = undefined;
270
271 try {
272 for (var _iterator = _this2.entryFiles[Symbol.iterator](), _step; !(_iteratorNormalCompletion = (_step = _iterator.next()).done); _iteratorNormalCompletion = true) {
273 let entry = _step.value;
274
275 try {
276 let asset = yield _this2.resolveAsset(entry);
277
278 _this2.buildQueue.add(asset);
279
280 _this2.entryAssets.add(asset);
281 } catch (err) {
282 throw new Error(`Cannot resolve entry "${entry}" from "${_this2.options.rootDir}"`);
283 }
284 }
285 } catch (err) {
286 _didIteratorError = true;
287 _iteratorError = err;
288 } finally {
289 try {
290 if (!_iteratorNormalCompletion && _iterator.return != null) {
291 _iterator.return();
292 }
293 } finally {
294 if (_didIteratorError) {
295 throw _iteratorError;
296 }
297 }
298 }
299
300 if (_this2.entryAssets.size === 0) {
301 throw new Error('No entries found.');
302 }
303
304 initialised = true;
305 } // Build the queued assets.
306
307
308 let loadedAssets = yield _this2.buildQueue.run(); // The changed assets are any that don't have a parent bundle yet
309 // plus the ones that were in the build queue.
310
311 let changedAssets = [..._this2.findOrphanAssets(), ...loadedAssets]; // Invalidate bundles
312
313 var _iteratorNormalCompletion2 = true;
314 var _didIteratorError2 = false;
315 var _iteratorError2 = undefined;
316
317 try {
318 for (var _iterator2 = _this2.loadedAssets.values()[Symbol.iterator](), _step2; !(_iteratorNormalCompletion2 = (_step2 = _iterator2.next()).done); _iteratorNormalCompletion2 = true) {
319 let asset = _step2.value;
320 asset.invalidateBundle();
321 }
322 } catch (err) {
323 _didIteratorError2 = true;
324 _iteratorError2 = err;
325 } finally {
326 try {
327 if (!_iteratorNormalCompletion2 && _iterator2.return != null) {
328 _iterator2.return();
329 }
330 } finally {
331 if (_didIteratorError2) {
332 throw _iteratorError2;
333 }
334 }
335 }
336
337 logger.progress(`Producing bundles...`); // Create a root bundle to hold all of the entry assets, and add them to the tree.
338
339 _this2.mainBundle = new Bundle();
340 var _iteratorNormalCompletion3 = true;
341 var _didIteratorError3 = false;
342 var _iteratorError3 = undefined;
343
344 try {
345 for (var _iterator3 = _this2.entryAssets[Symbol.iterator](), _step3; !(_iteratorNormalCompletion3 = (_step3 = _iterator3.next()).done); _iteratorNormalCompletion3 = true) {
346 let asset = _step3.value;
347
348 _this2.createBundleTree(asset, _this2.mainBundle);
349 } // If there is only one child bundle, replace the root with that bundle.
350
351 } catch (err) {
352 _didIteratorError3 = true;
353 _iteratorError3 = err;
354 } finally {
355 try {
356 if (!_iteratorNormalCompletion3 && _iterator3.return != null) {
357 _iterator3.return();
358 }
359 } finally {
360 if (_didIteratorError3) {
361 throw _iteratorError3;
362 }
363 }
364 }
365
366 if (_this2.mainBundle.childBundles.size === 1) {
367 _this2.mainBundle = Array.from(_this2.mainBundle.childBundles)[0];
368 } // Generate the final bundle names, and replace references in the built assets.
369
370
371 let numBundles = _this2.bundleNameMap ? _this2.bundleNameMap.size : 0;
372 _this2.bundleNameMap = _this2.mainBundle.getBundleNameMap(_this2.options.contentHash);
373
374 for (var _i = 0; _i < changedAssets.length; _i++) {
375 let asset = changedAssets[_i];
376 asset.replaceBundleNames(_this2.bundleNameMap);
377 } // Emit an HMR update if this is not the initial bundle.
378
379
380 let bundlesChanged = numBundles !== _this2.bundleNameMap.size;
381
382 if (_this2.hmr && !isInitialBundle) {
383 _this2.hmr.emitUpdate(changedAssets, bundlesChanged);
384 }
385
386 logger.progress(`Packaging...`); // Package everything up
387
388 _this2.bundleHashes = yield _this2.mainBundle.package(_this2, bundlesChanged ? null : _this2.bundleHashes); // Unload any orphaned assets
389
390 _this2.unloadOrphanedAssets();
391
392 let buildTime = Date.now() - startTime;
393 let time = prettifyTime(buildTime);
394 logger.success(`Built in ${time}.`);
395
396 if (!_this2.watcher) {
397 bundleReport(_this2.mainBundle, _this2.options.detailedReport);
398 }
399
400 _this2.emit('bundled', _this2.mainBundle);
401
402 return _this2.mainBundle;
403 } catch (err) {
404 _this2.error = err;
405 logger.error(err);
406
407 _this2.emit('buildError', err);
408
409 if (_this2.hmr) {
410 _this2.hmr.emitError(err);
411 }
412
413 if (_this2.options.throwErrors && !_this2.hmr) {
414 throw err;
415 } else if (!_this2.options.watch || !initialised) {
416 yield _this2.stop();
417 process.exit(1);
418 }
419 } finally {
420 _this2.pending = false;
421
422 _this2.emit('buildEnd'); // If not in watch mode, stop the worker farm so we don't keep the process running.
423
424
425 if (!_this2.watcher && _this2.options.killWorkers) {
426 yield _this2.stop();
427 }
428 }
429 })();
430 }
431
432 start() {
433 var _this3 = this;
434
435 return (0, _asyncToGenerator2.default)(function* () {
436 if (_this3.farm) {
437 return;
438 }
439
440 yield _this3.loadPlugins();
441
442 if (!_this3.options.env) {
443 yield loadEnv(Path.join(_this3.options.rootDir, 'index'));
444 _this3.options.env = process.env;
445 }
446
447 _this3.options.extensions = Object.assign({}, _this3.parser.extensions);
448 _this3.options.bundleLoaders = _this3.bundleLoaders;
449
450 if (_this3.options.watch) {
451 _this3.watcher = new Watcher(); // Wait for ready event for reliable testing on watcher
452
453 if (process.env.NODE_ENV === 'test' && !_this3.watcher.ready) {
454 yield new Promise(resolve => _this3.watcher.once('ready', resolve));
455 }
456
457 _this3.watchedGlobs.forEach(glob => {
458 _this3.watcher.add(glob);
459 });
460
461 _this3.watcher.on('add', _this3.onAdd.bind(_this3));
462
463 _this3.watcher.on('change', _this3.onChange.bind(_this3));
464
465 _this3.watcher.on('unlink', _this3.onUnlink.bind(_this3));
466 }
467
468 if (_this3.options.hmr) {
469 _this3.hmr = new HMRServer();
470 _this3.options.hmrPort = yield _this3.hmr.start(_this3.options);
471 }
472
473 _this3.farm = yield WorkerFarm.getShared(_this3.options, {
474 workerPath: require.resolve('./worker.js')
475 });
476 })();
477 }
478
479 stop() {
480 var _this4 = this;
481
482 return (0, _asyncToGenerator2.default)(function* () {
483 if (_this4.watcher) {
484 yield _this4.watcher.stop();
485 }
486
487 if (_this4.hmr) {
488 _this4.hmr.stop();
489 } // Watcher and hmr can cause workerfarm calls
490 // keep this as last to prevent unwanted errors
491
492
493 if (_this4.farm) {
494 yield _this4.farm.end();
495 }
496 })();
497 }
498
499 getAsset(name, parent) {
500 var _this5 = this;
501
502 return (0, _asyncToGenerator2.default)(function* () {
503 let asset = yield _this5.resolveAsset(name, parent);
504
505 _this5.buildQueue.add(asset);
506
507 yield _this5.buildQueue.run();
508 return asset;
509 })();
510 }
511
512 resolveAsset(name, parent) {
513 var _this6 = this;
514
515 return (0, _asyncToGenerator2.default)(function* () {
516 let _ref = yield _this6.resolver.resolve(name, parent),
517 path = _ref.path;
518
519 return _this6.getLoadedAsset(path);
520 })();
521 }
522
523 getLoadedAsset(path) {
524 if (this.loadedAssets.has(path)) {
525 return this.loadedAssets.get(path);
526 }
527
528 let asset = this.parser.getAsset(path, this.options);
529 this.loadedAssets.set(path, asset);
530 this.watch(path, asset);
531 return asset;
532 }
533
534 watch(path, asset) {
535 var _this7 = this;
536
537 return (0, _asyncToGenerator2.default)(function* () {
538 if (!_this7.watcher) {
539 return;
540 }
541
542 path = yield fs.realpath(path);
543
544 if (!_this7.watchedAssets.has(path)) {
545 _this7.watcher.watch(path);
546
547 _this7.watchedAssets.set(path, new Set());
548 }
549
550 _this7.watchedAssets.get(path).add(asset);
551 })();
552 }
553
554 unwatch(path, asset) {
555 var _this8 = this;
556
557 return (0, _asyncToGenerator2.default)(function* () {
558 path = yield fs.realpath(path);
559
560 if (!_this8.watchedAssets.has(path)) {
561 return;
562 }
563
564 let watched = _this8.watchedAssets.get(path);
565
566 watched.delete(asset);
567
568 if (watched.size === 0) {
569 _this8.watchedAssets.delete(path);
570
571 _this8.watcher.unwatch(path);
572 }
573 })();
574 }
575
576 resolveDep(asset, dep, install = true) {
577 var _this9 = this;
578
579 return (0, _asyncToGenerator2.default)(function* () {
580 try {
581 if (dep.resolved) {
582 return _this9.getLoadedAsset(dep.resolved);
583 }
584
585 return yield _this9.resolveAsset(dep.name, asset.name);
586 } catch (err) {
587 // If the dep is optional, return before we throw
588 if (dep.optional) {
589 return;
590 }
591
592 if (err.code === 'MODULE_NOT_FOUND') {
593 let isLocalFile = /^[/~.]/.test(dep.name);
594 let fromNodeModules = asset.name.includes(`${Path.sep}node_modules${Path.sep}`);
595
596 if (!isLocalFile && !fromNodeModules && _this9.options.autoinstall && install) {
597 return _this9.installDep(asset, dep);
598 }
599
600 err.message = `Cannot resolve dependency '${dep.name}'`;
601
602 if (isLocalFile) {
603 const absPath = Path.resolve(Path.dirname(asset.name), dep.name);
604 err.message += ` at '${absPath}'`;
605 }
606
607 yield _this9.throwDepError(asset, dep, err);
608 }
609
610 throw err;
611 }
612 })();
613 }
614
615 installDep(asset, dep) {
616 var _this10 = this;
617
618 return (0, _asyncToGenerator2.default)(function* () {
619 // Check if module exists, prevents useless installs
620 let resolved = yield _this10.resolver.resolveModule(dep.name, asset.name); // If the module resolved (i.e. wasn't a local file), but the module directory wasn't found, install it.
621
622 if (resolved.moduleName && !resolved.moduleDir) {
623 try {
624 yield installPackage(resolved.moduleName, asset.name, {
625 saveDev: false
626 });
627 } catch (err) {
628 yield _this10.throwDepError(asset, dep, err);
629 }
630 }
631
632 return _this10.resolveDep(asset, dep, false);
633 })();
634 }
635
636 throwDepError(asset, dep, err) {
637 return (0, _asyncToGenerator2.default)(function* () {
638 // Generate a code frame where the dependency was used
639 if (dep.loc) {
640 yield asset.loadIfNeeded();
641 err.loc = dep.loc;
642 err = asset.generateErrorMessage(err);
643 }
644
645 err.fileName = asset.name;
646 throw err;
647 })();
648 }
649
650 processAsset(asset, isRebuild) {
651 var _this11 = this;
652
653 return (0, _asyncToGenerator2.default)(function* () {
654 if (isRebuild) {
655 asset.invalidate();
656
657 if (_this11.cache) {
658 _this11.cache.invalidate(asset.name);
659 }
660 }
661
662 yield _this11.loadAsset(asset);
663 })();
664 }
665
666 loadAsset(asset) {
667 var _this12 = this;
668
669 return (0, _asyncToGenerator2.default)(function* () {
670 if (asset.processed) {
671 return;
672 }
673
674 if (!_this12.error) {
675 logger.progress(`Building ${asset.basename}...`);
676 } // Mark the asset processed so we don't load it twice
677
678
679 asset.processed = true; // First try the cache, otherwise load and compile in the background
680
681 asset.startTime = Date.now();
682 let processed = _this12.cache && (yield _this12.cache.read(asset.name));
683 let cacheMiss = false;
684
685 if (!processed || asset.shouldInvalidate(processed.cacheData)) {
686 processed = yield _this12.farm.run(asset.name);
687 cacheMiss = true;
688 }
689
690 asset.endTime = Date.now();
691 asset.buildTime = asset.endTime - asset.startTime;
692 asset.id = processed.id;
693 asset.generated = processed.generated;
694 asset.sourceMaps = processed.sourceMaps;
695 asset.hash = processed.hash;
696 asset.cacheData = processed.cacheData; // Call the delegate to get implicit dependencies
697
698 let dependencies = processed.dependencies;
699
700 if (_this12.delegate.getImplicitDependencies) {
701 let implicitDeps = yield _this12.delegate.getImplicitDependencies(asset);
702
703 if (implicitDeps) {
704 dependencies = dependencies.concat(implicitDeps);
705 }
706 } // Resolve and load asset dependencies
707
708
709 let assetDeps = yield Promise.all(dependencies.map(
710 /*#__PURE__*/
711 function () {
712 var _ref2 = (0, _asyncToGenerator2.default)(function* (dep) {
713 if (dep.includedInParent) {
714 // This dependency is already included in the parent's generated output,
715 // so no need to load it. We map the name back to the parent asset so
716 // that changing it triggers a recompile of the parent.
717 _this12.watch(dep.name, asset);
718 } else {
719 dep.parent = asset.name;
720 let assetDep = yield _this12.resolveDep(asset, dep);
721
722 if (assetDep) {
723 yield _this12.loadAsset(assetDep);
724 }
725
726 return assetDep;
727 }
728 });
729
730 return function (_x) {
731 return _ref2.apply(this, arguments);
732 };
733 }())); // If there was a processing error, re-throw now that we've set up
734 // depdenency watchers. This keeps reloading working if there is an
735 // error in a dependency not directly handled by Parcel.
736
737 if (processed.error !== null) {
738 throw processed.error;
739 } // Store resolved assets in their original order
740
741
742 dependencies.forEach((dep, i) => {
743 asset.dependencies.set(dep.name, dep);
744 let assetDep = assetDeps[i];
745
746 if (assetDep) {
747 asset.depAssets.set(dep, assetDep);
748 dep.resolved = assetDep.name;
749 }
750 });
751 logger.verbose(`Built ${asset.relativeName}...`);
752
753 if (_this12.cache && cacheMiss) {
754 _this12.cache.write(asset.name, processed);
755 }
756 })();
757 }
758
759 createBundleTree(asset, bundle, dep, parentBundles = new Set()) {
760 if (dep) {
761 asset.parentDeps.add(dep);
762 }
763
764 if (asset.parentBundle && !bundle.isolated) {
765 // If the asset is already in a bundle, it is shared. Move it to the lowest common ancestor.
766 if (asset.parentBundle !== bundle) {
767 let commonBundle = bundle.findCommonAncestor(asset.parentBundle); // If the common bundle's type matches the asset's, move the asset to the common bundle.
768 // Otherwise, proceed with adding the asset to the new bundle below.
769
770 if (asset.parentBundle.type === commonBundle.type) {
771 this.moveAssetToBundle(asset, commonBundle);
772 return;
773 }
774 } else {
775 return;
776 } // Detect circular bundles
777
778
779 if (parentBundles.has(asset.parentBundle)) {
780 return;
781 }
782 } // Skip this asset if it's already in the bundle.
783 // Happens when circular dependencies are placed in an isolated bundle (e.g. a worker).
784
785
786 if (bundle.isolated && bundle.assets.has(asset)) {
787 return;
788 }
789
790 let isEntryAsset = asset.parentBundle && asset.parentBundle.entryAsset === asset; // If the asset generated a representation for the parent bundle type, and this
791 // is not an async import, add it to the current bundle
792
793 if (bundle.type && asset.generated[bundle.type] != null && !dep.dynamic) {
794 bundle.addAsset(asset);
795 }
796
797 if (dep && dep.dynamic || !bundle.type) {
798 // If the asset is already the entry asset of a bundle, don't create a duplicate.
799 if (isEntryAsset) {
800 return;
801 } // Create a new bundle for dynamic imports
802
803
804 bundle = bundle.createChildBundle(asset, dep);
805 } else if (asset.type && !this.packagers.get(asset.type).shouldAddAsset(bundle, asset)) {
806 // If the asset is already the entry asset of a bundle, don't create a duplicate.
807 if (isEntryAsset) {
808 return;
809 } // No packager is available for this asset type, or the packager doesn't support
810 // combining this asset into the bundle. Create a new bundle with only this asset.
811
812
813 bundle = bundle.createSiblingBundle(asset, dep);
814 } else {
815 // Add the asset to the common bundle of the asset's type
816 bundle.getSiblingBundle(asset.type).addAsset(asset);
817 } // Add the asset to sibling bundles for each generated type
818
819
820 if (asset.type && asset.generated[asset.type]) {
821 for (let t in asset.generated) {
822 if (asset.generated[t]) {
823 bundle.getSiblingBundle(t).addAsset(asset);
824 }
825 }
826 }
827
828 asset.parentBundle = bundle;
829 parentBundles.add(bundle);
830 var _iteratorNormalCompletion4 = true;
831 var _didIteratorError4 = false;
832 var _iteratorError4 = undefined;
833
834 try {
835 for (var _iterator4 = asset.depAssets[Symbol.iterator](), _step4; !(_iteratorNormalCompletion4 = (_step4 = _iterator4.next()).done); _iteratorNormalCompletion4 = true) {
836 let _step4$value = (0, _slicedToArray2.default)(_step4.value, 2),
837 dep = _step4$value[0],
838 assetDep = _step4$value[1];
839
840 this.createBundleTree(assetDep, bundle, dep, parentBundles);
841 }
842 } catch (err) {
843 _didIteratorError4 = true;
844 _iteratorError4 = err;
845 } finally {
846 try {
847 if (!_iteratorNormalCompletion4 && _iterator4.return != null) {
848 _iterator4.return();
849 }
850 } finally {
851 if (_didIteratorError4) {
852 throw _iteratorError4;
853 }
854 }
855 }
856
857 parentBundles.delete(bundle);
858 return bundle;
859 }
860
861 moveAssetToBundle(asset, commonBundle) {
862 // Never move the entry asset of a bundle, as it was explicitly requested to be placed in a separate bundle.
863 if (asset.parentBundle.entryAsset === asset || asset.parentBundle === commonBundle) {
864 return;
865 }
866
867 var _arr = Array.from(asset.bundles);
868
869 for (var _i2 = 0; _i2 < _arr.length; _i2++) {
870 let bundle = _arr[_i2];
871
872 if (!bundle.isolated) {
873 bundle.removeAsset(asset);
874 }
875
876 commonBundle.getSiblingBundle(bundle.type).addAsset(asset);
877 }
878
879 let oldBundle = asset.parentBundle;
880 asset.parentBundle = commonBundle; // Move all dependencies as well
881
882 var _iteratorNormalCompletion5 = true;
883 var _didIteratorError5 = false;
884 var _iteratorError5 = undefined;
885
886 try {
887 for (var _iterator5 = asset.depAssets.values()[Symbol.iterator](), _step5; !(_iteratorNormalCompletion5 = (_step5 = _iterator5.next()).done); _iteratorNormalCompletion5 = true) {
888 let child = _step5.value;
889
890 if (child.parentBundle === oldBundle) {
891 this.moveAssetToBundle(child, commonBundle);
892 }
893 }
894 } catch (err) {
895 _didIteratorError5 = true;
896 _iteratorError5 = err;
897 } finally {
898 try {
899 if (!_iteratorNormalCompletion5 && _iterator5.return != null) {
900 _iterator5.return();
901 }
902 } finally {
903 if (_didIteratorError5) {
904 throw _iteratorError5;
905 }
906 }
907 }
908 }
909
910 *findOrphanAssets() {
911 var _iteratorNormalCompletion6 = true;
912 var _didIteratorError6 = false;
913 var _iteratorError6 = undefined;
914
915 try {
916 for (var _iterator6 = this.loadedAssets.values()[Symbol.iterator](), _step6; !(_iteratorNormalCompletion6 = (_step6 = _iterator6.next()).done); _iteratorNormalCompletion6 = true) {
917 let asset = _step6.value;
918
919 if (!asset.parentBundle) {
920 yield asset;
921 }
922 }
923 } catch (err) {
924 _didIteratorError6 = true;
925 _iteratorError6 = err;
926 } finally {
927 try {
928 if (!_iteratorNormalCompletion6 && _iterator6.return != null) {
929 _iterator6.return();
930 }
931 } finally {
932 if (_didIteratorError6) {
933 throw _iteratorError6;
934 }
935 }
936 }
937 }
938
939 unloadOrphanedAssets() {
940 var _iteratorNormalCompletion7 = true;
941 var _didIteratorError7 = false;
942 var _iteratorError7 = undefined;
943
944 try {
945 for (var _iterator7 = this.findOrphanAssets()[Symbol.iterator](), _step7; !(_iteratorNormalCompletion7 = (_step7 = _iterator7.next()).done); _iteratorNormalCompletion7 = true) {
946 let asset = _step7.value;
947 this.unloadAsset(asset);
948 }
949 } catch (err) {
950 _didIteratorError7 = true;
951 _iteratorError7 = err;
952 } finally {
953 try {
954 if (!_iteratorNormalCompletion7 && _iterator7.return != null) {
955 _iterator7.return();
956 }
957 } finally {
958 if (_didIteratorError7) {
959 throw _iteratorError7;
960 }
961 }
962 }
963 }
964
965 unloadAsset(asset) {
966 this.loadedAssets.delete(asset.name);
967
968 if (this.watcher) {
969 this.unwatch(asset.name, asset); // Unwatch all included dependencies that map to this asset
970
971 var _iteratorNormalCompletion8 = true;
972 var _didIteratorError8 = false;
973 var _iteratorError8 = undefined;
974
975 try {
976 for (var _iterator8 = asset.dependencies.values()[Symbol.iterator](), _step8; !(_iteratorNormalCompletion8 = (_step8 = _iterator8.next()).done); _iteratorNormalCompletion8 = true) {
977 let dep = _step8.value;
978
979 if (dep.includedInParent) {
980 this.unwatch(dep.name, asset);
981 }
982 }
983 } catch (err) {
984 _didIteratorError8 = true;
985 _iteratorError8 = err;
986 } finally {
987 try {
988 if (!_iteratorNormalCompletion8 && _iterator8.return != null) {
989 _iterator8.return();
990 }
991 } finally {
992 if (_didIteratorError8) {
993 throw _iteratorError8;
994 }
995 }
996 }
997 }
998 }
999
1000 onAdd(path) {
1001 var _this13 = this;
1002
1003 return (0, _asyncToGenerator2.default)(function* () {
1004 path = Path.join(process.cwd(), path);
1005
1006 let asset = _this13.parser.getAsset(path, _this13.options);
1007
1008 _this13.loadedAssets.set(path, asset);
1009
1010 _this13.entryAssets.add(asset);
1011
1012 yield _this13.watch(path, asset);
1013
1014 _this13.onChange(path);
1015 })();
1016 }
1017
1018 onChange(path) {
1019 var _this14 = this;
1020
1021 return (0, _asyncToGenerator2.default)(function* () {
1022 // The path to the newly-added items are not absolute.
1023 if (!Path.isAbsolute(path)) {
1024 path = Path.resolve(process.cwd(), path);
1025 }
1026
1027 let assets = _this14.watchedAssets.get(path);
1028
1029 if (!assets || !assets.size) {
1030 return;
1031 }
1032
1033 logger.clear();
1034 logger.progress(`Building ${Path.basename(path)}...`); // Add the asset to the rebuild queue, and reset the timeout.
1035
1036 var _iteratorNormalCompletion9 = true;
1037 var _didIteratorError9 = false;
1038 var _iteratorError9 = undefined;
1039
1040 try {
1041 for (var _iterator9 = assets[Symbol.iterator](), _step9; !(_iteratorNormalCompletion9 = (_step9 = _iterator9.next()).done); _iteratorNormalCompletion9 = true) {
1042 let asset = _step9.value;
1043
1044 _this14.buildQueue.add(asset, true);
1045 }
1046 } catch (err) {
1047 _didIteratorError9 = true;
1048 _iteratorError9 = err;
1049 } finally {
1050 try {
1051 if (!_iteratorNormalCompletion9 && _iterator9.return != null) {
1052 _iterator9.return();
1053 }
1054 } finally {
1055 if (_didIteratorError9) {
1056 throw _iteratorError9;
1057 }
1058 }
1059 }
1060
1061 clearTimeout(_this14.rebuildTimeout);
1062 _this14.rebuildTimeout = setTimeout(
1063 /*#__PURE__*/
1064 (0, _asyncToGenerator2.default)(function* () {
1065 yield _this14.bundle();
1066 }), 100);
1067 })();
1068 }
1069
1070 onUnlink(path) {
1071 var _this15 = this;
1072
1073 return (0, _asyncToGenerator2.default)(function* () {
1074 // The path to the newly-added items are not absolute.
1075 if (!Path.isAbsolute(path)) {
1076 path = Path.resolve(process.cwd(), path);
1077 }
1078
1079 let asset = _this15.getLoadedAsset(path);
1080
1081 _this15.entryAssets.delete(asset);
1082
1083 _this15.unloadAsset(asset);
1084
1085 _this15.bundle();
1086 })();
1087 }
1088
1089 middleware() {
1090 this.bundle();
1091 return Server.middleware(this);
1092 }
1093
1094 serve(port = 1234, https = false, host) {
1095 var _this16 = this;
1096
1097 return (0, _asyncToGenerator2.default)(function* () {
1098 _this16.server = yield Server.serve(_this16, port, host, https);
1099
1100 try {
1101 yield _this16.bundle();
1102 } catch (e) {// ignore: server can still work with errored bundler
1103 }
1104
1105 return _this16.server;
1106 })();
1107 }
1108
1109}
1110
1111module.exports = Bundler;
1112Bundler.Asset = require('./Asset');
1113Bundler.Packager = require('./packagers/Packager');
\No newline at end of file