vite-plugin / vite-plugin-dynamic-import

Enhance Vite builtin dynamic import
https://www.npmjs.com/package/vite-plugin-dynamic-import
MIT License
191 stars 11 forks source link

Dynamically-imported chunks import other dynamically-imported chunks that they shouldn't #12

Open stereokai opened 2 years ago

stereokai commented 2 years ago

Sorry for the confusing title. Allow me to quickly explain:

I'm on the latest versions of this plugin and vite. I have this code which dynamically imports a module: const chart = await import(`@/renderers/${renderer}/${renderer}.js`); (That's a link, in case you want to see the source code)

Here's a short description of my usage:

  1. At run time, that line will choose 1 module out of a few available options.
  2. These modules share a few common imports, and all of them also have exclusive dependencies, that are not imported by any other module.
  3. The app is also built so that only one of these modules is ever called, so they never run simultaneously.
  4. These modules also don't import each other, and naturally, they don't import the exclusive dependencies of the other modules.

In reality, however, my bundle ends up with these modules importing each other:

  "assets/echarts.renderer.4cf1a1d8.js": {
    "chunkName": "echarts.renderer",
    "isDynamicEntry": true,
    "imports": [
      "assets/workerpool.47e82dea.js", // dependency of a common import, should be imported
      "assets/echarts.f2fcefab.js", // exclusive dependency, should be imported
      "assets/d3fc.renderer.7df595b8.js" // another top-level module: SHOULD NOT BE IMPORTED
    ]
  },
  "assets/lightningchart.renderer.b6d85ecf.js": {
    "chunkName": "lightningchart.renderer",
    "isDynamicEntry": true,
    "imports": [
      "assets/d3fc.renderer.7df595b8.js", // another top-level module: SHOULD NOT BE IMPORTED
      "assets/echarts.renderer.4cf1a1d8.js", // another top-level module: SHOULD NOT BE IMPORTED
      "assets/lcjs.2f258342.js" // exclusive dependency, should be imported
    ]
  },
  "assets/uplot.renderer.ba13ce3a.js": {
    "chunkName": "uplot.renderer",
    "isDynamicEntry": true,
    "imports": [
      "assets/d3fc.renderer.7df595b8.js", // another top-level module: SHOULD NOT BE IMPORTED
      "assets/echarts.renderer.4cf1a1d8.js", // another top-level module: SHOULD NOT BE IMPORTED
      "assets/uplot.a2bc4425.js", // exclusive dependency, should be imported
      "assets/d3.7530ac4e.js", // dependency of another top-level module: SHOULD NOT BE IMPORTED
      "assets/vendor.ce91b36d.js", // dependency, should be imported
      "assets/workerpool.47e82dea.js", // dependency of a common import, should be imported
      "assets/echarts.f2fcefab.js" // dependency of another top-level module: SHOULD NOT BE IMPORTED
    ]
  },

Is there any way to control this behavior? Thanks a lot!!!

caoxiemeihao commented 2 years ago

Hey! I'm glad to see you again. πŸ˜„

You can try to configure options.onFiles

/**
 * If you want to exclude some files  
 * e.g `type.d.ts`, `interface.ts`
 */
onFiles?: (files: string[], id: string) => typeof files | void

https://github.com/vite-plugin/vite-plugin-dynamic-import#api

stereokai commented 2 years ago

Hey, me too 😎 Thanks for your help!

Can you please explain this setting onFiles? I'm not sure I fully understand it, or how to use it to solve my problem. Allow also me to clarify one critical point that I did not make fully clear:

  "assets/uplot.renderer.ba13ce3a.js": {
    "chunkName": "uplot.renderer",
    "isDynamicEntry": true,
    "imports": [
      "assets/d3fc.renderer.7df595b8.js", // another top-level module: SHOULD NOT BE IMPORTED
      "assets/echarts.renderer.4cf1a1d8.js", // another top-level module: SHOULD NOT BE IMPORTED
      "assets/uplot.a2bc4425.js", // exclusive dependency, should be imported
      "assets/d3.7530ac4e.js", // dependency of another top-level module: SHOULD NOT BE IMPORTED by this chunk, but can be imported dynamically
      "assets/vendor.ce91b36d.js", // dependency, should be imported
      "assets/workerpool.47e82dea.js", // dependency of a common import, should be imported
      "assets/echarts.f2fcefab.js" // dependency of another top-level module: SHOULD NOT BE IMPORTED by this chunk, but can be imported dynamically
    ]
  },
caoxiemeihao commented 2 years ago

It looks like Rollup's behavior. I need some time to figure it out. πŸ˜…

stereokai commented 2 years ago

Oh no πŸ˜… I tried debugging it myself but wasn't yet successful in figuring it out 🀯

stereokai commented 2 years ago

@caoxiemeihao Have you had a chance to take another look at this?

If you could give me pointers on where inside Rollup I should look, that would help me debug it myself, because I get lost in there pretty quick! πŸ˜…

caoxiemeihao commented 2 years ago

I'd like to know where your data came from

  "assets/uplot.renderer.ba13ce3a.js": {
    "chunkName": "uplot.renderer",
    "isDynamicEntry": true,
    "imports": [
      "assets/d3fc.renderer.7df595b8.js", // another top-level module: SHOULD NOT BE IMPORTED
      "assets/echarts.renderer.4cf1a1d8.js", // another top-level module: SHOULD NOT BE IMPORTED
      "assets/uplot.a2bc4425.js", // exclusive dependency, should be imported
      "assets/d3.7530ac4e.js", // dependency of another top-level module: SHOULD NOT BE IMPORTED by this chunk, but can be imported dynamically
      "assets/vendor.ce91b36d.js", // dependency, should be imported
      "assets/workerpool.47e82dea.js", // dependency of a common import, should be imported
      "assets/echarts.f2fcefab.js" // dependency of another top-level module: SHOULD NOT BE IMPORTED by this chunk, but can be imported dynamically
    ]
  },
stereokai commented 2 years ago

Using rollup-plugin-extract-bundle-tree