lwc icon indicating copy to clipboard operation
lwc copied to clipboard

Unify compiler and engine packages

Open nolanlawson opened this issue 1 year ago • 1 comments

In many frameworks, it is common to npm install name-of-framework and import everything from that one package. For LWC, this would avoid the problem where a consumer of LWC has multiple @lwc/* / lwc packages with conflicting versions.

In short, this would mean making sure that npm install lwc gives you everything you need to run LWC. There would be no need to install a separate @lwc/compiler package.

nolanlawson avatar Aug 10 '22 17:08 nolanlawson

One (simple) way we could solve this would be to just add files like the following to the lwc package:

// compiler.js
module.exports = require('@lwc/compiler')
// engine-server.js
module.exports = require('@lwc/engine-server')
// rollup-plugin.js
module.exports = require('@lwc/rollup-plugin')

... and then we would add @lwc/compiler, @lwc/engine-server, and @lwc/rollup-plugin (etc.) to the dependencies of lwc. So consumers could do:

import compiler from 'lwc/compiler'
import { renderComponent } from 'lwc/engine-server'
import plugin from 'lwc/rollup-plugin'

Some advantages of this approach:

  • lwc is guaranteed to install the correct version of @lwc/compiler as its dependency.
  • No breaking changes. You can continue to use @lwc/compiler or lwc/compiler – both work. (If there are multiple conflicting versions installed, then well, you were going to have a bad time anyway.)
  • We don't have to worry about tree-shaking problems (which would arise from cramming everything into a single index.js file) – everything is neatly separated into different files

nolanlawson avatar Aug 10 '22 17:08 nolanlawson

We could do this in a backwards-compatible way, but it may make more sense to start with a clean slate:

  1. Using Node.js package exports
  2. Dropping CommonJS support
  3. Removing lwc/index.js and lwc/types.d.ts, which don't seem necessary if lwc is just exporting other packages

nolanlawson avatar Jan 26 '23 23:01 nolanlawson

I really like this plan!

pmdartus avatar Jan 27 '23 07:01 pmdartus

We can also do https://github.com/salesforce/lwc/issues/2430 while we're at it. lwc should just be a dumb package that re-exports other packages.

OTOH, https://github.com/salesforce/lwc/issues/2765 and https://github.com/salesforce/lwc/issues/3017 may be a lot harder to accomplish; there are ecosystem issues: https://github.com/salesforce/lwc/issues/3445#issuecomment-1504121029

nolanlawson avatar Apr 11 '23 23:04 nolanlawson

We should probably also make the default export of lwc something like:

module.exports = require('@lwc/engine-dom');

Otherwise it's kind of weird to have import { LightningElement } from 'lwc', and yet lwc doesn't actually export that

nolanlawson avatar May 12 '23 00:05 nolanlawson

This issue has been linked to a new work item: W-13659052

git2gus[bot] avatar Jun 26 '23 15:06 git2gus[bot]

@nolanlawson would you consider exporting the mutation tracker and membrane functionality as well? That would make it much easier under Salesforce environment to integrate custom more complex state management on top of the existing one if we've have access to membranes and their get/set/subscribe functionality. As I checked framework/main.ts does not export anything useful regarding membranes.

attilah avatar Jun 27 '23 18:06 attilah

@attilah Mutation tracker / observable-membrane are a bit special in that they get directly bundled into engine-dom/engine-server. In other words, they aren't dependencies, but rather devDependencies.

What is your use case for importing observable-membrane on its own?

nolanlawson avatar Jun 27 '23 19:06 nolanlawson