diff --git a/packages/core/parcel/src/Bundler.js b/packages/core/parcel/src/Bundler.js index 8850c10aeaf..dd7d17312a8 100644 --- a/packages/core/parcel/src/Bundler.js +++ b/packages/core/parcel/src/Bundler.js @@ -51,6 +51,10 @@ class Bundler extends EventEmitter { browser: require.resolve('./builtins/loaders/browser/js-loader'), node: require.resolve('./builtins/loaders/node/js-loader') }); + this.addBundleLoader('html', { + browser: require.resolve('./builtins/loaders/browser/html-loader'), + node: require.resolve('./builtins/loaders/node/html-loader') + }); this.pending = false; this.loadedAssets = new Map(); @@ -620,6 +624,12 @@ class Bundler extends EventEmitter { let isEntryAsset = asset.parentBundle && asset.parentBundle.entryAsset === asset; + // If the asset generated a representation for the parent bundle type, and this + // is not an async import, add it to the current bundle + if (bundle.type && asset.generated[bundle.type] != null && !dep.dynamic) { + bundle.addAsset(asset); + } + if ((dep && dep.dynamic) || !bundle.type) { // If the asset is already the entry asset of a bundle, don't create a duplicate. if (isEntryAsset) { @@ -628,24 +638,23 @@ class Bundler extends EventEmitter { // Create a new bundle for dynamic imports bundle = bundle.createChildBundle(asset, dep); - } else if (asset.type && !this.packagers.has(asset.type)) { + } else if ( + asset.type && + !this.packagers.get(asset.type).shouldAddAsset(bundle, asset) + ) { // If the asset is already the entry asset of a bundle, don't create a duplicate. if (isEntryAsset) { return; } - // No packager is available for this asset type. Create a new bundle with only this asset. - bundle.createSiblingBundle(asset); + // No packager is available for this asset type, or the packager doesn't support + // combining this asset into the bundle. Create a new bundle with only this asset. + bundle = bundle.createSiblingBundle(asset, dep); } else { // Add the asset to the common bundle of the asset's type bundle.getSiblingBundle(asset.type).addAsset(asset); } - // If the asset generated a representation for the parent bundle type, also add it there - if (asset.generated[bundle.type] != null) { - bundle.addAsset(asset); - } - // Add the asset to sibling bundles for each generated type if (asset.type && asset.generated[asset.type]) { for (let t in asset.generated) { diff --git a/packages/core/parcel/src/builtins/loaders/browser/html-loader.js b/packages/core/parcel/src/builtins/loaders/browser/html-loader.js new file mode 100644 index 00000000000..36a71480421 --- /dev/null +++ b/packages/core/parcel/src/builtins/loaders/browser/html-loader.js @@ -0,0 +1,5 @@ +module.exports = function loadHTMLBundle(bundle) { + return fetch(bundle).then(function (res) { + return res.text(); + }); +}; diff --git a/packages/core/parcel/src/builtins/loaders/node/html-loader.js b/packages/core/parcel/src/builtins/loaders/node/html-loader.js new file mode 100644 index 00000000000..64f6f958be6 --- /dev/null +++ b/packages/core/parcel/src/builtins/loaders/node/html-loader.js @@ -0,0 +1,17 @@ +var fs = require('fs'); + +module.exports = function loadHTMLBundle(bundle) { + return new Promise(function(resolve, reject) { + fs.readFile(__dirname + bundle, 'utf8', function(err, data) { + if (err) { + reject(err); + } else { + // wait for the next event loop iteration, so we are sure + // the current module is fully loaded + setImmediate(function() { + resolve(data); + }); + } + }); + }); +}; diff --git a/packages/core/parcel/src/packagers/HTMLPackager.js b/packages/core/parcel/src/packagers/HTMLPackager.js index 498ba7dda9d..fdd5364e505 100644 --- a/packages/core/parcel/src/packagers/HTMLPackager.js +++ b/packages/core/parcel/src/packagers/HTMLPackager.js @@ -16,6 +16,11 @@ const metadataContent = new Set([ ]); class HTMLPackager extends Packager { + static shouldAddAsset() { + // We cannot combine multiple HTML files together - they should be written as separate bundles. + return false; + } + async addAsset(asset) { let html = asset.generated.html || ''; diff --git a/packages/core/parcel/src/packagers/Packager.js b/packages/core/parcel/src/packagers/Packager.js index a9aa82d8bd8..c60dfb7fd4a 100644 --- a/packages/core/parcel/src/packagers/Packager.js +++ b/packages/core/parcel/src/packagers/Packager.js @@ -10,6 +10,10 @@ class Packager { this.options = bundler.options; } + static shouldAddAsset() { + return true; + } + async setup() { // Create sub-directories if needed if (this.bundle.name.includes(path.sep)) { diff --git a/packages/core/parcel/src/packagers/RawPackager.js b/packages/core/parcel/src/packagers/RawPackager.js index cc40ff971db..06677f38b04 100644 --- a/packages/core/parcel/src/packagers/RawPackager.js +++ b/packages/core/parcel/src/packagers/RawPackager.js @@ -3,6 +3,11 @@ const path = require('path'); const fs = require('../utils/fs'); class RawPackager extends Packager { + static shouldAddAsset() { + // We cannot combine multiple raw assets together - they should be written as separate bundles. + return false; + } + // Override so we don't create a file for this bundle. // Each asset will be emitted as a separate file instead. setup() {} diff --git a/packages/core/parcel/test/integration/import-html-async/100x100.png b/packages/core/parcel/test/integration/import-html-async/100x100.png new file mode 100644 index 00000000000..8a1daa0121d Binary files /dev/null and b/packages/core/parcel/test/integration/import-html-async/100x100.png differ diff --git a/packages/core/parcel/test/integration/import-html-async/index.css b/packages/core/parcel/test/integration/import-html-async/index.css new file mode 100644 index 00000000000..67ce83e4d09 --- /dev/null +++ b/packages/core/parcel/test/integration/import-html-async/index.css @@ -0,0 +1,3 @@ +body { + background: red; +} diff --git a/packages/core/parcel/test/integration/import-html-async/index.js b/packages/core/parcel/test/integration/import-html-async/index.js new file mode 100644 index 00000000000..7235f4c3023 --- /dev/null +++ b/packages/core/parcel/test/integration/import-html-async/index.js @@ -0,0 +1 @@ +module.exports = import('./other.html'); diff --git a/packages/core/parcel/test/integration/import-html-async/other.html b/packages/core/parcel/test/integration/import-html-async/other.html new file mode 100644 index 00000000000..36d14dc9d2f --- /dev/null +++ b/packages/core/parcel/test/integration/import-html-async/other.html @@ -0,0 +1,10 @@ + + +
+ + + +