1

I use Vite api builder and with a custom plugin I replace some variables in the code, let's say I have const __CONFIG__ = {}; it's being replaced with a real object during the build. So for the compiler it will be just a plain object and based on it I want to include some components into my bundle.

I created a simplified example with 2 dynamic imports: one of them never executes. Despite of it, all 2 modules being included in the output bundle.

I tried different ways, for example this one includes all imports:

const getBasic = () => import('./BasicTemplate.svelte')
const getAdv = () => import('./AdvancedTemplate.svelte')

const imports = {
  'basic': getBasic,
  'advanced': getAdv,
}

const builder = async () => {
  const Component =  (await imports['advanced']()).default

  new Component({
    target: document.getElementById('app'),
  })
}

builder()

But this includes only 1 import:

const builder = async () => {
  if (false) {
    const Component =  (await import('./BasicTemplate.svelte')).default

    new Component({
      target: document.getElementById('app'),
    })
  }

  const Component =  (await import('./AdvancedTemplate.svelte')).default

  new Component({
    target: document.getElementById('app'),
  })
}

builder()

Is there any way to include only those modules which actually executed?

Georgy
  • 1,879
  • 2
  • 9
  • 14

1 Answers1

2

It doesn't feel particularly problematic that dynamic imports remain included in the final prod build, since they will still get code split into their own chunk, and their code won't be loaded if the import is never called.

That said, if you really want some "dead" code branches to be eliminated by the bundler, you need to write conditions that can be statically analyzed. An object is beyond what a bundler will try to parse, for sure.

Something like @rollup/plugin-replace would do, if the replacements are primitives.

Another option would be to use Vite's built-in support for environment variables, for example.

.env

VITE_TEMPLATE=advanced

And in code like this, the unused import will get eliminated from the prod bundle:

const getBasic = () => import("./lib/BasicTemplate.svelte");
const getAdvanced = () => import("./lib/AdvancedTemplate.svelte");

const builder = async () => {
  const getModule =
    import.meta.env.VITE_TEMPLATE === "advanced" ? getAdvanced : getBasic;

  const Component = (await getModule()).default;

  const cmp = new Component({
    target: document.body
  });
};

builder()
rixo
  • 23,815
  • 4
  • 63
  • 68
  • 1
    See also [`define`](https://vitejs.dev/config/shared-options.html#define). – H.B. May 19 '23 at 17:00
  • When using this code, if condition fails, does one expect to still see unused assets in build output? I'm trying to conditionally import images and video in a certain Vue component, based on build flag, and no matter what my assets output always includes unused assets. I've trying many techniques including yours. – Kalnode Aug 01 '23 at 14:43