28 May 2018 ~ 6 min read
Deploy your Webpack apps to Heroku in 3 simple steps
If you are starting on web-development in 2018, I am sure all or at least most of your frontend projects are by default built and bundled using Webpack. Webpack has sunk into almost all the frontend projects we use nowadays and we have a really strong online dev community around Webpack to support us. If you are a beginner or even an intermediate to Webpack, I highly recommend this link to get started on adding Webpack to your working web application.
This post is mainly aimed at people who are already using Webpack applications in their personal, GitHub or even client projects to successfully deploy and host their web applications on Heroku.
If you are new to Heroku, please check out the link to read further.
In this post, I am going to quickly cover how to make an existing Webpack application deployment ready, (irrespective of the frontend libraries React or Vue JS) and help deploy your code on your Heroku account, in three simple steps. I have also attached my code repo at the end of the post, please feel free to clone/fork and play around with it.
Assuming that you already have a working Webpack application, let’s get into making it deployment ready for Heroku.
1. Build an express server
The first step is to build a simple express server to serve your application. What is an Express server you ask?
An Express is a web-application framework that basically runs on a node environment. In our case it serves our application from a port available in the same environment.
This is all you need to know to get started with building an express server. Unlike full-fledged express web applications, we are not going to serve each page based on an express router (it’s not really important to know what I am talking about tbh..! ). Instead, we are going to build a simple standard express server to serve our index.html file.
This code might seem repetitive across many other blogs because it pretty much is the standard for building a simple express web server. Create a server.js and copy- paste this code.
const express = require("express");
const path = require("path");
const port = process.env.PORT || 8080;
const app = express();
// the __dirname is the current directory from where the script is running
app.use(express.static(__dirname));
// send the user to index html page inspite of the url
app.get("*", (req, res) => {
res.sendFile(path.resolve(__dirname, "index.html"));
});
app.listen(port);
Explanation
- __dirname points to the current directory from where the server.js is being run from and that is treated as the root of your project.
- When we tell the express app to use a directory it automatically picks up the index.html file to serve.
- We have also added an extra check to redirect the users back to index.html to avoid ‘not found’ errors and for the sake of simplicity.
2. Webpack Production Build
This is a crucial step for us and it ensures that our application properly spits out a bundled js which we can use for deployment.
In the Webpack-cli, this is a simple one-liner, and it should spit out the output based on webpack.config.js we have.
webpack -p
In your webpack.config.js file, if you have the following code, you will see a bundle.js generated at the root of your application.
module.exports = {
entry: \[
'./src/index.js'
\],
output: {
path: __dirname,
publicPath: '/',
filename: 'bundle.js'
}
}
On the flip-side when you do not have this config setup, your output will be generated in a /dist folder under the name main.js.
In both the cases, we need an HTML file and the location of your index.html determines where your express application should point to. Let’s say if you generate your index.html inside your /dist folder using a [htmlWebpackPlugin], then the code that points to express app.use should be modified in the following way
app.use(express.static(__dirname + '/dist'));
In my case I do not use a [htmlWebpackPlugin], instead I have a predefined index.html at the root of the folder where bundle.js is linked through the script tag.
Note: At this stage if you are not clear on what I am talking about, please download the code repo at the end of this post and check out the webpack.config.js file.
3. Verify and deploy
If you have successfully generated the bundled js file either in the /dist folder or in your custom location and made sure that your generated/pre-defined index.html has a script tag pointing to the bundled js(main.js / bundle.js), you are now ready to ready to deploy your application.
But before we jump the guns and deploy we need to make sure that the express server properly serves the application to localhost:8080.
Run the following command in your terminal and verify if your application is being served on port 8080.
node server.js
Yes? Great, you are just two scripts away from deployment. No? verify your server.js and make sure that you are pointing to the right directory and also check your webpack.config.js to see where your bundled js is being generated.
Now that we are here finally, close to deployment, we need to add two lines of script in our package.json file. Add these two following commands under the scripts section.
"scripts": {
"start": "node server.js", // serves the application
"heroku-postbuild": "webpack -p" // runs after installation
},
Note: Please replace the existing “start” command with “dev” and continue running dev server using npm run dev instead of start.
Explanation
Heroku automatically installs all our dependencies and goes on to do a post-build operation before serving our application. In this post-build operation, we do the production bundling of our js files and allow Heroku to kick-start the application by running the start command.
Once you are done with the above, now let’s look at the deploying it to Heroku. Assuming that you already have a Heroku login and an account. Install the Heroku-cli following the instructions on this link.
Once you have installed the Heroku-CLI, follow the instructions below to deploy from the command line one after another.
heroku login
heroku create
git init
heroku git:remote --app <your-heroku-app-name>
git add . && git commit -m "initial commit"
git push heroku master
Explanation
- Heroku login prompts you to enter username and password.
- Heroku create command creates an application and gives you back the application URL and Heroku’s git repo for your project.
- Re-initialize your project by running git init.
- Add Heroku’s git repo as the remote repo of your current application.
- Git add and commit .
- Push to Heroku’s git repository.
Visit your application URL generated at step 2, during Heroku create, you should be able to view your application. Voila !! your app is deployed :)
Conclusion
This should work for all the Webpack applications, irrespective of their frontend library, based on your web pack config file. The key thing to note here is your package.json file, make sure all the dependencies and dev-dependancies are part of it including Webpack.
I have created a Webpack 4 boilerplate with react and express server on my Github, please feel free to fork the code and try to run all the commands I have mentioned above.
GitHub Repo Webpack-react-express Boilerplate