Doing dynamic imports in Vite/Rollup with an arbitary directory depth
02:43 22 Dec 2025

In Vite and Rollup (with @rollup/plugin-dynamic-import-vars), it is possible to declare a dynamic import in code:

import(`./components/${name}.js`);

The code is analysed at build-time and Rollup will create a chunk for every file matching the glob ./components/*.js. Then, at run-time, the Rollup-processed version of the code will import the correct chunk, based on the runtime value of name. This strategy works on dynamic imports with a directory depth of one.

It's also possible to do other directory depths, so long as every chunk has the same depth:

import(`./components/${superName}/${subName}.js`);

For this case, Rollup will consider any file matching the glob ./components/*/*.js.

I have a more complicated structure to my components folder:

components/
├─ Baz.js
├─ FooBar/
│  ├─ Bar.js
│  ├─ Foo.js
├─ Qux.js

Here, the directory depth is arbitrary, specific to the file. Baz.js and Qux.js have a depth of one, and can be imported with ./components/${name}.js, while Bar.js and Foo.js have a depth of two, and have to be imported with ./components/${superName}/${subName}.js. (In my actual real-world situation, there are even deeper files.)

Ideally, I'd want to write the code somewhat like this, where pathAndName could be Baz, FooBar/Bar, FooBar/Foo, or Qux:

import(`./components/${pathAndName}.js`);

Unfortunately, Rollup and Vite don't seem to have a way to handle this situation. The glob I'd want Rollup to match with would be ./components/**/*.js. However, @rollup/plugin-dynamic-import-vars's documentation insists:

Globs only go one level deep

When generating globs, each variable in the string is converted to a glob * with a maximum of one star per directory depth. This avoids unintentionally adding files from many directories to your import.

And if I try my desired code, I get an error like the following in the browser:

Error: Unknown variable dynamic import: ./components/FooBar/Bar.js. Note that variables only represent file names one level deep.

If this were Webpack, I'd have done the following, and it would be no problem:

import(
    /* webpackInclude: /\.js$/ */
    `components/${chunk_name}`
);

So, is there a way to do this? A plugin I've missed in my searching? Some other way that I'm intended to do this? Or is the advice just "Don't do this, it's bad, and here's why"?

javascript vite rollup rollupjs