(upbeat music)
- Hi everyone, my name is Aditya
and I'm a Developer Evangelist at Salesforce.
In this quick take,
I'm going to show you how you can deploy
a Lightning Web Components Open Source app,
that uses an Express API server to Heroku.
Before watching this video,
I strongly encourage you to go
and check out my other quick take,
in which I deploy an LWC OSS app,
without Express API server to Heroku.
The link is in the description below.
And the reason I asked you to go and check
that video out is,
the process in which you deploy LWC apps with or without
an Express API server is literally the same.
You're going to be using the same commands,
the same deployment options are available to you.
And I've gone over all of them
in pretty much a lot of detail,
in the previous quick take.
And there is a small change that you'll have to make
in a piece of code,
to make sure the deployment
with the API server goes successfully,
which is what I'm going to cover in this quick take today.
So, let's dive in.
What you're seeing here is an
LWC OSS app, that uses an Express API Server.
The src folder has two sub folders,
one for the client and one for the server.
And to deploy this to Heroku,
as usual you'll be creating a Procfile,
and you'll have the contents
web: npm run serve.
Now let's look at the serve script in package.json.
So here you'll see the serve command is now
a little bit different from what you have seen
in the previous quick take.
It now has two sub commands.
One is serve:client and the other is serve:api.
And if you look at both of those scripts,
each of those scripts are running different files.
So the serve:client is running script/server.js,
and the serve:api is running src/server/api.js.
Let's open both of those files.
So I'm opening the api.js file, and then script/server.js.
The server.js looks exactly the same
whether or not you use a custom API server.
That is because the job of this file is to serve out
static content from the build directory.
And the logic for that is written in lines 15 to 17.
What you'll also notice here,
is that it is listening onto the port,
which can either be passed as an environment variable,
or it's hard coded to 3001.
Heroku randomly assigns a port number to run your app.
And this port number is passed to
the PORT environment variable.
Now let's look api.js.
This looks almost similar to server.js,
but the purpose of this file,
is to serve out APIs and server-side logic.
Which is why, what you see in line number 13,
is a bunch of code that exposes an endpoint,
which returns a JSON string that is success:true.
You'll also notice here that,
there is a different port on which this file runs.
And that is either 3002,
or you can send a value
to the API_PORT environment variable.
So whenever you run the serve command,
it executes both of these files,
which means there are two different
Express servers that are running.
One of which is serving out your static content,
and the other one is serving out your APIs.
But what you'll notice in this file is
the name of the environment variable,
which is API_PORT.
As you know, Heroku dynamically assigns port numbers.
And there is no way for you to know
which port number is free.
And the port number, which is dynamically assigned,
is sent to the PORT environment variable,
and not the API_PORT.
So, which is why when you deploy this file as is to Heroku,
this file fails to run,
because you can't supply a hard-coded port
because you never know if it is available or not.
And same as the case with 3002.
Now the only way in which you can get this file to run,
is by replacing API_PORT with just PORT.
But there is one problem that occurs when you do this.
Both api.js and server.js try to run on the same port
and you can't have two express servers running
on one port, which is why one of them is going to fail.
So one of the options we have here,
is to combine the code from both server.js and api.js,
into one file, so that
there is only one express server that is created,
that serves out both the static content and the APIs.
So I've chosen to merge the code from server.js into api.js.
And here is how the resulting code will look like.
So what you can see here is that,
in api.js, I'm using both
the standard HOST and PORT environment variables.
And if you remember, these two were the lines of code
required to serve out static content from server.js.
I've pasted both of them here.
And of course, I already have my logic
that creates APIs present underneath them.
However, there is one small change that I've made here.
So in server.js, if you go and see,
here it says app.use *
but here I have replaced it with a regular expression.
So that is because,
when you say app.use *
that means any HTTP request that comes to the server,
is going to send out static files.
But since this file is also serving out API endpoints
and whenever a user tries to hit /api endpoint,
instead of sending static content,
I need to send this JSON response.
I am modifying this to a regular expression that says,
if the request is coming to an endpoint
that starts with /api, then don't execute this.
And for all the other scenarios, execute this.
So that is what,
this line of code is doing.
So now that we have successfully merged both the files,
there is one more place in which
you need to make a small modification.
Now, back in package.jsn
we can see that the serve script is still trying
to run both the sub-scripts
that is serve:client and serve:api.
So we need to modify it,
in such a way that the serve script only runs one file.
And we can do that
by copying this command and pasting it here.
So now every time the serve script runs,
it's only going to execute server/api.js.
And because we've combined the code to serve
both static files and dynamic endpoints from this file,
it's going to all work when deployed to Heroku.
So let's now deploy this to Heroku.
I'll open up a Terminal,
create a Heroku app.
And once the app is created,
push all of my code, to the new Heroku remote endpoint.
I'll add all the files, then commit them.
And once the pre-commit hook has successfully executed,
push them to the remote endpoint.
It's going to automatically run the build script.
And then based on the information
we have given in the Procfile
it's going to run the serve command.
Now that the app has been deployed, let's launch it.
And here, you can see the app in action.
The static content is being served well.
Let's also look at the API endpoint
So let's copy the url, /api/v1/endpoint,
and then paste it here, and there you go.
You can see that you're getting a JSON response
from the API as well.
So this is how you deploy an app,
which has a custom Express API server to Heroku.
I've also committed all of this code to a GitHub repo,
and the link for that is available in the description.
So you can refer to that in case you run into any issues.
Thank you for watching.
If you've learned something,
be sure to like this video.
If you want to get more content like this
pushed directly to you, click subscribe,
and click that bell icon to get notifications.