Releases: salesforce/lwc
v6.3.2
What's Changed
- fix: disable form association entirely on older API versions by @nolanlawson in #4041
- Revert "fix(synthetic-shadow): retargeting does not correctly account for native shadow roots" by @ekashida in #4047
- chore: routine dependencies update by @ravijayaramappa in #4046
- chore: release v6.3.2 by @ravijayaramappa in #4049
Full Changelog: v6.3.0...v6.3.2
v6.3.1
What's Changed
- test: add test for wired properties from consts by @nolanlawson in #4032
- refactor: apply
formAssociated
on demand and enable forCustomElementConstructor
by @jmsjtu in #4035
Full Changelog: v6.3.0...v6.3.1
v6.3.0
Full Changelog: v6.3.4...v6.3.0
What's Changed
- refactor: move fragment cache-busting to Karma-only by @nolanlawson in #4025
- fix(template-compiler): avoid mutating the ast when binding complex template expressions by @ekashida in #4026
- docs: add more JSDoc for top-level exports @W-13278716 by @wjhsf in #4028
- chore: avoid @ts-ignore by @wjhsf in #4027
- test: enable test for native shadow by @ekashida in #4031
- fix: event listener not being invoked for native web components by @jye-sf in #4012
- feat: support generating inlined sourcemaps when transforming js file… by @jye-sf in #4033
- fix(template-compiler): avoid discarding text content whitespace for complex expressions by @ekashida in #4029
Full Changelog: v6.2.1...v6.3.0
v6.2.1
What's Changed
- fix: isObject doesn't actually narrow down to just an object by @wjhsf in #4003
- docs: add JSDoc for @lwc/shared language features @W-13278716 by @wjhsf in #4007
- chore(eslint): add JSDOC plugin @W-13278716 by @wjhsf in #4006
- chore: pin CI tests to chrome 121 by @nolanlawson in #4010
- test(integration-karma): improve lifecycle timing tests by @nolanlawson in #4009
- chore: more JSDoc rules! @W-13278716 by @wjhsf in #4008
- fix(synthetic-shadow): retargeting does not correctly account for native shadow roots by @ekashida in #4018
- chore: update dependencies by @rui-rayqiu in #4019
- test: add tests for invocation order in light DOM by @nolanlawson in #4016
- docs: add JSDoc for some exports @W-13278716 by @wjhsf in #4014
- fix: revert update to karma to see if the intermittent test failure is caused by this by @rui-rayqiu in #4021
- test: add test to confirm export behavior by @nolanlawson in #4022
- chore: release v6.2.1 by @rui-rayqiu in #4023
- chore: release v6.2.1 by @rui-rayqiu in #4024
Full Changelog: v6.2.0...v6.2.1
v6.2.0
Contains signal implementation in LWC and a few other bug fixes.
What's Changed
- feat: signals implementation v1 by @jmsjtu in #3963
- feat: add reporting for shadowSupportMode by @jye-sf in #3980
- refactor: disable
formAssociated
on custom element constructor by @jmsjtu in #3984 - chore: Update target to es2021 by @ekashida in #3988
- chore: remove punctuation from filenames by @wjhsf in #3994
- chore: facilitate manual type checking @W-15023469 by @wjhsf in #3992
- chore: leverage the full power of @typescript-eslint @W-15024672 by @wjhsf in #3995
- refactor: avoid calling traverseAndSetElement on every rerender by @jmsjtu in #3998
- fix: add default exports to
lwc
@W-13710298 by @wjhsf in #3997 - build(deps): bump ip from 1.1.8 to 1.1.9 by @dependabot in #4001
- chore: release v6.2.0 by @rax-it in #4004
- chore: release v6.2.0 by @rax-it in #4005
New Contributors
Full Changelog: v6.1.1...v6.2.0
v5.0.9
v5.0.8
v6.1.1
What's Changed
- fix(hydration): force native shadow when synthetic exists by @nolanlawson in #3907
- chore: warn on shadowSupportMode 'any' by @ekashida in #3972
- fix(engine-dom): support LWC v5 compiler slot format by @nolanlawson in #3973
- chore: release v6.1.1 by @nolanlawson in #3976
- chore: release v6.1.1 by @nolanlawson in #3977
Full Changelog: v6.1.0...v6.1.1
v6.1.0
What's Changed
- fix: use more helpful error message for invalid render() return value @W-14785069 by @wjhsf in #3943
- chore: improve license header checks @W-14846456 by @wjhsf in #3951
- test(errors): validate error object shapes and unique codes @W-14841223 by @wjhsf in #3949
- feat: allow computed properties in @wire if they are constants or primitives @W-14785085 by @wjhsf in #3955
- refactor: remove
shadowSupportMode = 'any'
by @jmsjtu in #3953 - chore: update non-breaking deps by @nolanlawson in #3966
- chore(copyright): update rollup config to use correct copyright by @wjhsf in #3967
- chore: fix broken test due to Firefox update by @nolanlawson in #3968
- refactor: remove polyfill globalThis by @SaurabhMulay999 in #3960
- chore: release v6.1.0 by @nolanlawson in #3969
- chore: release v6.1.0 by @nolanlawson in #3970
New Contributors
- @SaurabhMulay999 made their first contribution in #3960
Full Changelog: v6.0.0...v6.1.0
v6.0.0
LWC v6.0.0 contains breaking changes. Please read carefully below if you are upgrading from v5.
If you are upgrading from v4, please upgrade to v5 first.
Note
LWC v6 corresponds to Salesforce release Summer '24 (API version 61).
Summary of new features
- Form-Associated Custom Elements (FACE) and Element Internals are now supported.
Summary of breaking change
- Native custom element lifecycle
- Fixed light DOM slot remapping
- Standard
shadowrootmode
attribute in SSR
Breaking changes
Native custom element lifecycle
Note
This change currently only applies to consumers of the LWC open-source project outside of the Salesforce Lightning platform.
Previous versions of LWC used a synthetic (polyfill) system to call the connectedCallback
and disconnectedCallback
component lifecycle hooks. This was originally designed for legacy browsers such as Internet Explorer 11. Such browsers are no longer supported, and LWC v6 uses the native browser APIs instead.
Important
Native vs synthetic custom element lifecycle is not the same as native vs synthetic shadow DOM. They are two entirely separate concepts.
This change may affect the firing of connectedCallback
and disconnectedCallback
hooks in your components, since the previous implementation did not perfectly align with the browser standard. Most commonly, this will occur in unit tests, or when manually creating components using the lwc.createElement()
API. The new behavior also fixes common memory leaks caused by disconnectedCallback
not firing consistently.
Native custom element lifecycle also unlocks support for Form-Associated Custom Elements (FACE) and Element Internals.
Changes you may see to connectedCallback
and disconnectedCallback
behavior:
- New behavior when disconnected from the DOM
- New error behavior
- New timing behavior in native shadow DOM
- Shadow roots may be null after appending to disconnected elements
- New timing behavior during list rendering
New behavior when disconnected from the DOM
Note
This situation will probably only occur when writing tests that do not connect elements to the DOM.
LWC components now only fire connectedCallback
when they are actually connected to the DOM. If they are disconnected from the DOM (i.e. they are not inside the document
), then connectedCallback
will not fire.
For instance, if you are testing for an event to be fired from a connectedCallback
, this would previously work:
export default class Foo extends LightningElement {
connectedCallback() {
this.dispatchEvent(new CustomEvent('foo', { bubbles: true, composed: true }))
}
}
const element = createElement('x-foo', { is: Foo })
const div = document.createElement('div')
div.addEventListener('foo', () => {
console.log('received foo event!')
})
div.appendChild(element) // triggers connectedCallback
In the above example, received foo event!
would be logged to the console.
After this change, the above no longer triggers the connectedCallback
, nor the event.
Instead, you must ensure the element is connected to the DOM:
document.body.appendChild(div)
Once the element is in the DOM tree, connectedCallback
will fire as expected.
New error behavior
Note
This situation will probably only occur if you are writing tests to capture errors thrown in connectedCallback
/disconnectedCallback
. Most component authors should never have to deal with this.
Errors thrown by connectedCallback
s and disconnectedCallback
are dispatched globally, rather than locally when elements are added/removed from the DOM.
For example, let's say you have a component that throws an error in connectedCallback
:
export default class Foo extends LightningElement {
connectedCallback() {
throw new Error('foo')
}
}
And then you expect to be able to catch the error synchronously on appendChild
:
const element = lwc.createElement('x-foo', { is: Foo })
try {
document.body.appendChild(element)
} catch (error) {
console.log('caught error', error)
}
- Old behavior: the error is caught.
- New behavior: the error is uncaught.
The solution is to use a global error
listener:
const listener = (error) => {
console.log('Caught error', error)
}
try {
window.addEventListener('error', listener)
document.body.appendChild(element);
} finally {
window.removeEventListener('error', listener)
}
If you're using @lwc/jest-*
, then you can use the new toThrowInConnectedCallback
API which will handle this logic for you.
Note
Events dispatched in connectedCallback
and disconnectedCallback
are unaffected by this change.
New timing behavior in native shadow DOM
The timing of connectedCallback
has changed slightly to align with native browser standards, when using native shadow DOM.
For example, the timing of when connectedCallback
fires in child components relative to parent components has changed. Consider this DOM tree:
<x-a>
#shadow-root
| <x-a-child>
</x-a>
<x-b>
#shadow-root
| <x-b-child>
</x-b>
<x-c>
#shadow-root
| <x-c-child>
</x-c>
Old behavior: the order of connectedCallback
s firing is:
x-a
x-b
x-c
x-c-child
x-b-child
x-a-child
New behavior: the order of connectedCallback
s firing is:
x-a
x-a-child
x-b
x-b-child
x-c
x-c-child
Note that, with the new behavior, connectedCallback
fires in standard DOM depth-first tree-traversal order. (The old behavior was defined by the synthetic lifecycle polyfill, and did not follow the standard.)
The relative timing of renderedCallback
has also changed due the new native connectedCallback
timing. For example, consider this DOM tree:
<x-grandparent>
<x-parent>
<x-child></x-child>
</x-parent>
</x-grandparent>
(Note that, in the above example, the <x-parent>
and <x-child>
are slotted, not part of the shadow roots of their containers.)
Old behavior: the order of lifecycle hooks firing is (example):
Component | Lifecycle hook |
---|---|
grandparent | connectedCallback |
parent | connectedCallback |
child | connectedCallback |
child | renderedCallback |
parent | renderedCallback |
grandparent | renderedCallback |
New behavior: the order of lifecycle hooks firing is (example):
Component | Lifecycle hook |
---|---|
grandparent | connectedCallback |
grandparent | renderedCallback |
parent | connectedCallback |
parent | renderedCallback |
child | connectedCallback |
child | renderedCallback |
Note that the above only applies to native shadow DOM. In synthetic shadow DOM, the ordering is the same, regardless of native vs synthetic custom element lifecycle (example). The same is true of light DOM (example).
In general, your components should not rely on the particular timing of connectedCallback
or renderedCallback
across components. In case they do, please update to match the new timing behavior, or make your code agnostic to any particular timing.
Note that the timing of disconnectedCallback
has not changed, except as noted elsewhere in these release notes.
Shadow roots may be null after appending to disconnected elements
Consider this case:
<!-- app.html -->
<template>
<x-child></x-child>
</template>
const elm = createElement("x-app", { is: App })
const div = document.createElement('div'...