Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How does Dynamic Import in webpack works when used with an expression?

How does the bundling happens when you use something like this:
const module = import(`folder1/${someExpression}`);
I mean, I do understand when you pass a plain string to it, but how does webpack understands all the possible outcomes?
Is this a good pattern?
Does it bundle all the files from that folder?
If so, it bundles them all together and does it recursively?

like image 319
marcelo-ferraz Avatar asked May 25 '20 03:05

marcelo-ferraz


People also ask

How does webpack dynamic import works?

Whenever you import a file in your code, Webpack will look for it in the project directory and copy it to the build folder with a new name, then Webpack replaces the import code in your bundled JavaScript file with the path to the newly copied file.

How do you dynamically import a module using a function?

To load dynamically a module call import(path) as a function with an argument indicating the specifier (aka path) to a module. const module = await import(path) returns a promise that resolves to an object containing the components of the imported module. } = await import(path);

How does webpack import work?

Webpack is a command line tool to create bundles of assets (code and files). Webpack doesn't run on the server or the browser. Webpack takes all your javascript files and any other assets and transforms then into one huge file. This big file can then be sent by the server to a client's browser.

What is the use of dynamic import?

The import() call, commonly called dynamic import, is a function-like expression that allows loading an ECMAScript module asynchronously and dynamically into a potentially non-module environment.


1 Answers

So, I bumped into this question that gave me an idea on how it works and what to search for. I am posting here so it can help someone else.
The key here is to use Magic Comments. From the the docs:

Inline comments to make features work. By adding comments to the import, we can do things such as name our chunk or select different modes.

webpackMode
It will tell how webapack should bundle your assets. You mark your imports as such: import(/* webpackMode: "lazy" */`./locales/${language}.json`)

  • 'lazy' (default): Generates a lazy-loadable chunk for each import()ed module.
  • 'lazy-once': Generates a single lazy-loadable chunk that can satisfy all calls to import(). The chunk will be fetched on the first call to import(), and subsequent calls to import() will use the same network response. Note that this only makes sense in the case of a partially dynamic statement, e.g. import(./locales/${language}.json), where multiple module paths that can potentially be requested.
  • 'eager': Generates no extra chunk. All modules are included in the current chunk and no additional network requests are made. A Promise is still returned but is already resolved. In contrast to a static import, the module isn't executed until the call to import() is made.
  • 'weak': Tries to load the module if the module function has already been loaded in some other way (e.g. another chunk imported it or a script containing the module was loaded). A Promise is still returned, but only successfully resolves if the chunks are already on the client. If the module is not available, the Promise is rejected. A network request will never be performed. This is useful for universal rendering when required chunks are always manually served in initial requests (embedded within the page), but not in cases where app navigation will trigger an import not initially served.

You can also make use of combinations with other magic comments, such as:

  • /* webpackMode: "lazy-once", webpackChunkName: "all-i18n-data", webpackPrefetch: true */,
    • will bundle all the possible assets in one bundle, name it as all-i18n-data and will instruct the browser to prefetch in idle time after the parent module is loaded
  • /* webpackMode: "lazy", webpackChunkName: "[request]", webpackPreload: true */,
    • will bundle all the possible assets in separate bundles, name them as as the string of your request and request it as the parent module is requested.

I hope it helps! For something a little more in depth:

  1. the stackoverflow question mentioned above
  2. https://github.com/webpack/webpack/issues/4807
  3. documentation for the dynamic imports and Magic Comments
  4. code splitting, pre-fetching and pre-loading
like image 58
marcelo-ferraz Avatar answered Nov 01 '22 22:11

marcelo-ferraz