ES Modules

All JavaScript files in Lightning web components are ES modules. An ES module is a JavaScript file that explicitly exports variables or functions that other modules can import and use.

A Lightning web component that renders UI consists of an HTML template and an ES module.

<!-- example.html -->
<template>
    My Component
</template>

The ES module of a UI component must import LightningElement from lwc, which is the core module of Lightning Web Components. The default export must be a class that extends LightningElement, which is a custom wrapper of the standard HTML element.

// example.js
import { LightningElement } from 'lwc';

export default class Example extends LightningElement {

}

To share code between components, create an ES module that acts as a library (also known as a service component). Export the variables or functions that you want to share, and then import them into other modules that want to use them.

Module Resolution

Because ES modules import other modules, at build time the compiler has to find all the module files. This process is called module resolution.

Module resolution provides a uniform way to build and use modules across multiple repos and npm packages. You can import components from anyone by using just npm. You can also distribute your own components via npm.

Configure Module Resolution

To tell the compiler how to resolve modules, add configuration information at the root of the project. There are two ways to configure module resolution.

// package.json
{
    "name": "my-app",
    "version": "1.0.0",
    "lwc": {
        "modules": [
            /* list of module records */
            {
              "dir": "src/modules"
            },
        ]
    }
}
// lwc.config.json
{
    "modules": [
        /* list of module records */
        {
            "dir": "src/modules"
        },
    ]
}

The modules key holds an Array of ModuleRecords. A module record is an object with a specific shape depending on the type of module record it holds. You need at least one ModuleRecords entry that points to your local source. There are three types of ModuleRecords.

{
    "modules": [
        {
            "dir": "src/modules"
        },
        {
            "name": "ui/button",
            "path": "src/modules/ui/button/button.js"
        },
        {
            "npm": "lwc-recipes-oss-ui-components"
        }
    ]
}

Specificity is resolved from inner to outer, merging upwards.

Distribute Your Component Using npm

As we just learned, NpmModuleRecord loads Lightning web components that are published in npm packages. Lightning web components are published to npm as source code. The consumer of the npm package must compile the components part of the package.

To distribute your own Lightning Web Components package via npm, explicitly define which components from your project to expose. Use the expose key in the lwc.config.json or package.json file.

{
    "modules": [
        {
            "dir": "src/modules"
        }
    ],
    "expose": [
        "ui/button",
        "ui/card",
        "ui/input",
        "ui/navfooter",
        "ui/output",
        "ui/select"
    ]
}

Resources

This document relies on the module resolution feature specification, which is public, and on a blog post from Salesforce Architect, Developer Evangelism, René Winkelmeyer. For more information, please read these documents.