Migrate from Aura to Lightning Web Components to Increase Performance
April 12, 2019

Migrate from Aura to Lightning Web Components to Increase Performance

Salesforce cloud platform provides customers with the whole variety of options for customization. Those include point-and-click tools like Lightning App Builder, Process Builder, Visual Flow and Workflow, and development tools like Apex, Visualforce, Lightning Aura Components, Lightning Aura Events, Lightning Aura Tokens, Lightning Aura Standalone application and Lightning Web Components.

While reading this list you might find many familiar application building bricks except one. Have you ever heard about Lightning Web Components? Do you think these are the same Aura components you developed earlier in Developer Console or in popular IDE plugins? Obviously, they aren’t.

What are Lightning Web Components (LWC)?

Lightning Web Components (LWC) is a programming model for a Lightning Component Framework released in Spring 2019, though available since December 2018. This new programming model is architected with three principles in mind:

  • Align with modern web standards
  • Interoperability with the original Aura-based Lightning component development model
  • Better performance

–  Lightning Web Components comply with most ES2015 (also known as ES6) and subsequent standards adopted across modern browsers.

– Lightning Web Components demonstrate better security as they add CSS isolation, script isolation, DOM isolation, and a more limited event scope.

– Lightning Web Components perform way better due to leveraging native DOM support.

– Lightning Web Components can be unit tested with the Jest framework, but such tests are not stored in Salesforce and Node.js; npm and Jest should be installed on the Developer’s machine to be able to run them.

LWC Migration Plan

So, with LWC’s better performance, does it mean that every Aura component should be refactored into a Lightning Web Component?

Also, can Lightning Web Components coexist with Aura components?

Can Lightning Web Components be embedded into Aura Components or vice versa?

