Releases: salesforce/lwc
v4.0.0
LWC v4.0.0 contains breaking changes. Please read carefully below if you are upgrading from v3.
If you are upgrading from v2, please upgrade to v3 first.
Note
LWC v5 corresponds to Salesforce release Spring '24 (API version 60).
Summary of breaking changes
- ARIA reflection global polyfill is removed
- TypeScript types have changed
- Light DOM may emit additional whitespace characters
- Decorators are disallowed on non-
LightningElement
classes - Babel object rest spread transpilation is removed
Breaking changes
ARIA reflection global polyfill is removed
Note
This change only applies to LWC usage outside Salesforce Lightning Experience. This includes Lightning Web Runtime, Jest tests, and off-core scenarios.
The global polyfill of the ARIA reflection API is removed from @lwc/engine-dom
. This affects the exposed ARIA APIs on built-in HTML elements.
Removal of non-standard ARIA APIs
Non-standard ARIA reflection APIs such as ariaActiveDescendant
and ariaLabelledBy
are no longer available on the global Element.prototype
. Use the getAttribute
/setAttribute
format instead:
Non-standard property | Standard attribute |
---|---|
ariaActiveDescendant |
aria-activedescendant |
ariaControls |
aria-controls |
ariaDescribedBy |
aria-describedby |
ariaDetails |
aria-details |
ariaErrorMessage |
aria-errormessage |
ariaFlowTo |
aria-flowto |
ariaLabelledBy |
aria-labelledby |
ariaOwns |
aria-owns |
Example of incorrect code:
div.ariaActiveDescendant = 'foo';
console.log(div.ariaActiveDescendant);
Example of correct code:
div.setAttribute('aria-activedescendant', 'foo');
console.log(div.getAttribute('aria-activedescendant'));
In LWC v3, if you are using these non-standard APIs, you will see a warning message in the console:
Element
<div>
owned by<x-foo>
uses non-standard property "ariaLabelledBy". This will be removed in a future version of LWC. See https://sfdc.co/deprecated-aria
LWC v4 is the "future version of LWC" mentioned in the warning.
Note that this change only applies to built-in HTML elements such as <div>
, <button>
, and <input>
. For a LightningElement
(e.g. <c-my-component>
), the non-standard APIs continue to be supported in LWC v4.
Removal of standard ARIA reflection global polyfill
Some browsers and environments, notably Firefox pre-119 and JSDOM, do not support standard ARIA reflection for properties such as role
and ariaLabel
. For maximum compatibility, you may use the attribute format instead:
element.role
->element.getAttribute('role')
element.ariaLabel
->element.getAttribute('aria-label')
If you are using the latest version of @lwc/jest-preset
, a polyfill is already included.
Deprecation of @lwc/aria-reflection
package
The @lwc/aria-reflection
package is considered deprecated. If you need it for backwards compatibility, you may install and import it separately:
import '@lwc/aria-reflection' // applies the polyfill
Note that, on Salesforce Lightning Experience, this polyfill is still in effect for backwards compatibility. However, this is transparent to LWC users.
- fix(engine-dom): remove ARIA reflection global polyfill (BREAKING CHANGE) by @nolanlawson in #3666
TypeScript types have changed
Note
This change only applies to TypeScript users.
If you are using TypeScript, you may need to update your types to align with the new typings. In particular, the types for @wire
and context providers have changed.
Light DOM may emit additional whitespace characters
Note
On the Salesforce Lightning platform, this change only applies to components with an API version of 60 or above.
Off-core consumers, or those bumping their component's metadata apiVersion
to 60+, will see additional empty text nodes rendered in light DOM slots. This can change use cases like the following:
renderedCallback() {
const myExpectedChildNode = this.childNodes[0];
}
In API versions <60, the above this.childNodes[0]
would resolve to the first slotted element in the light DOM component.
In API versions >=60, it will be an empty text node. This is due to the new system using VFragment
s to enclose light DOM slots, which means there is an additional empty text node before and after the slot.
Affected APIs are:
Component authors are encouraged to use lwc:ref
or this.querySelector
rather than relying on the exact makeup of child nodes. Using children
/firstElementChild
/lastElementChild
will also work, since text nodes are not elements (simply nodes).
Additionally, Jest snapshots will change to have additional whitespace, unless you have upgraded to lwc-test v13.0.0+.
- refactor: use fragments for slots in light DOM (BREAKING CHANGE) by @nolanlawson and @abdulsattar in #3649
Decorators are disallowed on non-LightningElement
classes
Note
On the Salesforce Lightning platform, this change only applies to components with an API version of 60 or above.
Previously, the following would not be a syntax error:
class MyCustomClass {
@api foo = 'foo';
}
In v60+, this will be a syntax error. The decorators @track
, @wire
, and @api
can only be used on LightningElement
classes. In the above case, MyCustomClass
does not extend
another class, so it cannot possibly be a LightningElement
class.
In this release,the unnecessary @track
, @wire
, and @api
decorators are now removed from class
es that do not extend another class
. This will cause a breakage in downstream JavaScript compilers such as Babel, unless they are otherwise configured to handle decorators.
This change was made to avoid functional bugs, such as when using Jest mocks containing a class
.
- fix(babel-plugin-component): skip unnecessary registerDecorators (BREAKING CHANGE) by @nolanlawson in #3660
Babel object rest spread transpilation is removed
Note
On the Salesforce Lightning platform, this change only applies to components with an API version of 60 or above.
For the object rest spread syntax (e.g. {...foo}
), LWC no longer emits the Babel transpiled version, and instead emits the native syntax (...
).
This is mildly breaking because it is observable. In particular, if you have a counter inside of a getter and are relying on the count to report a particular number, then this change will break you because the Babel transform does not behave exactly like the native behavior. E.g.:
let count = 0;
const {
foo: {
bar,
...quux
}
} = {
get foo() {
count++;
return { bar: 42 };
}
};
console.log(count); // Logs 2 for Babel, 1 for native
This is judged as extremely unlikely to break anyone, but it is technically a breaking change.
This change was made as part of a performance improvement, as the native syntax (...
) is much shorter than the transpiled syntax.
- perf(compiler): remove object rest spread (BREAKING CHANGE) by @nolanlawson in #3654
Full changelog
Full Changelog: v3.8.0...v4.0.0
v3.8.0
What's Changed
- build(deps): bump @babel/traverse from 7.23.0 to 7.23.2 by @dependabot in #3805
- fix(template-compiler): fix static listeners with deep paths by @nolanlawson in #3807
- chore: weekly dependency update by @ekashida in #3812
Full Changelog: v3.7.3...v3.8.0
v3.7.3
v3.7.3 (#3809)
v3.7.2
chore: release v3.7.2 (#3803)
v3.7.1
What's Changed
- engine-server/template-compiler: remove parse5 utils by @43081j in #3785
- test: fix aria tests in Firefox Nightly by @nolanlawson in #3792
- fix: errorCallback was incorrectly invoked in SSR by @divmain in #3793
New Contributors
Full Changelog: v3.7.0...v3.7.1
v3.7.0
What's Changed
- chore: update deps to fix security audits by @nolanlawson in #3781
- perf(engine-core): implement static parts by @nolanlawson in #3694
- chore: update parse5 to v7 by @divmain in #3602
- fix: move parse5 to devDeps by @jye-sf in #3786
Full Changelog: v3.6.0...v3.7.0
v3.6.0
What's Changed
- feat: adding native shadow mode support by @gonzalocordero in #3771
- fix(engine-core): fix subclass not inheriting
@api
in dev mode by @nolanlawson in #3763 - chore: update dependencies by @nolanlawson in #3776
New Contributors
- @gonzalocordero made their first contribution in #3771
Full Changelog: v3.5.0...v3.6.0
v3.0.4
v3.5.0
What's Changed
- chore: remove references to internal docs by @jmsjtu in #3743
- fix(engine-core): change console.errors to console.warns(#3692) by @yashpatel1998 in #3698
- feat: add shortcut for running karma tests by @AllanOricil in #3750
- feat: enable face lifecycle methods and wrap
ElementInternals
in a proxy by @jmsjtu in #3695
New Contributors
- @yashpatel1998 made their first contribution in #3698
Full Changelog: v3.4.0...v3.5.0
v3.4.0
What's Changed
- perf(synthetic-shadow): micro-optimize MutationObserver by @nolanlawson in #3729
- feat: add dev-only warning to props that are not decorated with @api by @AllanOricil in #3713
- feat: add flag to render legacy CSS scope tokens by @nolanlawson in #3734
New Contributors
- @AllanOricil made their first contribution in #3713
Full Changelog: v3.3.3...v3.4.0