Many tutorials about deploying a Vue app to Heroku are using a very simple setup with no server (or a really simple one only using express as a server dependency).
But what about deploying an app with more complex server which has a lot of dependencies? I couldn’t find a good and working tutorial, so I wrote this one.
My Vue App is not only a frontend, but also needs a backend. Of course I could deploy the frontend and backend to different services and maybe utilize CDNs for the frontend, but I wanted to have everything in the same repository and server.
All the Node.js server code is in the root folder and I have a seperate
frontend folder for my Vue.js app.
Developing the project locally was no problem. That’s why I thought pushing to Heroku would as well be a piece of cake.
My server code needs a simple
npm install && npm start and the Vue.js app has to be build with
npm run build. On the server side I am using
fastify and with the help of
fastify-static I am serving the
frontend/dist folder to the users.
So, in order to build everything upon deployment, the command for the build step in my root package.json would be:
cd frontend && npm run build? Wrong!
First of all, all the Vue.js dependencies are not installed, so we are missing a
npm install in the frontend folder. But Heroku apparently sets
NPM_CONFIG_PRODUCTION=true so when running an
npm install no devDependencies get installed. I tried different approaches to get Heroku to install and build everything correctly (e.g. https://stackoverflow.com/questions/22954782/install-devdependencies-on-heroku , https://dev.to/jmbejar/how-to-quickly-deploy-a-vuejs-app-to-heroku-5b0f) but in the end I resorted to a simple build script:
#/bin/bash npm install —only=dev # installs only dev dependencies npm install # installs prod dependencies npm run build # builds the Vue.js app
This script resides in the
frontend folder. And I call this script from the root
package.json by using
“heroku-postbuild”: “cd frontend && ./build.sh”,
Now upon deployment all my server dependencies get installed as well as my Vue.js frontend being build.
There are surely other ways to accomplish this, but my approach works for me and is easy to understand.