'Benefits of using autoloader with js modules?

In my workplace I've been told by my supervisor to use autoloaders instead of using many import statements since it's slow! First of all, based on my research there are no performance benefits of doing so and secondly(I'm using js modules, and we are not talking about bundles), I can't think of any good reasons for doing such thing. The way my imports work now are: Imagine we import a.mjs like so -> import '/js/components/a.mjs' The route /js/ is a rule that redirects to my root of static js files, so I don't even need to use relative paths. Is it bad practice? If there is something that I'm missing anything please tell me; I've done my research and didn't find any reasons to use autoloaders with js modules.

An actual example for you to see:

Flask route rule:

@app.route('/js/<path:filename>')
def js(filename):
    return send_from_directory(Path(app.root_path).parent.absolute().joinpath("static\\js"), filename)

and in my js files:

import {View} from "/js/common.mjs";
import Spinner from "/js/components/spinner.mjs";
import RecommendedTripsSlider from "/js/components/recommended-trips-slider.mjs";
import TripsSlider from "/js/components/trips-slider.mjs";
import Blogs from "/js/components/blogs.mjs";

Thank you for your time. I appreciate it.



Solution 1:[1]

From the JavaScript Modules Guide on MDN :

Modules are only executed once, even if they have been referenced in multiple <script> tags.

This can be verified in the spec under section 16.2.1.5.2 Evaluate.

Evaluate creates and returns a Promise which resolves when the module has finished evaluating. This Promise is stored in the [[TopLevelCapability]] field of the [[CycleRoot]] for the component. Future invocations of Evaluate on any module in the component return the same Promise.

The first time the browser needs a module, it is hoisted, loaded, cached and executed. Additional import statements in future scripts will reference the pre-evaluated module from memory. No additional HTTP requests need to be made. No additional execution needs to happen.

On subsequent page views, the locally cached version of the module will be used, assuming your server's caching policy is configured appropriately, or you've implemented caching with a service-worker. In fact, you can even preload any specific modules that you might need ahead of time.

Performance-wise, as long as your app isn't importing hundreds of modules you should be fine. At that point you should probably look into bundling related components together with tree shaking. However, monolithic app bundles should be avoided as they obliterate the benefits gained from using modules since one small change to a single component means your users now have to re-fetch the entire app. Keeping your components split up means that user agents only download the parts needed to display the content on the page they're on and nothing more.

One reason you might want to use a module loader/bundler would be if you were installing dependencies through a package manager like npm. Then you would need a way to resolve the named imports to their actual file paths. But that process can easily be handled without a build step by using import-maps.

<script type="importmap">
  {
    "imports": {
      "moment": "/node_modules/moment/src/moment.js",
      "yourlib": "/lib/yourlib.js"
    }
  }
</script>

Unfortunately, this feature is not available in all browsers yet but. This already works in Chromium based browsers, has recently been implemented in Firefox (slated for release in v102) and support for other browsers can be polyfilled with es-module-shims.

This is the future of native module resolution. Implementing an autoloader into your project now would be a step backwards.

Sources

This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.

Source: Stack Overflow

Solution Source
Solution 1