Module Providers for Lightning Web Runtime on Node.js
Module providers locate and serve modules for your web app. Your project's LWR server contains a module registry, which maintains a list of available module providers and helps match module requests to a valid module provider.
All Lightning Web Runtime on Node.js (LWR-JS) apps automatically include default module providers that support common module types, like static file system modules and packaged Lightning web components (LWCs). If you want to use ECMAScript (ES) modules from other sources, you can import a module provider or create a custom module provider.
This flexibility ensures that your runtime is small for simple use cases, but LWR-JSS can support more complex applications if needed.
You project automatically includes these module providers.
This module provider generates only the Application Bootstrap Module. You need it for your website to load correctly.
The Router Module Provider generates a router based on a static JSON file.
The LWC Module Provider locates and serves Lightning Web Components (LWC) modules for your app. LWCs are special instances of ES modules that extend the LightningElement
class. They have to be processed by the LWC compiler before a module provider can serve them.
This module provider locates and serves all of the Node Package Manager (npm) ES modules from your project's node_modules
directories.
The LWR-JS Externals Module Provider creates module definitions based on the externals in your project's bundle configuration (bundleConfig
).
With LWR-JS, you can add an existing module provider to your project. For example, the LWR Label Module Provider exposes capabilities for scoped module label support (@salesforce/label/*
). You can add this tooling to your application via the @lwrjs/label-module-provider
npm package.
To add an optional module provider to your project, first install the package using npm
on the command line interface (CLI). For example, this code installs the Label Module Provider.
Then, add the module provider plugin to your lwr.config.json
file. Remember to include the default module providers in the moduleProviders
array. Here's how to add the Label Module Provider to your app's config file.
The moduleProviders
array overwrites the default LWR array. You have to list all the module providers needed by your app, including the default LWR ones listed in Default Module Providers.
That configuration lets your application components statically import labels sourced from JSON files in your project’s $rootDir/src/labels
directory, like this:
You can add these module providers to your LWR-JS project.
If you want your app to use a custom module that can't be served by one of the default module providers, add a custom module provider to your project. You can create a custom ES provider or a custom LWC provider.
In this section, we'll walk through how to create and implement a custom ES provider. We can boil this process down into three steps.
- Create the module provider.
- Configure
getModuleEntry()
andgetModule()
. - Register the module provider.
To create an ES module provider, implement the ModuleProvider
LWR interface. You have to give the module provider a name, but the version
property is optional.
Save this file in your app's src
folder. For example, the sample module provider es-custom-provider
is nested in src/services
.
Module providers rely on getModuleEntry()
and getModule()
to match module requests to module providers and help compile modules. You should customize these functions for your custom module provider.
When your LWR server receives a request for a module – like someone loading a webpage – the module registry calls getModuleEntry()
on all of its module providers. The first module provider to correctly handle this request is assigned to serve the requested module.
The module registry passes these two arguments into getModuleEntry()
.
- A module ID, which contains the module's
specifier
(a unique ID value). RuntimeParams
, a map of unique requirements for the requested page. For example, it could include a requirement for a specificlocale
.
The function returns a ModuleEntry
object that contains information from a valid module provider and the module request.
You should customize the information in ModuleEntry
based on your custom module provider and the module it serves.
id
- At a minimum, include the module'sspecifier
and the module provider'sversion
. If the moduule is locale-specific, include thelocale
value fromRuntimeParams
.virtual
- If module code from your provider is generated from scratch, set this totrue
. If it's read off of a file system or another source, set this tofalse
.entry
- Set this to the module's filepath. If the module is virtual, ensure the path includes thespecifier
.version
- Set this to the module provider's version.
Here's an example of a ModuleEntry
object returned by a custom module provider.
When the module registry validates that a module provider can fulfill a module request, the registry calls getModule()
. getModule()
takes the same arguments as getModuleEntry()
. It returns a ModuleCompiled
object.
To register a custom module provider, add it to your project's lwr.config.json
file. Make sure that TypeScript has been transpiled into JavaScript.
The moduleProviders
array overwrites the default LWR array. You have to list all the module providers needed by your app, including the default LWR ones listed in Default Module Providers.
Alternatively, you can pass your configuration from lwr.config.json
to a module provider constructor. The configuration can be any JSON object or primitive type.
The configuration and ProviderContext
(from the LWR server) are passed into the module provider constructor.
LWCs are special instances of ES modules that extend the LightningElement
class. Before a module provider serves LWCs, they have to be processed by the LWC compiler.
The easiest way to create a custom LWC module provider is to extend the LwcModuleProvider
class from the package @lwrjs/lwc-module-provider
.
To adapt the LWC module provider for your LWR app, override getModuleEntry()
and getModuleSource()
. The getModule()
function of the superclass handles compilation of the LWC.