Codzienna praca w środowisku Salesforce sprawia, że w Craftware bardzo poważnie podchodzimy do wszystkich nowości związanych z możliwością rozwijania produktów na tej platformie. Z tego też powodu na bieżąco śledzimy wprowadzane rozwiązania i to, jakie przynoszą korzyści. Jedną z takich nowości jest Lightning Web Component, nowy model programowania komponentów Lightning.

Udogodnienia LWC

  • Nowoczesny framework js: moduły, importy, dziedziczenie, dekoratory, Shadow DOM. Te wszystkie elementy zmuszają do pisania bardzo przejrzystego kodu, podziału na komponenty, używania kompozycji, Lightning Data Service.
  • Dostęp do Lightning/ui*Api i takich metod jak: getRecord, createRecord, getObjectInfo, getPicklistValues itp – tego zdecydowanie brakowało w Lightiningu. Dzięki temu dużo więcej można zrobić bez udziału back-end. W moim przypadku bez problemów byłem w stanie pobrać rekord (zdefiniowane pola) i pobrać labelki do pól.
    Część metod można wywoływać tylko przez oznaczenie jako @wire. Przy próbie wywołania na żądanie pojawia się błąd: „Imperative use is not supported”. To niestety mocno ogranicza możliwości użycia np. nie będzie się dało zrobić łańcucha wywołań, gdzie jednym z elementów jest getRecord.
  • Importowanie referencji do pól. Do wskazania jakie pola mają być pobrane np. przez getRecord możemy podać standardowo listę stringów w postaci: [„Account.Name”, „Account.Id”] lub pobrać pola jako: import ACCOUNT_NAME_FIELD from ‚@salesforce/schema/Account.Name‚. Dzięki pobraniu referencji do pola możemy, w bardziej przejrzysty sposób, pobierać wartości pól, labelki pól itp.
  • Wywoływanie metod backendowych. Do wywołania metody trzeba pobrać do niej referencje (podobnie jak pola obiektów) import apexMethod from ‚@salesforce/apex/Namespace.Classname.apexMethod‚. Dzięki referencji możemy w bardzo prosty sposób wywoływać metody. To jest zdecydowanie krok do przodu, w porównaniu z obecnym Lightningiem.

W przypadku Lightning mogło się zdarzyć, że nazwa metody na back-end była taka sama jak metoda w kontrolerze i to „działało”. Taka próba wywołania nie powodowała błędu, tylko dziwne zachowanie kodu. Z doświadczenia wiem, że straciliśmy wiele czasu na analizowanie takich błędów.

Lightning

var action = cmp.get(actionName); if (params) {action.setParams(params); } if (background) {action.setBackground(); }action.setCallback(that, function (response) {var state = response.getState(); if (cmp.isValid() && state === „SUCCESS”) {successMethod(response.getReturnValue()); } else { errorMethod(response.getError()[0].message); } }); $A.enqueueAction(action);

LWC

import getContactList from ‚@salesforce/apex/ContactController.getContactList’; @wire(getContactList, {params}) contacts; lub wywołanie nad którym mamy więcej kontroli: import getContactList from ‚@salesforce/apex/ContactController.getContactList’;getContactList({params}) .then(result => {this.contacts = result; }) .catch(error => {this.error = error; });

  • Taka sama biblioteka komponentów jak w Lightningu.

Dzięki temu na pewno zmniejszamy próg wejścia dla osób znających Lightning.

Lightning

<lightning:layoutItem size=”12″ smallDeviceSize=”12″ mediumDeviceSize=”6″ largeDeviceSize=”4″ padding=”around-small”>

LWC

<lightning-layout-item size=”12″ small-device-size=”12″ medium-device-size=”12″ large-device-size=”12″ padding=”around-small”>

