Loadable-components: Babel-plugin: Unrelated files are being bundled together due to import with identical relative paths

Created on 7 Apr 2020  ·  7Comments  ·  Source: gregberge/loadable-components

🐛 Bug Report

When using the babel-plugin, two different, unrelated, modules having the same filename, and being imported with an identical relative path from different components, end up being bundled together.

For instance, consider this directory structure:

└─ component-1
   ├── index.js
   └── later.js

└─ component-2
   ├── index.js
   └── later.js

If both component-1 and component-2 are using _@loadable/component_ to import their respective later.js module like so:

const Content = loadable(() => import('./later.js'));

We end up with the content of both later.js files bundled in a single later-bundle-[hash].js file.
Since these components have nothing in common (except a naming scheme), this is not desirable and seems like a bug to me.

My guess would be that this is due/related to the chunkName being later.js for both.

Changing the imports and filenames to import('./later-1.js) and import('./later-2.js) properly creates two independent modules, not being bundled together.

To Reproduce

Clone this fork quentind/loadable-components and run the modified "server side rendering" example with:

cd examples/server-side-rendering
yarn
yarn build

This will result in the following _assetsByChunkName_ in the loadable-stats.json:

"vendors~letters-A~letters-B~moment": "vendors~letters-A~letters-B~moment-bundle-ebaf5b04.js",
"letters-test-1": "letters-test-1-bundle-6904889d.js",
"letters-test-2": "letters-test-2-bundle-a6f9fa21.js",
"letters-A": [
    "letters-A.css",
    "letters-A-bundle-741365d5.js"
],
"letters-B": "letters-B-bundle-22ea974d.js",
"letters-C": "letters-C-bundle-ac34183c.js",
"letters-D": "letters-D-bundle-5855063f.js",
"letters-E": "letters-E-bundle-0a9b3a90.js",
"letters-F": "letters-F-bundle-0d5ffdb3.js",
"letters-G": "letters-G-bundle-8e463824.js",
"letters-Z-file": "letters-Z-file-bundle-51e385c3.js",
"letters-test-1-content": "letters-test-1-content-bundle-08c48f90.js",
"letters-test-2-content": "letters-test-2-content-bundle-22007c7e.js",
"Y-file": "Y-file-bundle-3e89611f.js",
"content": "content-bundle-16c508f6.js",
"letters-A-css": [
    "letters-A-css.css",
    "letters-A-css-bundle-d5cf68fd.js"
],
"main": [
    "main.css",
    "main-bundle-efe2b3de.js"
],
"moment": "moment-bundle-7128bd13.js"

Notice the "content": "content-bundle-16c508f6.js" file which contains both modules imported as import('./content.js') (not desirable).

Expected behavior

Following the reproduction method described above, I would expect ./letters/test-1/content.js and ./letters/test-2/content.js to NOT be bundled together, allowing them to be loaded separately and only when necessary.

Link to repl or repo (highly encouraged)

quentind/loadable-components
See "To reproduce" for instructions.

Run npx envinfo --system --binaries --npmPackages @loadable/component,@loadable/server,@loadable/webpack-plugin,@loadable/babel-plugin --markdown --clipboard

## System:
 - OS: macOS 10.15.2
 - CPU: (16) x64 Intel(R) Core(TM) i9-9880H CPU @ 2.30GHz
 - Memory: 109.27 MB / 16.00 GB
 - Shell: 5.7.1 - /bin/zsh
## Binaries:
 - Node: 10.18.1 - ~/.nvm/versions/node/v10.18.1/bin/node
 - Yarn: 1.21.1 - /usr/local/bin/yarn
 - npm: 6.13.4 - ~/.nvm/versions/node/v10.18.1/bin/npm
## npmPackages:
 - @loadable/babel-plugin: ^5.10.3 => 5.12.0
 - @loadable/component: ^5.10.3 => 5.12.0
 - @loadable/server: ^5.10.3 => 5.12.0
 - @loadable/webpack-plugin: ^5.7.1 => 5.12.0

Please let me know if I can help clarify this in any way.
Thanks !

wontfix

Most helpful comment

This is a bug

All 7 comments

Hey @quentind :wave:,
Thank you for opening an issue. We'll get back to you as soon as we can.
Please, consider supporting us on Open Collective. We give a special attention to issues opened by backers.
If you use Loadable at work, you can also ask your company to sponsor us :heart:.

You can distinguish them by assigning cacheKey

const Content = loadable(
  () => import('./content.js'), 
  {
      cacheKey: () => 'test-1' // 'test-2'
  }
);

Thank for you feedback @kaysonwu.

Unfortunately, even with a cacheKey, both content.js modules get bunched together in a single file as demonstrated here: https://github.com/quentind/loadable-components/tree/with-cachekey

ah!Or use webpackChunkName to distinguish.

const Content = loadable(() => import(/* webpackChunkName: "page1-content" */ './content.js'))

This issue has been automatically marked as stale because it has not had recent activity. It will be closed if no further activity occurs. Thank you for your contributions.

This is a bug

This issue has been automatically marked as stale because it has not had recent activity. It will be closed if no further activity occurs. Thank you for your contributions.

Was this page helpful?
0 / 5 - 0 ratings

Related issues

lauterry picture lauterry  ·  6Comments

wellyshen picture wellyshen  ·  7Comments

gcardella picture gcardella  ·  7Comments

gregberge picture gregberge  ·  6Comments

sinwailam193 picture sinwailam193  ·  6Comments