Aurelia 2 bundling portions of application

In Aurelia v1, the second parameter of PLATFORM.moduleName advises the bundler to divide a specific set of app code into a separate bundle. How do we accomplish this in v2? Any chance we can also use dynamic imports in supported browsers to load the bundles on-demand?

2 Likes

That is a webpack thing only.

1 Like

I understand the limitation, should have made that clear. Just curious if we’ll see it in Aurelia 2 and how that will work since PLATFORM.moduleName will no longer benecessary, as I understand it.

1 Like

Aurelia 2 doesn’t have runtime magic, this simplified lots of implementation. For dynamic loading, Aurelia 2 relies on standard ESM feature: dynamic import().

In Aurelia 2, To use a resource (custom element, or route component), the code needs to explicitly import that resource.

In js/ts

import {SomeResource} from './some-resource';
// Then use SomeResource directly in code

In html

<import from="./some-resource"></import>

You can write <require from... too, require and import tags are same in Aurelia 2.
The Aurelia 2 conventions is implemented as a bundler plugin (for webpack, it’s @aurelia/webpack-loader), the plugin translates html into js code, the above import tag is translated into

import * as d0 from './some-resource';
// Then d0 is used as a dependency of this custom element

This is very different from Aurelia 1, where Aurelia 1 deals with <require> tag at runtime. Aurelia 2 does it at compile time.

So, there is no magic to accept a module id string as a resource in Aurelia 2, it’s all translated into static import.

In Aurelia 1, PLATFORM.moduleName is introduced as a hint for webpack to pick up the module id string, in order to bring in dependency.

In Aurelia 1, module id string gave Aurelia the flexibility to lazy load a resource. It only starts to request the resource module when it’s firstly used in the app UI. Whether it’s in currently loaded js bundle (or call chunk), or additional bundle to be loaded, it doesn’t matter.

In Aurelia 2, most resources are loaded statically, so you lose the default lazy load behaviour in Aurelia 1. In some use case you do need lazy loading, for example a route component, Aurelia 2 allows you to supply a promise, normally implemented with dynamic import().

() => import('./another-route')

This is a pattern you probably have seen in many other frameworks’ router.

I am pretty sure the new router in Aurelia 2 supports lazy loading, but I have not tried it. @jwx probably can provide you a better example.

When you use dynamic import() to lazy load a module, some bundlers provide automatic code splitting, some may require little config. You can refer to bundler document for the details.

4 Likes

@huochunpeng Thanks for the explanation of how this is done in Aurelia 2. What about global custom elements? Is it still possible to lazy load them in Aurelia 2?
We have implemented our own way of lazy loading those in Aurelia 1 as described here: Lazy load global custom elements.

1 Like

The 2 main API surfaces for lazy loading in au2 are:

  • Dynamic composition (e.g. passing the promise from import('./my-module.js') to <au-compose>)
  • Routing (either manually dynamically loading a module and passing it into the router, or having lazy loaded child routes (API for this still in progress))

What’s the benefit of lazy loaded global resources instead of lazy loaded scoped resources though? Assuming bundlers take care of the same module only being loaded once…

2 Likes

Do you know wheather the webpack chunkname syntax will be supported in Aurelia 2?

 import(/* webpackChunkName: "my-module/lazy" */ './my-module')

We use this to structure the output of a big business application with lots of modules. In Aurelia 1 we’re able to write it like:

PLATFORM.moduleName('./my-module', 'my-module/lazy')
1 Like

Yes, this will work OOTB because we use native modules

2 Likes

Thanks!

In our use case, our customers can build their own “apps” based on Aurelia and install them into our platform (also based on Aurelia). We then guarantee that they can use a set of custom elements build by us, e.g. <sci-list-view>, <sci-grid>, etc. We have a lot of these <sci-*> custom elements build with Aurelia, but we don’t want to load these just before they are actually required by some component in one of our customer’s apps - otherwise we would have a very slow startup of the entire platform.

This is our use-case for lazy-loading custom elements :slight_smile: Hope it makes sense.

1 Like