The current Spring `19 release allows Aura Components to contain Lightning Web Components but Lightning Web Components can not contain Aura components.

This enables developers to migrate only the children components to LWC and place them inside the legacy Aura containers components. That is, Lightning Web Components can coexist with Aura components.

In order to answer the question about refactoring, it is suggested to follow the Decision Matrix provided by Salesforce itself.

The brand new custom Lightning components can be built by using Lightning Web Components to take advantage of the faster performance.

When there exist some Aura-based components, which are a part of business application, it is needed to check if any benefit can be obtained from migrating them into Lightning Web Components. If existing components are simple and render time performance is acceptable, there is no need to rewrite them. Otherwise, there are options either rewriting every component into LWC or refactoring only some of the children components, which have the worst performance.

The recent Spring’19 release does not support the Lightning Web Components to be directly included inside Lightning Actions, Utility Bar, Console, Flows, Visualforce pages and external systems, so the parent components should be kept as the Aura components, while the child components contained in these parent components can be considered for a rewrite into LWC if they can benefit from a faster performance runtime. Also, once Lightning Web Components become supported in the aforementioned list of containers in the future Salesforce releases, this item can be revisited, so not only the children components, but the parent ones as well, may be available for migration to LWC.    

LWC Development Prerequisites

The main difference between modern LWC and the development tools developers might be used to, is that it is not possible to develop Lightning Web Components in the Developer Console. It is possible to use any preferred code editor or the default one suggested by Salesforce, which is the Salesforce Extension Pack extension for Visual Studio Code.

LWC Development Prerequisites

Regardless of the chosen code editor, Salesforce CLI is still required when moving source code to and from a Salesforce org, so it is required to use the Salesforce CLI of version 45 or higher. Version 45 corresponds to the Spring’19 release where Lightning Web Components are introduced. Also, if developers already use an IDE plugin which supports Metadata API\Tooling API of version 45 and LWC development, then they might continue using it instead.

That is, before LWC development starts, Salesforce CLI must be installed, and VS Code Salesforce Extension Pack is recommended and should be considered as a default option.

ES6 Compliance

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 Front-End developers in other technologies, were not available to Lighting Developers, since these features were not supported by the proprietary Aura Javascript framework. Lightning Web Components bring modern JavaScript and web standards to the Lightning Component framework.

Lightning Web Components are the 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 browser instead of by a JavaScript framework. This improvement can vary depending on the use case, but the quicker rendering time for components should pleasantly surprise your customer.

It is easier now for a Front-End developer, who is not familiar with Salesforce or Lightning, to switch to Lightning Development since LWC uses standard JavaScript, HTML, and CSS, and even Lightning Framework proprietary components can be accessed and used in a standard way.

LWC Building blocks

There are two types of LWC: UI components and service components. UI components are used to display UI while service components or libraries are designed to reshare common Javascript code by exporting methods for other components to import them. Service components resemble abstract Lightning Aura components which were also used to extract common code.

An UI Lightning Web Component must include an HTML file, a JavaScript file, and a configuration file. It can optionally include a CSS file and more JavaScript files, while service components don’t require a HTML markup file. However, any Lightning Web Component must include a JavaScript file and a metadata configuration file. The Lightning Web Component’s JavaScript file is just an ES6 module which imports dependencies, defines properties and methods, and exports them.

Create Salesforce DX Project in Visual Studio Code

In order to work with a Lightning Web Component, a Salesforce DX project should be created first so that one is able to deploy and retrieve source by using corresponding force:source:deploy and force:source:retrieve commands.

To create a Salesforce DX project, a command can be used, which is covered in our previous article about Salesforce DX, or a menu item can be used in Visual Studio Code. Let’s describe how to create project using VSCode menu item.

In order to create a Salesforce DX project in Visual Studio Code, it is needed to invoke the 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.

How to create Salesforce DX Project in VSCode

How can Lightning Components be created?

Both the Aura Component and the Lightning Web Component can be created from CLI or from a VSCode menu item. An Aura Component can be also created from a Developer Console while Lightning Web Components cannot.

In order to create a Lightning Aura Component, the menu item SFDX: Create Lightning Component can be used and a name for a component should be chosen, like AuraCmp. To display the output panel and monitor which Salesforce DX command is executed under the hood, a key combination Ctrl-Shift-U can be used on Windows (or Cmd-Shift-U on Macs) or a corresponding menu item can be used. Salesforce CLI should be selected in the Output panel dropdown to be able to see the Salesforce DX commands run in the background.

How to create Lightning Components in VS

 

As one can see, the command

sfdx force:lightning:component:create  --componentname AuraCmp --outputdir force-app\main\default\aura>

is run under the hood.

It can be run in the terminal to create another Aura component with the name AuraCmpHello. Using the hot key combination Ctrl-` or Cmd-`or View \ Terminal menu item makes it possible to switch to Terminal. To see a created component, the Refresh Explorer button can be clicked.

sfdx force:lightning:component:create  --componentname AuraCmpHello --outputdir force-app\main\default\aura

 

How to see a created component in VS

Lightning Aura Components are stored in the `aura` subfolder while Lightning Web Components are stored in the `lwc` subfolder. So, in order to create a Lightning Web Component, it is necessary to click on the SFDX: Create Lightning Web Component menu item, then on the `lwc` subfolder. Let’s create a lwcHello component using the menu item.

How to create a lwcHello component using the menu item in VS

Please, make a note that the following command:

sfdx force:lightning:component:create --type lwc --componentname lwcHello --outputdir force-app\main\default\lwc

is executed by Visual Studio, which looks very similar to the command used for creation of Lightning Aura Components; there are different parts: –type lwc attribute and the 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-app\main\default\lwc

How to use the command from Terminal to create helloWebComponent

So, the creation of the Lightning Web Component is as easy as creating the Lightning Aura Component. Also, it is convenient to create both from a menu item and by typing a command.

Migrate Component Bundle Files

The Aura Components and the Lightning Web Components have similar but still different structures. The Aura components have multiple Javascript files while the Lightning Web Components have the only Javascript file, which is also an ES6 Javascript module, as is pointed out in the LWC Building Blocks section. A natural question arises here on how the existing Aura Component Bundle Files can be migrated to the 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

So, the markup from the file with a cmp extension should be moved to a html file. All javascript files should be merged into the one ES6 module file. The CSS file can remain almost unchanged, however, the .THIS class reference should be removed. The component design can be moved to the metadata file. Aura documentation and SVG files cannot be translated into LWC in the current release.

Migrate Aura Component Markup

Migrate Interfaces

Salesforce documentation provides helpful information about the migration of the interfaces. There are no interfaces for the Lightning Web Components. Some Aura interfaces have corresponding functionality in LWC while others do not.

Most Aura interfaces are marker interfaces. Some of them allow developers to place the corresponding component inside the specific context, like on record pages or on community. Others provide access to context data properties, like record identifier, object type or page reference.

Use a target’s metadata property in the configuration file to migrate interfaces which allow container context.

Aura Component 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>

In order to migrate interfaces which provide access to context data properties, a corresponding module needs to be imported.

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;

Interfaces force:hasRecordId and force:hasSObjectName upon conversion also need target lightning__RecordPage in the configuration file making it possible to place the corresponding component onto the record page.

Migrate Component References

Let’s assume there is an AuraContainer component which refers to an AuraContained component and developers need to refactor these Lightning Aura Components into an lwcContainer Lightning Web Component and an lwcContained component. The Aura framework uses camelCase style for references while Lightning Web Components use the kebab-case style. Also, the HTML specification mandates that tags for custom elements aren’t self-closing. Self-closing tags end with />. A Lightning Web Component is essentially a custom element, so developers must write a closing tag, which might be a bit annoying, in my opinion. This requirement is different from the Aura components, where self-closing tags are allowed.

That is, to migrate the following code of the AuraContainer component:

<aura:component>
    <c:AuraContained />
    <lightning:formattedNumber value="5000" style="currency" currencyCode="USD" />
</aura:component>

It is needed to write the following code inside your lwcContainer Lightning Web Component:

<template>
    <c-lwc-contained></c-lwc-contained>
    <lightning-formatted-number value="5000" style="currency" currency-code="USD">
    </lightning-formatted-number>
</template>

Migrate Access Control

The mechanism for access control is different in the Lightning Web Component from the access attribute of a component or attribute in the Aura framework. In Lightning Web Components the access is rather defined by the JavaScript property decorators and the component’s configuration file.

In case the Aura Component access is global or if it is designed to be placed in a Community Builder or App builder, then its LWC counterpart should have the value <isExposed>true</isExposed> in the component’s configuration file.

In case the Aura Component access is public and it is not designed to be placed in a Community Builder or an App builder, it should have the value <isExposed>false</isExposed> in the component’s configuration file.

Public and global attributes in the Aura component should be declared in the Lightning Web Component Javascript module with a @api decorator.

Private attributes in the Aura component  should be declared in the Lightning Web Component Javascript module with a @track decorator if the component should be refreshed on attribute value changes or without any decorators.

Migrate Attributes

Let’s consider now how attributes can be migrated in an example of some dummy component which defines four attributes, displays them, and has an input to change the value of one of the attributes.

<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}
    {!v.property.Name}
    {!v.message}
    {#v.unbound}
    <lightning:input label="Message" value="{!v.message}"/>
</aura:component>

The LWC counterpart will look like the following:

<template>
   {recordId}
   {property.Name}
   {message}
   {unbound}
    <lightning-input label="Message" value={message} onchange={changeHandler}></lightning-input>
</template>
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;
   }
}   

The first attribute recordId has a global access modifier. Its counterpart has instead an @api decorator. The @api decorator defines a public reactive property. A public property is part of the public API for the component, which means that it can be set in the Lightning App Builder, or by a parent component that uses the component in its markup. An owner component that uses the component in its markup can access the component’s public properties. Public properties are reactive. If the value of a reactive property changes, the component’s template rerenders any content that references the property.

The second attribute property has a public access modifier and a default value. Its counterpart has also the @api decorator and the value is initialized by Javascript.

The third attribute message has a private access modifier but it is referenced by bound expression. Its counterpart has a @track decorator. To track a private property’s value and rerender a component when it changes, decorate the property with the @track. Tracked properties are also called private reactive properties. These properties are used to track the internal component’s state and aren’t a part of the component’s public API.

The fourth attribute unbound is referenced only by an unbound expression so, to migrate it to the LWC form it is just enough to avoid adding any decorators to its counterpart, since the component doesn’t have to be refreshed upon the change of the value of this attribute.

One-way binding expressions in LWC

One can easily notice that the LWC counterpart contains a lot more Javascript code, including the handler method which sets the value of the attribute when the corresponding value on the UI is changed. The 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. That is, whenever the value is changed on UI, the 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 a one way process. If the property value changes in the owner component, the updated value propagates to the child component. The reverse is not true.

Migrate Iterations

Aura Iterations become HTML Iterations. Migrate <aura:iteration> tags in the Aura component to for:each directives in the 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>

Migrate Conditionals

Migrate <aura:if> tags in the Aura component to if:true and if:false in the 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 a html file and

@api pageNumber;
   get isFirstPage() {
       return this.pageNumber === 1;
   }

in a Javascript file.

Moving a business logic to Javascript  determining the condition for being on the first page allows developers to write unit tests for it.

Migrate Initializers

Aura Initializers become lifecycle hooks. Replace an init event handler in the Aura component with the standard JavaScript connectedCallback() method in the Lightning Web Component. So, the following code:

<aura:handler name="init" value="{!this}" action="{!c.onInit}" />

can be translated into such a code inside the Javascript file:

   connectedCallback() {
       // initialize component
   }

Migrate CSS

In order to migrate CSS, just remove the proprietary THIS class, that Aura components generally use. An Aura CSS code snippet:

.THIS .lower-third > p {
   padding: 0;}
A LWC CSS code snippet counterpart:
.lower-third > p {
   padding: 0;
}

CSS Encapsulation with Shadow DOM

The Aura component styles cascade to any Lightning Web Components that they contain.

However, the styles of the Lightning Web Component never interfere with other Lightning Web Components or with the Aura components. The Lightning Web Component styles don’t cascade to their children. Overriding styles not owned by the current component, may create many problems, so the Lightning Web Components don’t allow it.

Lightning Web Components use a web-standard mechanism called a shadow DOM that hides the elements inside the component from the page that contains the component. Because Lightning Web Components have a shadow DOM, the 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 the component to be reused in different contexts without losing its styling. It also prevents component’s styles from overriding styles on other parts of a page.

In order to simplify the development for component authors, a Lightning Web Component’s shadow DOM works a bit differently from the web standard. The difference lies in the fact that the shadow DOM for the Lightning Web Component is created automatically. The component author doesn’t have to implement it. Also, the Lightning Web Component’s shadow DOM works even on browsers that don’t natively support shadow DOM.

Reuse of Javascript Code

In the Aura framework, the only way to reuse Javascript Code is to create an abstract basic component and inheritance of it by descendant components. If a component needs to reuse code from two different components, one of those Aura components would inherit the other since multiple inheritance is not allowed in the Aura framework. The Lightning Web Component Javascript Module can however import as many other modules as developers want. Also, Javascript code from the Lightning Web Component can be reused in the Aura component as well.

Let’s consider LWC module utils, which are used by the LWC module libcaller and by the Aura Component:

/*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');
            }
        ); 
    }
}

<aura:component>
    <aura:handler name="init" value="{!this}" action="{!c.doInit}"/>
 

Aura component calling the utils lib

    <!-- 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);
    }
})

In LWC, the developer needs to import the module, to use methods from it, while in the Aura Component the module should be included in markup and then retrieved in Javascript code.

Third Party Javascript Libraries

For the third-party Javascript libraries stored in static resources, a global value provider was used with a ltng:require tag like the following:

<ltng:require scripts="{!$Resource.resourceName}" afterScriptsLoaded="{!c.afterScriptsLoaded}" />

In LWC a static resource is imported through an import command:

import resourceName from '@salesforce/resourceUrl/resourceName';

and then loadScript or loadStyle methods can be used to load the third-party library.

No Dynamic Component Creation in LWC

There is no equivalent for the dynamic components’ creation $A.createComponent() or $A.createComponents()  methods from the Aura framework in a LWC implementation. Salesforce deliberately decided not to provide a dynamic components’ creation equivalent since they believe that this feature has led to buggy and convoluted code existing in the Aura components and they chose not to provide this feature in LWC for the same reason.

However, inside the Aura component or inside the Aura standalone application dynamic component creation can be used to build the Lightning Web Component dynamically inside the Aura component.

Migrate Server Side Apex Calls

There is one standard way to call the Apex method from the Aura framework:

var action = component.get("c.getPictures");
        action.setParams({
            "propertyId": propertyId,
        });
        action.setCallback(this, function (response) {
            var state = response.getState();
            if (state === "SUCCESS") {
                var files = response.getReturnValue();
                component.set("v.files", files);
            }
            else if (state === "INCOMPLETE") {
                // handle incomplete state
            }
            else if (state === "ERROR") {
                // handle error state
            }
        });
        $A.enqueueAction(action);

while in LWC, there are three different ways to use Apex.

In order to call the Apex method, the Lightning Web Component can:

  • Wire a property
  • Wire a function
  • Call a method imperatively

Either way,the Apex method should be imported first by using the syntax:

import apexMethodName from '@salesforce/apex/Namespace.Classname.apexMethodReference';

Any Apex method that will be exposed to the Lightning Web Component, should be declared as static method with an  @auraEnabled annotation and with public or global access keyword. The first two options require the Apex method to be cacheable, which means it should be declared with an @AuraEnabled(cacheable=true) annotation, while an imperative Apex call can be used even if the 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];
    }
}
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 the Apex method by a @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">
        
{contact.Name}

    </template>
</template>
<template if:true={contacts.error}>
    <c-error-panel errors={contacts.error}></c-error-panel>
</template>

Let’s consider an example when the 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. The markup to display the data is similar but still different:

<template if:true={contacts}>
    <template for:each={contacts} for:item="contact">
        
{contact.Name}

    </template>
</template>
<template if:true={error}>
    <c-error-panel errors={error}></c-error-panel>
</template>

If the Apex method is not annotated with cacheable=true ,the only option to call it into LWC is an imperative Apex call.

    @track contacts;
    @track error;

    connectedCallback() {
        getContactList()
            .then(result => {
                this.contacts = result;
            })
            .catch(error => {
                this.error = error;
            });
    }

The markup for this case is the same as for wired function, since the same Javascript properties are used.

<template if:true={contacts}>
    <template for:each={contacts} for:item="contact">
        
{contact.Name}

    </template>
</template>
<template if:true={error}>
    <c-error-panel errors={error}></c-error-panel>
</template>

Migrate Facets

The Aura framework provides a facets option to dynamically insert a component markup using the attribute with the 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>
        <span>{!v.body}</span>
    </div>


</aura:component>

In Lightning Web Components, slots are used instead of facets. To migrate a body facet, it is possible to use an unnamed slot and for the header it is possible to use a named slot like the following:

<template>
    

<div>
        <slot name="header"></slot>
        <slot></slot>
    </div>


</template>

In order to use this component in parent, a 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, the “Header !” text is passed to the header slot and a span with the content “Body content” is passed to an 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 a UI pattern is unusual. A component usually has zero or only one unnamed slot.

Migrate Events

Instead of the proprietary Event object in the Aura components, the Event or CustomEvent standard DOM interfaces should be used. It is recommended to use CustomEvent.

There’s no equivalent in Lightning Web Components for the <aura:registerEvent> tag as it is in the Aura component markup that registers that a component can fire an event.

To fire an event, Instead of the event.fire() syntax in the Aura framework, a 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);
   }
}

There is also no equivalent in Lightning Web Components for the <aura:handler> tag in the Aura component markup that configures an event handler. Lightning Web Components can have declarative handlers declared similar to the Aura components; the only major difference here is that the event name in LWC is prefixed by “on”

<c:child notification="{!c.handleNotification}"/>

Note the difference in markup.

<c-child onnotification={handleNotification}></c-child>

Communication between components outside of the same DOM tree can be implemented by using the pubsub module from the Salesforce sample repositories library.

In a publish-subscribe pattern, one component publishes an event. The other components subscribe to receive and handle the event. Every component that subscribes to the event receives that particular event. For example, if two components are added to a Lightning page in the Lightning App Builder, the pubsub module should be used to send events between them.

The pubsub module exports through three methods.

  • register : Registers a callback for an event.
  • unregister: Unregisters a callback for an event.
  • fire : Fires an event to listeners.

LWC to Aura Events Communication

The following is an example of how an event can be fired from the Lightning Web Component and received in the Aura component.

// catchAndRelease.js
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: 'Sent from LWC to Aura.' }
        });
        this.dispatchEvent(event);
    }
}

<!-- catchAndReleaseWrapper.cmp -->
<aura:component implements="force:appHostable">
    <c:catchAndRelease onnotification="{!c.handleCustomEvent}"/>
</aura:component>
// catchAndReleaseWrapperController.js
({
    handleCustomEvent: function(cmp, evt) {
        // Get details from the DOM event fired by the Lightning web component
        var msg = evt.getParam('message') || '';
    }
})

Test Lightning Components

Lightning Testing Service, customarily used to test Lightning Aura Components , can still be used to test the Lightning Web Components. However, Salesforce recommends to use Jest to unit test LWC. If Jest doesn’t cover all of 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 the cloud and can only be run locally or by a continuous integration server machine.

Migrate Aura Methods

The Aura methods can become Javascript methods. Migrate methods from <aura:method> tags in the Aura component to JavaScript methods with an @api decorator in the Lightning Web Component.

Conclusion

As it can be summarized, since December 2018 Salesforce provides Lightning Web Components in order to be able to follow the latest Javascript code standards and to discourage developers from using some features of the Aura framework leading 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 get to know the new features provided by Salesforce and suggest the best appropriate development option to customers.

 

Tags

AuraLightningmigrationSalesforce

Share


Recent Articles

Anti-Spoofing System Project

September 19, 2019 | Arsen Senkivskyy, Applied Sciences faculty of Ukrainian Catholic University graduated
Sam Senyuk, CTO, Head of R&D

Cameras are everywhere. We bet you have one in your pocket on a smartphone. Web cameras are incorporated into tablets, laptops, we use them for security in banks and groceries, on the parking lots and at the airports. Facial recognition systems for access control, attendance tracking or marketing purposes are on the rise, as they […]

CoreValue Advances in Salesforce Excellence

September 10, 2019

We are proud to announce that CoreValue achieved a new Salesforce partnership milestone. Our company is now officially a Salesforce Silver Consulting Partner. Together with our great Salesforce team, we made it happen. CoreValue provides Salesforce CRM solutions for more than eight years. We help enterprises get measurable business outcomes with platform development and implementation […]

Contact Us

By submitting this form you acknowledge that you agreed to our Cookies and Privacy Policy.