Standalone web application using open-source LWC and node.js

Standalone web application using open-source LWC and node.js

If you have ever wondered to build a standalone web application and you are a salesforce developer this article might help you. Let's start with the aim of the article.

Aim of the article

  • Understanding the basic building blocks of the standalone web application.
  • Setting up the application and understanding folder structure
  • Building a basic single page web application using LWC and node.js
  • Sharing of application code
  • To know about missing items of LWC for open source


Prerequisite

NodeJs and a text editor (VS Code) need to be installed. Basic understanding of ExpressJs will be helpful.


Basic building blocks of a standalone web application

A standalone web application consists of two parts frontend and backend (or in simple words client and server). Frontend development mainly focuses on look n feel of the application as well as their behaviours whereas backend development focuses on the implementation of business logic, API building, interaction with the database etc.

Before LWC (for open source), building the standalone application was a tough thing for a salesforce developer. Because in that case, he needs to learn technology like AngularJS or ReactJS. Now we don’t need to learn any new technology, LWC is simple to understand, simple to build and capable enough to build single-page applications.

I have just mentioned the single page application. Let’s talk little about it. In simple words, a single-page application (SPA) is a web application or web site that interacts with the user by dynamically rewriting the current page rather than loading entire new pages from a server.

In this article, we are also going to use ExpressJs for serverside development. For this, we don’t need to install ExpressJs explicitly, it can be added during the application configuration.


Setting up the application and understanding folder structure

To set up the LWC application we have to run following command in the terminal:

npx create-lwc-app my-app

This command creates the app with the provided name (in this case app name is my-app). But before creating the app it asks some questions. Except following questions, you can simply press the return key and use the default value:

Select a package manager: Select npm here.

Use TypeScript or JavaScript: Select JavaScript.

Use custom Express server configuration: Enter 'y' here. This will create server configuration for ExpressJs and install related dependencies.

Now, set up for application is complete. Go to the folder using the first command and then execute the second command to run the application in development mode.

cd my-app
npm run watch


After this, you can see the below screen in the browser at http://0.0.0.0:3001. npm run watch watches for the changes you make in codes and so you don’t need to refresh your browser again and again to see the updated changes.

No alt text provided for this image


Folder Structure

No alt text provided for this image

Application folder has the same name as the application name. It contains three subfolders node_modules, scripts and src. It also contains some configuration files. node_modules contains the library or dependencies of the application.

scripts folder contains the ExpressJs server configuration for development.

The src folder contains two subfolders client and server. client folder has modules folder which will have LWC components. client folder has one more folder with name resources. All the static resources will be placed in the resources folder. server folder contains the index.js file which is the entry point for server-side codes and in this file, we can create our serverside services.

During the development, LWC components and ExpressJs runs at different endpoints. LWC components run at http://0.0.0.0:3001/ while ExpressJs server runs at http://0.0.0.0:3002/. LWC components connect to the server via the proxy configuration stored in /lwc-services.config.js.


Building a basic single page web application using LWC and node.js

What are we going to build?

We are going to build a very basic web application having a button which fetches data from the server and render that data in the browser.

Step 1: Create the LWC component 'students'

To create students component we need to create a folder with the name students and three files inside it, students.html, students.js and students.css. The CSS file is optional.

We can create this component directly inside /src/client/modules or we can make subfolders inside modules and create component inside them to maintain namespace. Let's create the component inside my subfolder with the following code:

src/client/modules/my/students/students.html

<template>
    <div>
        <button onclick   ​={getStudents}>Get Students</button>
    </div>
    <!-- Check if data is available -->
    <template if:true={isStudentsAvailable}>
        <div>
            <h2>Students Data:</h2>
            <table>
                <thead>
                    <tr>
                        <th>Id</th>
                        <th>Name</th>
                        <th>Age</th>
                    </tr>
                </thead>
                <tbody>
                    <!-- iterating through for each -->
                    <template for:each={students} for:item="student">
                        <!-- unique key is required for for:each -->
                        <tr key={student.id}>
                            <!-- rendering data -->
                            <td>{student.id}</td>
                            <td>{student.name}</td>
                            <td>{student.age}</td>
                        </tr>
                    </template>
                </tbody>
            </table>
        </div>
    </template>
</template>


src/client/modules/my/students/students.js

import { LightningElement, track } from 'lwc';


export default class Students extends LightningElement {
    @track students = [];


