2. Introduction
Bohdan Dovhan - Senior Salesforce Developer and Salesforce Development Team Lead
Salesforce Certified Development Lifecycle & Deployment Designer
Salesforce Certified Platform Developer I
Salesforce Certified Platform Developer II
Salesforce Certified Platform App Builder
8 years of Development experience
5 years of Development on Salesforce platform
3. SF UI Dev Tools
Salesforce: point-and-click tools and development tools
UI Development frameworks:
Visualforce
Lightning Aura Components
Lightning Web Components (Brand new since Spring’19 release)
UI Development Tools:
Developer Console, many IDEs (VF, Aura)
VS Code (LWC, Aura, VF)
Does your IDE support LWC development? If it does not, migrate to VS Code
4. LWC
Lightning web components (LWC) are a new programming model for the Lightning
Component Framework that is released in the Spring `19 release and is
available since December of 2018. This programming model is architected with
three principles in mind.
Align with modern web standards
Interoperability with the original Aura-based Lightning development
model
Better Performance
LWC are compliant with most ES2015 (also known as ES6) and later standards
that have seen good adoption across modern browsers.
LWC are more secure, since they add CSS isolation, script isolation, DOM
isolation, and a more limited event scope.
LWC have better performance because of leveraging native DOM support.
LWC can be unit tested with Jest framework but such tests are not stored in
Salesforce, these tests cannot be run on cloud. Node.js, npm and Jest should
be installed on Developer machine to be able to run them.
6. LWC Migration Plan
Aura Components can contain LWC. LWC cannot contain Aura
Components.
1. To develop brand new UI: try to use LWC
2. To increase performance: refactor slowest children to LWC or everything
3. If feature is not supported by LWC: use Aura completely or wrap LWC with Aura
At the current Spring 19 release Lightning Web Components are not supported in
Lightning Actions,
Utility Bar,
Console,
Flows,
Visualforce pages and
external systems
7. Prerequisites
LWC cannot be developed in Developer Console.
VS Code with Salesforce Extensions pack is recommended (however any other editor can be used).
LWC requires version 45 (Spring 19)
8. ES6 Compliance
The JavaScript language and web standards, such as HTML templates, custom elements, and web
components have evolved significantly in the last few years.
Many modern HTML and CSS features developed recently and used by Frontend developers in other
technologies were not available to Lighting Developers since these features were not supported by
proprietary Aura Javascript framework.
Lightning Web Components bring modern JavaScript and web standards to the Lightning Component
framework.
Lightning Web Components is an implementation of the W3C’s Web Components standards. It supports
the parts of Web Components that perform well in browsers, and adds only what’s needed to work in
all browsers supported by Salesforce.
Web standards usage boosts performance because more features are executed natively by the modern
browser instead of by a JavaScript framework.
Salesforce promises quicker rendering time for LWC
9. LWC Building blocks
There are two types of LWC: UI components and service components.
HTML File (expected for UI Components, optional for service components)
Javascript File (always required)
Configuration File (always required)
CSS file (optional)
Lightning web component’s JavaScript file is just an ES6 module which imports dependencies, defines
properties and methods and exports them.
To reuse code in Aura Component C of Aura Components A and B, A should inherit B or vice versa and
then C can inherit A or B to reuse both code of A and B
To reuse code in Lightning Web Component C of LWC A and B, C can import two modules A and B.
A doesn’t require to import B and B doesn’t require to have A imported.
10. Create SFDX Project
To work with Lightning Web Component, SFDX project should be created first to be able to deploy and
retrieve source by using corresponding force:source:deploy and force:source:retrieve
commands.
To create SFDX project in Visual Studio Code, we need to invoke hot key combination Ctrl-Shift-P in
Windows (or Cmd-Shift-P in Macs) and then either select or type SFDX: Create Project and select a
name for it, like “demo”. Watch this video GIF image to see this in action.
Also SFDX Project can be created by command line directly
12. Create Lightning
To create Lightning Aura Component, menu item SFDX: Create Lightning Component can be used and
name for a component should be chosen, like AuraCmp
To display output panel and monitor which SFDX command is executed under hood, a key combination
Ctrl-Shift-U can be used on Windows (or Cmd-Shift-U on Macs) or corresponding menu item can
be used. In Output panel dropdown Salesforce CLI should be selected to be able to see SFDX
commands run in the background.
14. Create Aura Comp
As we can see, command
sfdx force:lightning:component:create --componentname AuraCmp --outputdir force-
appmaindefaultaura
is run under the hood.
We can run in terminal to create another Aura component with name AuraCmpHello.
To switch to Terminal we can use hot key combination Ctrl-` or Cmd-`or View Terminal menu item.
To see created component we can click Refresh Explorer button.
sfdx force:lightning:component:create --componentname AuraCmpHello --outputdir
force-appmaindefaultaura
16. Create LWC
Lightning Aura Components are stored in `aura` subfolder while Lightning Web Components are stored in
`lwc` subfolder. So to create Lightning Web Component we need to click SFDX: Create Lightning
Web Component menu item on `lwc` subfolder. Let’s create lwcHello component using menu item.
18. Create in terminal
Lightning Aura Components are stored in `aura` subfolder while Lightning Web Components are stored in
`lwc` subfolder. So to create Lightning Web Component we need to click SFDX: Create Lightning
Web Component menu item on `lwc` subfolder. Let’s create lwcHello component using menu item.
We can notice that this command
sfdx force:lightning:component:create --type lwc --componentname lwcHello --outputdir
force-appmaindefaultlwc
is executed by the Visual Studio, which looks very similar to the command used to create Lightning Aura
Components, please note the different parts: --type lwc attribute and different location ending. Let’s
use this command from terminal to create another Lightning Web Component called
helloWebComponent
sfdx force:lightning:component:create --type lwc --componentname helloWebComponent
--outputdir force-appmaindefaultlwc
20. Metadata API LWC?
How do I retrieve Lightning Web Components using Ant Migration tool or mdapi:retrieve
command from SFDX?
What is appropriate metadata API component which corresponds to LWC folder components in sfdx?
The new Metadata API component is called LightningComponentBundle
The following XML code should be added to package.xml for Ant or force:mdapi:retrieve SFDX
command:
<types>
<members>*</members>
<name>LightningComponentBundle</name>
</types>
SFDX command
sfdx force:source:retrieve -m LightningComponentBundle
can be used as well to retrieve lwc folder.
21. Migrate Bundle Files
Aura and LWC have similar but different structure. Aura components have multiple Javascript files while
LWC have the only Javascript file which is also an ES6 Javascript module as we pointed in the LWC
Building Blocks section.
How can we migrate existing Aura Component Bundle Files to Lightning Web Component
structure?
Salesforce documentation provides the following table to address this question.
RESOURCE AURA FILE LWC FILE
Markup sample.cmp sample.html
Controller sampleController.js sample.js
Helper sampleHelper.js sample.js
Renderer sampleRenderer.js sample.js
CSS sample.css sample.css
Documentation sample.auradoc Not currently available
Design sample.design sample.js-meta.xml
SVG sample.svg Not currently available
22. Access Control
How can we migrate Aura Component access control to Lightning Web Components?
The mechanism for access control is different in a Lightning web component from access attribute of a
component or attribute in Aura framework. In Lightning Web Components access is rather defined by
JavaScript property decorators and the component’s configuration file.
If Aura Component access is global or if it is designed to be placed in Community Builder or App builder
then its LWC counterpart should have value <isExposed>true</isExposed> in the component’s
configuration file.
If Aura Component access is public and it is not designed to be placed in Community Builder or App
builder, it should have value <isExposed>false</isExposed> in the component’s configuration file.
Public and global attributes in Aura component should be declared in LWC component Javascript module
with @api decorator.
Private attributes in Aura component should be declared in LWC component Javascript module with
@track decorator if component should be refreshed on attribute value changes or without any
decorators otherwise.
23. Aura Access Example
How can we migrate Aura Component access control to Lightning Web Components?
See the following component example
<aura:component>
<aura:attribute name="recordId" type="Id" access="global" />
<aura:attribute name="property" type="Property__c" access="public"
default="{Name:'Myself'}"/>
<aura:attribute name="message" type="String" access="private" default="Hello"/>
<aura:attribute name="unbound" type="String" access="private" default="Hi"/>
{!v.recordId}<br/>
{!v.property.Name}<br/>
{!v.message}<br/>
{#v.unbound}<br/>
<lightning:input label="Message" value="{!v.message}"/>
</aura:component>
24. LWC Access Example
How can we migrate Aura Component access control to Lightning Web Components?
See the LWC counterpart
<template>
{recordId}<br/>
{property.Name}<br/>
{message}<br/>
{unbound}<br/>
<lightning-input label="Message"
value={message}
onchange={changeHandler}>
</lightning-input>
</template>
Global recordId receives @api decorator. The @api decorator defines a public reactive property.
Public property receives @api decorator.
Private message referenced by bound expression receives @track decorator. Private reactive properties
rerender a component when their value is changed.
Private unbound referenced only by unbound expressions doesn’t decorators.
import { LightningElement, api, track } from 'lwc’;
export default class Mig extends LightningElement {
@api recordId;
@api property = {Name:'Myself'};
@track message = 'Hello’;
unbound = 'Hi’;
changeHandler(event) {
this.message = event.target.value;
}
}
25. One-way binding
We can also notice that the LWC counterpart contains a lot more Javascript code, including handler
method which sets the value of attribute when the corresponding value on the UI is changed. Aura
framework supports bound expressions and unbound expressions which are two-way binding and
one-way binding while Lightning Web Components always use unbound or one-way binding
expressions, so whenever the value is changed on UI, developer needs to write a handler to capture
that and update the corresponding attribute value.
In Lightning web components, the data binding for property values is one way. If the property value
changes in the owner component, the updated value propagates to the child component. The reverse
is not true.
26. Migrate Interfaces
There are no interfaces for LWC.
How can we migrate existing Aura Component Interfaces to Lightning Web Components?
To migrate context availability interfaces set targets metadata property in configuration file.
Salesforce documentation provides the following table to address this question.
Interface Add to *.js-meta.xml:
forceCommunity:availableForAllPageTypes <targets>
<target>lightningCommunity__Page</target>
</targets>
flexipage:availableForAllPageTypes <targets>
<target>lightning__AppPage</target>
<target>lightning__RecordPage</target>
<target>lightning__HomePage</target>
</targets>
flexipage:availableForRecordHome <targets>
<target>lightning__RecordPage</target>
</targets>
27. Migrate Interfaces
There are no interfaces for LWC.
How can we migrate existing Aura Component Interfaces to Lightning Web Components?
To migrate interfaces providing context data properties import corresponding Javascript module
Salesforce documentation provides the following table to address this question.
Aura Component Interface Add to Javascript
lightning:hasPageReference import { CurrentPageReference } from 'lightning/navigation';
@wire(CurrentPageReference) pageRef;
force:hasRecordId import { LightningElement, api } from 'lwc';
@api recordId;
force:hasSObjectName import { LightningElement, api } from 'lwc';
@api objectApiName;
28. Migrate References
How can we migrate existing Aura Component references to Lightning Web Components?
Aura framework uses camelCase style for references while LWC uses kebab-case style.
HTML specification mandates that tags for custom elements aren’t self-closing.
So to migrate the following code of AuraContainer component
<aura:component>
<c:AuraContained/>
<lightning:formattedNumber value="5000" style="currency" currencyCode="USD" />
</aura:component>
the following code inside your lwcContainer Lightning web component should be written
<template>
<c-lwc-contained></c-lwc-contained>
<lightning-formatted-number value="5000" style="currency" currency-code="USD">
</lightning-formatted-number>
</template>
29. Migrate Iterations
How can we migrate existing Aura Component iterations to Lightning Web Components?
Aura Iterations become HTML Iterations. Migrate <aura:iteration> tags in an Aura component to
for:each directives in a Lightning web component’s HTML file.
So, the following Aura component code part
<aura:iteration items="{!v.properties}" var="property">
<c:PropertyTile property="{#property}"/>
</aura:iteration>
transforms to the following LWC counterpart
<template for:each={properties} for:item="property">
<c-property-tile property={property} key={property.Id}></c-property-tile>
</template>
30. Migrate Conditionals
How can we migrate existing Aura Component references to Lightning Web Components?
Migrate <aura:if> tags in an Aura component to if:true and if:false in a Lightning web component.
So, the following Aura code
<aura:if isTrue="{!v.page > 1}">
can be transformed to the following LWC counterpart
<template if:false={isFirstPage}>
In html file and
@api pageNumber;
get isFirstPage() {
return this.pageNumber === 1;
}
in Javascript file.
Moving business logic determining condition for being on the first page to the Javascript allows
developers to write unit tests for it.
31. Migrate Initializers
How can we migrate existing Aura Component initializers to Lightning Web Components?
Aura Initializers become lifecycle hooks. Replace an init event handler in an Aura component with the
standard JavaScript connectedCallback() method in a Lightning web component. So the following
code
<aura:handler name="init" value="{!this}" action="{!c.onInit}" />
can be translated into such code inside the Javascript file
connectedCallback() {
// initialize component
}
32. Migrate CSS
How can we migrate existing Aura Component CSS to Lightning Web Components?
To migrate CSS just proprietary THIS class, that Aura components use, should be removed.
This Aura CSS code snippet
.THIS .lower-third > p {
padding: 0;
}
corresponds to the following LWC CSS code snippet counterpart
.lower-third > p {
padding: 0;
}
34. Shadow DOM CSS
Aura component styles cascade to any Lightning web components that they contain.
However, the styles of a Lightning web component never interfere with other Lightning web components
or with Aura components. Lightning web component styles don’t cascade to their children. Overriding
styles that you don’t own can create many problems, so Lightning web components don’t allow it.
Lightning web components use a web-standard mechanism called shadow DOM that hides the elements
inside the component from the page that contains the component. Because Lightning web
components have a shadow DOM, styles defined in a component’s style sheet are scoped to the
component. They don’t apply to parent, child, or sibling components. This rule is strict, but it allows a
component to be reused in different contexts without losing its styling. It also prevents a component’s
styles from overriding styles in other parts of a page.
To make development easier for component authors, a Lightning web component’s shadow DOM works a
bit differently than the web standard. One difference is that the shadow DOM for a Lightning web
component is created automatically. The component author doesn’t have to implement it. Also, a
Lightning web component’s shadow DOM works even on browsers that don’t natively support
shadow DOM.
35. JS Code Reuse
In Aura framework the only way to reuse Javascript Code was creation of abstract basic component and
inheritance of it by descendants components. If a component needs to reuse code from two different
components, one of those aura components should inherited another since multiple inheritance is not
allowed in Aura framework. Lightning Web Component Javascript Module can however import as
many other modules as developers want. Also, Javascript code from Lightning Web Component can
be reused in Aura component as well.
In LWC developer needs to import the module to use methods from it while in Aura Component the
module should be included in markup and then retrieved in Javascript code.
So LWC to Aura Javascript code reuse is implemented through aggregation instead of inheritance
36. LWC JS Code Reuse
/*utils.js*/
export function isFunction(value) {
return typeof value === 'function';
}
/* libcaller.js */
import { LightningElement, track } from 'lwc';
import { isFunction } from 'c/utils';
export default class LibCaller extends LightningElement {
@track result;
checkType() {
// Call the imported library function
this.result = isFunction(
function() {
console.log('I am a function');
}
);
}
}
37. Aura JS Code Reuse
<aura:component>
<aura:handler name="init" value="{!this}" action="{!c.doInit}"/>
<p>Aura component calling the utils lib</p>
<!-- add the lib component -->
<c:utils aura:id="utils" />
</aura:component>
({
doInit: function(cmp) {
// Call the lib here
var libCmp = cmp.find('utils');
var result = libCmp.isFunction(
function() {
console.log(" I am a function");
}
);
console.log("Is it a function?: " + result);
}
})
38. Third-party libraries
For third-party Javascript libraries stored in static resources, global value provider was used with
ltng:require tag like following
<ltng:require scripts="{!$Resource.resourceName}"
afterScriptsLoaded="{!c.afterScriptsLoaded}" />
In LWC static resource is imported through import command
import resourceName from '@salesforce/resourceUrl/resourceName';
and then loadScript or loadStyle methods can be used to load the third-party library.
39. No Dynamic Create
There is no equivalent for dynamic components creation $A.createComponent() method from Aura
framework in LWC implementation. Salesforce decided deliberately not to provide dynamic
components creation equivalent since they believe that this feature has led to buggy and convoluted
code existence in Aura components and they decided not to provide this feature in LWC to avoid
buggy and convoluted code.
However, inside Aura component or app dynamic component creation can be used to create LWC
component dynamically inside an Aura component.
40. Apex Calls in LWC
There is one standard way to call Apex method from Aura framework
While in LWC there are three different ways how Apex can be used.
To call an Apex method, a Lightning web component can:
Wire a property
Wire a function
Call a method imperatively
In every way apex method should be imported first by using syntax
import apexMethodName from '@salesforce/apex/Namespace.Classname.apexMethodRef’;
Any Apex method to be exposed to LWC component, should be declared as static and public or global
method with @auraEnabled annotation. The first two options require Apex method to be cacheable,
which means it should be declared with @AuraEnabled(cacheable=true) annotation while imperative
Apex call can be used even if Apex method is not cacheable.
public with sharing class ContactController {
@AuraEnabled(cacheable=true)
public static List<Contact> getContactList() {
return [SELECT Id, Name FROM Contact LIMIT 10];
}
}
41. Wired property
The simplest way to call Apex from LWC is to use wired property.
import { LightningElement, wire } from 'lwc’;
import getContactList from '@salesforce/apex/ContactController.getContactList’;
export default class ApexWireMethod extends LightningElement {
@wire(getContactList) contacts;
}
In the code snippet above contacts is a property and it is wired to Apex method by @wire(getContactList)
decorator. The following markup displays the data retrieved by Apex
<template if:true={contacts.data}>
<template for:each={contacts.data} for:item="contact">
<p key={contact.Id}>{contact.Name}</p>
</template>
</template>
<template if:true={contacts.error}>
<c-error-panel errors={contacts.error}></c-error-panel>
</template>
42. Wired function
Let’s consider example when Apex method is wired to a function.
@track contacts;
@track error;
@wire(getContactList)
wiredContacts({ error, data }) {
if (data) {
this.contacts = data;
this.error = undefined;
} else if (error) {
this.error = error;
this.contacts = undefined;
}
}
Here wiredContacts is a function and it is wired to the same Apex method.
43. Wired function HTML
The markup to display the data is similar but different
<template if:true={contacts}>
<template for:each={contacts} for:item="contact">
<p key={contact.Id}>{contact.Name}</p>
</template>
</template>
<template if:true={error}>
<c-error-panel errors={error}></c-error-panel>
</template>
It is possible to pass parameters to Apex from in property or function declaration
import apexMethod from '@salesforce/apex/Namespace.Classname.apexMethod';
@wire(apexMethod, { apexMethodParams })
propertyOrFunction;
44. Imperative Apex call
If an Apex method is not annotated with cacheable=true the only option to call it in LWC is imperative
Apex call. Since cacheable methods cannot perform DML operation, when DML is needed, the only
way to call such method from LWC is Imperative Apex approach.
@track contacts;
@track error;
connectedCallback() {
getContactList()
.then(result => {
this.contacts = result;
})
.catch(error => {
this.error = error;
});
}
The markup to display the data can be the same as for wired function approach
45. Migrate Facets
Aura framework provided facets options to dynamically insert component markup using attribute with type
of Aura.Component[]. For example, the following code could be used:
<aura:component>
<aura:attribute name="header" type="Aura.Component[]"/>
<div>
<span>{!v.header}</span><br/>
<span>{!v.body}</span>
</div>
</aura:component>
In Lightning web components, slots are used instead of the facets. To migrate body facet, it is possible to
use unnamed slot and for header it is possible to use named slot like following
<template>
<div>
<slot name="header"></slot><br/>
<slot></slot>
</div>
</template>
46. Populate slots
To use this component in parent, markup should be provided for slots in the following way
<template>
<c-named-slots>
<span slot="header">Header !</span>
<span>Body content</span>
</c-named-slots>
</template>
In this example, “Header !” text is passed to the header slot and span with content “Body content” is
passed to unnamed slot.
If a component has more than one unnamed slot, the markup passed into the body of the component is
inserted into all the unnamed slots. However, such UI pattern is unusual. A component usually has
zero or one unnamed slot.
47. Migrate Global VP
Many Global value Providers in Lightning have corresponding @salesforce Javascript module in LWC.
globalId Not available
$Browser Not available
$ContentAsset @salesforce/contentAssetUrl
$Label @salesforce/label
$Locale @salesforce/i18n
$Resource @salesforce/resourceUrl
For more details, visit documentation
48. Migrate Events
Instead of the proprietary Event object in Aura components, the Event or CustomEvent standard DOM
interfaces should be used. CustomEvent is recommended to use.
There’s no equivalent in Lightning web components for the <aura:registerEvent> tag in Aura component
markup to register that a component can fire an event.
To fire an event, Instead of event.fire() syntax of Aura framework, standard DOM method
this.dispatchEvent(myEvent) should be used in Lightning web components.
This is an example of code which fires an event in LWC
export default class PropertyTile extends LightningElement {
@api property;
propertySelected() {
const selectedEvent = new CustomEvent('selected', {
detail: this.property.Id,
});
this.dispatchEvent(selectedEvent);
}
}
49. Migrate Handlers
Instead of the proprietary Event object in Aura components, the Event or CustomEvent standard DOM
interfaces should be used. CustomEvent is recommended to use.
Also there's no equivalent in Lightning web components for the <aura:handler> tag in Aura component
markup that configures an event handler. Lightning Web Components can have declarative handlers
declared similar to Aura components, the only major difference here is that event name in LWC is
prefixed by “on”
<c:child notification="{!c.handleNotification}"/>
Note the difference in markup.
<c-child onnotification={handleNotification}></c-child>
50. Communication
To communicate between components outside of the same DOM tree, copy library from Salesforce
sample repositories for pubsub module implementation.
In a publish-subscribe pattern, one component publishes an event. Other components subscribe to
receive and handle the event. Every component that subscribes to the event receives the event. For
example, if two components are added to a Lightning page in Lightning App Builder, the pubsub
module should be used to send events between them.
The pubsub module exports three methods.
register : Registers a callback for an event.
unregister: Unregisters a callback for an event.
fire : Fires an event to listeners.
51. Fire in LWC to Aura
This is an example how an event can be fired from LWC and received in Aura component.
LWC Catch And Release component code listing
import { LightningElement } from 'lwc’;
export default class CatchAndRelease extends LightningElement {
/**
* Handler for 'Fire My Toast' button.
* @param {Event} evt click event.
*/
handleFireMyToast(evt) {
const eventName = 'notification’;
const event = new CustomEvent(eventName, {
detail: { message: 'See you on the other side.’ }
});
this.dispatchEvent(event);
}
}
52. Catch in Aura
This is an example how an event can be fired from LWC and received in Aura component.
Aura Catch and Release Wrapper component code listing
<aura:component implements="force:appHostable">
<c:catchAndRelease onnotification="{!c.handleCustomEvent}"/>
</aura:component>
({
handleCustomEvent: function(cmp, evt) {
// Get details from the DOM event fired by the Lightning web component
var msg = evt.getParam('message') || '';
}
})
53. Testing Lightning
In Aura components, Lightning Testing Service can be used to test components.
In Lightning web components, Jest can be used for unit testing. If Jest doesn’t cover all your test cases,
use Lightning Testing Service to cover the remaining test cases. Jest unit tests can be stored in the
same source code repository but they cannot be saved to cloud and can only be run locally or by
continuous integration server machine.
54. Aura Methods
Aura methods can become Javascript methods. Migrate methods from <aura:method> tags in an Aura
component to JavaScript methods with an @api decorator in a Lightning web component.
55. More topics…
Import Objects and Fields from @salesforce/schema (object and fields references instead of string literal)
https://developer.salesforce.com/docs/component-library/documentation/lwc/lwc.apex
Refresh the Cache (cacheable methods update)
https://developer.salesforce.com/docs/component-library/documentation/lwc/lwc.apex
JavaScript Property Names (Don’t start names with on, aria, data, don’t use slot, part, is as names)
https://developer.salesforce.com/docs/component-library/documentation/lwc/js_props_names
Library component mapping (most lightning: library components are supported, for complete list visit link)
https://developer.salesforce.com/docs/component-library/documentation/lwc/lwc.migrate_map_aura_lwc_compon
Standard event mapping (use lifecycle hooks for valueInit, valueDestroy and valueRender,use hashChange
instead of aura:locationChange, use navigation service and pageReference object for force:navigate… or
lightning:openFiles or force:createRecord or force:editRecord; import ShowToastEvent from the
lightning/platformShowToastEvent module instead of force:showToast, for complete list visit link)
https://developer.salesforce.com/docs/component-library/documentation/lwc/lwc.migrate_events
56. Even more topics…
Navigation mixin
https://developer.salesforce.com/docs/component-library/documentation/lwc/lwc.use_navigate
Page reference types
https://developer.salesforce.com/docs/component-library/documentation/lwc/lwc.reference_page_reference_type
Event best practices
https://developer.salesforce.com/docs/component-library/documentation/lwc/lwc.events_best_practices
Salesforce modules
https://developer.salesforce.com/docs/component-library/documentation/lwc/lwc.reference_salesforce_modules
57. Conclusion
As we can conclude now, Salesforce provide Lightning Web Components to be able to follow the latest
Javascript code standards and to discourage developers to use some features of Aura framework
which might lead to buggy and convoluted code. Also UI performance can be significantly increased
on modern browsers which support the latest Javascript code standards. Polyfills to older browsers
which do not support the latest code standards are also provided but they can slow down
performance on older browsers. Every Salesforce developer should learn the new features provided
by Salesforce to suggest the customers the best appropriate development option.