lvarayut / relay-fullstack

:point_up::running: Modern Relay Starter Kit - Integrated with Relay, GraphQL, Express, ES6/ES7, JSX, Webpack, Babel, Material Design Lite, and PostCSS
https://lvarayut.github.io/relay-fullstack/
MIT License
986 stars 126 forks source link

Improving Heroku deploys #37

Closed kkostov closed 8 years ago

kkostov commented 8 years ago

I've used the yo generator to create a new solution and then directly publish it to Heroku.

This unfortunately did not succeed without some tweaks to the build tasks.

Tweak 1

Heroku has a 60 second timeout for apps to startup and bind to $PORT.

After some poking around, I discovered that the app was just taking too long to transpile while running the current "deploy" command:

"cross-env NODE_ENV=production webpack --config webpack.config.js && npm run update && cross-env NODE_ENV=production babel-node server/index.js"

Of course, the time it takes a Heroku instance to perform this step depends entirely on the available resources. I was using the "Free" tier containers for the task.

I was wondering if it would be helpful to further customise the build process for such cases and have the transpiler run in advance. For example:

package.json: "heroku-postbuild": "cross-env NODE_ENV=production webpack --config webpack.config.js && cross-env NODE_ENV=production babel ./server --out-dir ./lib"

Procfile: web: node ./lib/index.js

That way, any time an instance spins up, it will directly start from the already transpiled output of the app (which is very fast).

Tweak 2

Heroku doesn't seem to resolve babel from path, so the following change to the npm tasks was required:

"scripts": { "start": "nodemon --watch server/data/**/*.js --exec \"npm run update && ./node_modules/.bin/ server/index.js\"", "update": "babel-node server/utils/updateSchema.js", "deploy": "cross-env NODE_ENV=production webpack --config webpack.config.js && npm run update && cross-env NODE_ENV=production ./node_modules/.bin/babel-node server/index.js", "lint": "eslint --ignore-path .gitignore client server", "heroku-postbuild": "cross-env NODE_ENV=production webpack --config webpack.config.js && cross-env NODE_ENV=production ./node_modules/.bin/babel ./server --out-dir ./lib" },

Tweak 3

The favicons-webpack-plugin dependency should be moved to the "dependencies" section of package.json. It is required by webpack during build so both will be required at runtime.

Tweak 4

Include an engines section in package.json. By default Heroku would use node v4 or something which is rather inconvenient if it doesn't happen to match the local environment. As mentioned in Heroku's best practices it is not a bad idea to explicitly mention node's version so it can be deployed accordingly e.g.:

"engines": { "node": "6.6.0" }

I have the changes already made in a local repo so if the above seem acceptable I can submit a PR right away.

lvarayut commented 8 years ago

Thanks @kkostov, that's the awesome improvement 👍. The PR would be very appreciated