    getStudents(){
        //assigning students data to students variable
        this.students = [
            {
                name: 'James Smith',
                age: 17,
                id: 1
            },
            {
                name: 'Elizabeth Johnson',
                age: 17,
                id: 2
            },
            {
                name: 'David Wilson',
                age: 17,
                id: 3
            },
        ];
    }
    //getter method to check if students array have value
    get isStudentsAvailable(){
        return this.students.length > 0;
    }
}


Let’s understand the code briefly. students component has a button 'Get Students'. On click of this button, it calls getStudents method from students.js and assigns the array of students to students variable. if:true provides conditional rendering by calling getter method isStudentsAvailable which checks if data is available. for:each renders array by iterating on that.


Step 2: Add the component to the container component 'app'

After creating the student component we need to add this component to app component which will the be the topmost parent for all the components we create. After adding, code of app.html should look like below:

/src/client/modules/my/app/app.html

<template>
    <my-students></my-students>
</template>


After this step page at http://0.0.0.0:3001/ should look like below:

No alt text provided for this image


Step 3: Create a GET method at server-side which provides a list of students

Till now we have built the component which shows data from the component variable. Now we'll create a GET service at server side which will provide the data. We will use this service to fetch data from the LWC component. /src/server/index.js is the entry point for the server and so we can write our GET services inside it.

/src/server/index.js

module.exports = app => {
    // put your express app logic here
    app.get('/students', (req, res) => {
        // preparing array of student
        var students = [
            {
                name: 'James Smith',
                age: 17,
                id: 1
            },
            {
                name: 'Elizabeth Johnson',
                age: 17,
                id: 2
            },
            {
                name: 'David Wilson',
                age: 17,
                id: 3
            },
        ];
        //next line will send response in JSON format
        res.json(students);
    });
};


Step 4: Connect backend service to frontend

To make GET request from LWC component we need to make ajax calls from the component and for that, we'll use fetch API here. We need to change the code of students component. After the change /src/client/modules/my/students.js will look like below:

/src/client/modules/my/students.js

import { LightningElement, track } from 'lwc';


export default class Students extends LightningElement {
    @track students = [];


    getStudents(){
        //using javascrip native fetch method to get data from server
        fetch('/students').then(res => {
            res.json().then(data =>{
                this.students = data;
                console.log(data);
            });
        }).catch(err => {
            console.error(err);
        });
    }
    //getter method to check if students array have value
    get isStudentsAvailable(){
        return this.students.length > 0;
    }
}

We have completed the development part of the application. We can see the updated changes in the browser. Now on click of 'Get Students' button data is being fetched from server-side service.


Step 5: Make application ready for the production

After the development, we need to make the build of the application for production. Below command makes the build and creates a folder /dist. All the required items to run the application are available in the dist folder.

npm run build

After the build, the following command will run the application at http://0.0.0.0:3002/ from /dist folder.

npm run serve


Sharing of application code

After building the application or during the development you might want to share your code to your teammates or want to add to the Git repository. While sharing or committing to Git repository just ignore the node_modules folder. This folder contains the dependencies which can be installed on any computer using npm commands.

To run the application after sharing of code or cloning it form Git repository, you first need to go to the application folder and install the dependencies. To install dependency execute the following command in the terminal:

npm install

After installing the dependencies you can run the application using npm run watch command.


Missing components in open source LWC

LWC for open source is in its early stage. Although it is simple to use and set up, it has few things missing which are important for the development of single page application. For some of them, I found alternatives. Let's know them:

  • Routing or Navigation: LWC for open source has no built-in support for client-side navigation or routing. It plays a very important role in building single-page applications. I have looked for alternatives and found Navigo. This can help in client-side routing.
  • AJAX Support: Writing long code for XMLHttpRequest is the thing any javascript developers don’t like to do. Most of the javascript frameworks like jQuery, Angular provide support for AJAX calls. Unfortunately, LWC does not provide any support for this. The alternative for this is Axios.
  • LWC basic components support: Currently LWC for open source does not support basic LWC components like lightning-input, lightning-accordion, lightning-tabset etc. To build these components you need to write your own code.


Thank you for reading this article. Please tell me how you find this or if you have any questions regarding this.

thank you for writing this post

Thank you for the article. While following along, I got error like: ./src/client/modules/my/students/students.html LWC1043: Event handler should be an expression Do you know how to fix this?

To view or add a comment, sign in

More articles by Prashant Kumar

  • Navigation in open-source LWC

    Welcome back! In the last article Standalone web application using open-source LWC, we have discussed setting up a…

    2 Comments

Others also viewed

Explore content categories