Module Unification

Summary

One of the primary use-cases for LWC is to allow Lightning Web Components inside the Salesforce's platform. This platform has some constrains around the folder structure and files names, and we will have to align with those constrains. Additionally, we will like to have a comprehensive structure that is easy to understand that easy to reasoning, and ideally, it can map to existing mechanism of resolution (e.g.: NPM).

This proposal is about the bundle interface, not about the internals of the bundle, which means that existing invariants about the bundle's internal behavior continue to be valid.

Proposals

1. camelCase

Rules

Examples

Folder structure:

└── src
    └── modules
        ├── foo
        │   ├── list
        │   │   ├── list.html
        │   │   └── list.js
        │   └── listItem
        │       ├── listItem.html
        │       └── listItem.js
        └── lightning
            ├── button
            │   ├── button.html
            │   └── button.js
            ├── keyboardNav
            │   └── keyboardNav.js
            └── buttonGroup
                ├── buttonGroup.html
                └── buttonGroup.js

HTML Files:

<template>
    <lightning-button-group>
        <lightning-button></lightning-button>
    </lightning-button-group>
    <foo-list>
        <foo-list-item></foo-list-item>
    </foo-list>
</template>

JS Files:

import { something } from "foo/keyboardNav";

Compiled HTML Code:

import buttonGroup from "lightning/buttonGroup";
import button from "lightning/button";
import listItem from "foo/listItem";
import list from "foo/list";
function template() {
    // ...
}
export { template };

Ergonomics

SFDX Compliance

Force.com namespaces documentation can:

  1. Contain underscores
  2. Are case preserving though case-insensitive (eg customer registers Acme and the namespace can be referenced as acme or ACME in the various languages/tech)
<template>
    <mynamespace_foo-my-component_bar></mynamespace_foo-my-component_bar>
</template>

The compiler can analyze apply the heuristic, and produce the following import statement:

import C1 from "mynamespace_foo/myComponent_bar";`

And the platform can readjust the module specifier to match the internal representation, (e.g.: MyNamespace_Foo/myComponent_bar) to match the canonical version for bundle in folder MyNamespace_Foo/myComponent_bar/. This does not affect the compiler in any way since force.com's namespaces are technically case-insensitive.

Pros:

Cons

Edge Cases

  1. Bundle name starting with UpperCase:
<template>
    <foo--my-component></foo--my-component>
</template>

The compiler can analyze the double - in the name to apply the heuristic, and produce the following import statement:

import C1 from "foo/MyComponent";`
undefined