Setup Heroku Hosting for Production
In this section, we're going to dive into the configuration changes necessary to really control our bundles in a production scenario. We'll get into:
- Optimizing bundles for size for Time to First Byte (TTFB)
- Exporting separate files from our
main.jsand loading them asynchronously.
- Server-side rendering for Time to First Paint (TTFP)
- Loading Fonts and Markdown
- Code splitting front end and back end code.
- HTTP2/Caching/CDNs and other futuristic asset considerations.
But first, we need a platform (or 2) to practice on. I use Heroku for most of my node projects. , which is an industry leader in cloud app deployments and runs atop Amazon Web Services.
We're going to start from a particular branch in our repo that kind of skips over the Choose Your Own Adventure section.
git clone https://github.com/lawwantsin/webpack-course.git cd webpack-course git checkout heroku npm install
Once installed, in your terminal:
Follow the prompts to enter your password.
Once complete you need to create a new project from within the project and
Procfile for it. This is a "process file" which tells Heroku what
commands to run on startup.
heroku create touch Procfile
web: npm run prod
package.json define a new script shortcut:
"prod": "NODE_ENV=production node src/server/main.js"
We're explicitly setting the environment before the command, even though Heroku
defines it anyway. Run
heroku config to see the
We do this so we can run heroku locally in preparation for the push to prod.
src/server/express.js we see that express.js is already setup for
production, by wrapping much of the DevServer middleware in an if statement.
Everything works except the Server's Port. Heroku sets this in a
environment variable, so if this is set, we'll use it, otherwise, default to
const PORT = process.env.PORT || 8080
We have nothing in our dist folder, and the static middleware will be looking there. So let's fill that folder up:
npm run build
That should give you an
index.html and a js and image file in dist. Now we can
run locally to make sure all is working.
In your browser go to http://localhost:5000. And it should be working. You can see the site is working.
But there's an error.
Hot Module Reloading is still being added to the client
it's still in the
We can comment out in
main.js for now.
// require("babel-runtime/regenerator") // require("webpack-hot-middleware/client?reload=true")
webpack.dev.js we can also comment out the HMR Plugin.
plugins: [ // new webpack.HotModuleReplacementPlugin(), new webpack.NamedModulesPlugin(), ... ]
Okay, now we can rerun our build and restart heroku locally.
npm run build heroku local
git checkout heroku-final
And the error is gone.
Finally, let's push this up to heroku, by committing our changes and pushing
them to heroku's git repo. We can see using
heroku create added a git remote
to our project in
git commit -am "ready for production" git push heroku heroku:master
Usually Heroku likes to use the master branch, but since we're on another branch, we can simply use this color syntax to specify which branch will be pushed to master in our remote. In this case the branch is heroku, but it could be any name.