Minusy LWC

  • Brak wsparcia dla: Lightning Out, Lightning Components for Visualforce, Standalone Apps, Salesforce Console (Navigation Item API, Workspace API, UtilityBar API), URL Addressable Tabs, Flows, Snap-ins Chat, Lightning for Gmail, Outlook Integration, EMP API, Conversation Toolkit API, Omni Toolkit API, Quick Action API, Standard Action Overrides, Custom Actions (z punktu widzenia projektu najbardziej bolesne), Global Actions, List View Actions, Related List View Actions, Chatter Extensions.
  • Większość customowego kodu piszemy jako Quick Action. W takim przypadku LWC nie da się użyć bezpośrednio. Moim obejściem było użycie Lightningowego komponentu jako kontenera dla LWC. Możliwe jest używanie LWC w Lightning, ale już Lightning w LWC nie.
  • Brak możliwości obsługi standardowych eventów: force:refreshView, lightning:tabFocused, lightning:tabRefreshed itp. praktycznie uniemożliwia samodzielne użycie LWC na stronach wymagających interakcji ze standardowymi komponentami, np. Record Detail.
  • Brak $A i tym samym zablokowanie wielu niezbędnych metod, np: $A.get(‚e.force:refreshView’).fire(); Większość tego typu problemów można obejść przez zastosowanie Lightningowego kontenera. Wszystko czego nie może zrobić LWC można obsłużyć w kontenerze i skomunikować go z LWC, ale pajęczyna która powstanie będzie spora. Dodatkowo część „workaround” może w przyszłych releasach SF przestać działać. Taką sytuację mieliśmy wiele razy w złożonych projektach. Po kilku pierwszych wersjach konsoli trzeba było poprawiać sporą liczbę błędów i przepisywać kod.
  • Jednokierunkowe bindownie. To jest coś czego totalnie nie rozumiem. Bindowanie między widokiem a kontrolerem jest tylko w postaci: kontroler -> widok. Żeby zmiany, np. z najprostszego inputa były w kontrolerze, trzeba dopisać: onchange={handleChangeValue}. Podejście archaiczne, tworzące sporą ilość dodatkowego pustego kodu. Możliwe też, że uniemożliwi zastosowanie pewnych zewnętrznych bibliotek i komponentów.
  • Brak możliwości dynamicznego tworzenia komponentów (brakuje $A, tym samym nie ma $A.createComponent()). Wszystkie komponenty muszą być zawarte na layoucie. Da się to obejść if-ami, ale to kolejny workaround.
  • Bardzo długi czas deploy LWC na sandbox. Nie wiem czym to jest spowodowane, ale jest to bardzo irytujące. Deploy jednego komponentu potrafi zająć kilka minut. W tym samym czasie bez problemów w kilka sekund idą komponenty Lightningowe.

 

LWC – dobry kierunek, ale …

Lightning Web Components to ciekawa technologia, wychodząca naprzeciw pędzącemu światu front-end. Rozwiązuje wiele problemów standardowego Lightninga, dodaje nowe możliwości (np @wire) oraz przejmuje dobrze znane standardy. Niestety momentami za bardzo ogranicza programistę. Jako przykład można podać metody, które możemy wywołać tylko przez oznaczenie @wire. Znacznie bardziej uniwersalnie byłoby użyć np. metody getRecord tam gdzie chcemy, nie tylko z wykorzystaniem @wire. Prosty framework ma swoje plusy i minusy. Z jednej strony stworzenie kodu zajęło mi niewiele czasu: dwa dni na przeczytanie całej dokumentacji i kolejne dwa na napisanie kodu. Z drugiej – prostota oznacza także, że brakuje bardziej zaawansowanych funkcjonalności. W przypadku LWC towarzyszą mi podobne odczucia, jak w przypadku konsoli Salesforce. Kiedy zaczynaliśmy pisać kod po pierwszym releasie, jeszcze w wersji beta, produkt był jeszcze niedopracowany. Brakowało mu podstawowych funkcjonalności (np. WorkspaceAPI, które jest niezbędne do podstawowego zarządzania zakładkami, wyszło blisko rok później). Na razie odradzałbym korzystanie z LWC przy bardziej rozbudowanych projektach. Brak możliwości komunikacji ze standardem będzie powodował wiele problemów i konieczność tworzenia obejść, które mogą w niespodziewanych momentach przestać działać. Z drugiej strony do wyizolowanych komponentów nadaje się znakomicie. Z niecierpliwością czekam na kolejne release’y Salesforce i nowinki wprowadzone do LWC. Mam nadzieję, że framework będzie sprawnie rozwijany i w niedługim czasie zastąpi obecne rozwiązania. Jest to na pewno dobry kierunek rozwoju i spory krok do przodu.

Autor

  • Łukasz Czerwiński
  • Swoją przygodę z programowaniem zaczynał od Delphi 7. Kolejnym krokiem w świecie kodowania był C# i niedługo póżniej Java oraz javascript. Obecnie zajmuje się głównie technologiami front-endowymi, a znajomość różnych języków programowania, technologii i frameworków, takich jak: ASP.NET, JSF, PrimeFaces, AngularJS czy Lightning, ułatwia mu pracę i dobór odpowiednich narzędzi do powierzonych zadań. Prywatnie miłośnik jazdy na rowerze, który wyznaje zasadę: kilometry same się nie zrobią.

Podobał Ci się mój artykuł?

Jeśli tak, zapraszam Cię do grona najlepiej poinformowanych czytelników bloga. Dołącz do naszego newslettera, a nie ominą Cię żadne nowości.