Error running Grunt Build on Heroku - node.js

So I am installing a simple Backbone application on Heroku that I generated using the Yeoman Backbone generator. I have a very simple node.js server file to serve up the Backbone application, but had trouble deploying to Heroku due to missing dependencies:
Output:
remote: Loading "Gruntfile.js" tasks...ERROR
remote: >> Error: Cannot find module 'connect-livereload'
remote: Warning: Task "build" not found. Use --force to continue.
Server.js
var express = require('express');
var app = express();
var port = process.env.PORT || 8080;
app.use(express.static(__dirname + '/app'));
app.listen(port, function() {
console.log('App is running on port ' + port);
});
packages.json
{
"name": "ssi",
"version": "0.0.0",
"dependencies": {
...
},
"devDependencies": {
"bower": "^1.4.1",
"connect": "^3.3.5",
"grunt": "^0.4.5",
"grunt-cli": "^0.1.13",
...
},
"engines": {
"node": ">=0.10.0"
},
"scripts": {
"start": "node server.js",
"test": "mocha",
"postinstall": "bower install && grunt build"
}
}
Originally I had problems running bower install because I hadn't added bower to the dependencies in packages.json, so I thought, "maybe I have to add it to the normal dependencies list instead of devDependencies, since this is my deployment process.
So I added bower and grunt to the dependencies list, but then it would fail while running grunt build because now it couldn't find any of the required grunt modules used during the build task. I figured there must be a better way to let Heroku see these dependencies without adding them to the production dependencies list.
I already tried setting the NODE_ENV variable to "development" like so:
$ heroku config:set NODE_ENV=development
But that didn't seem to have any effect. So since I am answering my own question, the hypothetical question in question is:
"How do I get Heroku to run bower install and grunt build without having to move all my dependencies into the production dependencies list?"
N.B. - I realise that a "proper" deployment process might instead add all this stuff to a distribution folder, including the dependencies. This question and answer are aimed at those, like me, who are instead attempting to just push their current build to Heroku without having to set up a "better" deployment process just yet.

In the end the solution was very simple. In the first few lines of the console output when pushing my app to Heroku, is the following line:
remote: NPM_CONFIG_PRODUCTION=true
It appears that changing this environment variable to false will cause NPM to install the devDependencies list as well. So just type in the following:
$ heroku config:set NPM_CONFIG_PRODUCTION=false
And you should then see Heroku build and deploy successfully.

Related

How to deploy a Typescript, NodeJS and Express app to Heroku

I wanted to provide a howto on this as I couldn't find any complete information. I thought that this seemed most appropriate in Stackoverflow documentation. However it has been sunsetted *-) - Sunsetting Documentation (*).
Instead I will write this as a StackOverflow Q&A.
How to deploy a Typescript, NodeJS and Express app to Heroku
I created a project (https://gitlab.com/OehmSmith_Examples/herokumovies) that includes a README describing what needs to be done and I will reproduce that here. As a good StackOverflow practice I will also provide a copy of all the code at the bottom of this post.
Tutorial - Deploy Typescript NodeJS Express app to Heroku
This tutorial will work from https://amenallah.com/node-js-typescript-jest-express-starter/ as the base app. I have no affiliation with that site or the author. I chose it as it is simple and works. It is also an example of good OO Typescript code.
Install typescript
Most tutorials or even the official documentation in https://www.typescriptlang.org/docs/handbook/typescript-in-5-minutes.html say to install typescript globally:
> npm install -g typescript
Heroku doesn't have a global install of typescript so it needs to be kept locally. The example project does just this:
> npm i -D nodemon rimraf typescript ts-node ts-jest jest #types/jest #types/node
#types/node
In the case you have pinned your #types/node at an older version you will see something like this error:
~/AppData/Roaming/nvm/v11.15.0/node_modules/typescript/lib/lib.es2015.iterable.d.ts:41:6 - error TS2300: Duplicate identifier 'IteratorResult'.
41 type IteratorResult<T, TReturn = any> = IteratorYieldResult<T> | IteratorReturnResult<TReturn>;
~~~~~~~~~~~~~~
node_modules/#types/node/index.d.ts:170:11
170 interface IteratorResult<T> { }
~~~~~~~~~~~~~~
'IteratorResult' was also declared here.
node_modules/#types/node/index.d.ts:170:11 - error TS2300: Duplicate identifier 'IteratorResult'.
170 interface IteratorResult<T> { }
~~~~~~~~~~~~~~
~/AppData/Roaming/nvm/v11.15.0/node_modules/typescript/lib/lib.es2015.iterable.d.ts:41:6
41 type IteratorResult<T, TReturn = any> = IteratorYieldResult<T> | IteratorReturnResult<TReturn>;
~~~~~~~~~~~~~~
'IteratorResult' was also declared here.
Found 2 errors.
From TypeScript: Duplicate identifier 'IteratorResult'. And as per that you need to update your version of #types/node. This was a problem I struck as I was working with older code and wanted to include this discussion of it.
Update port for cloud service
Change the index.ts to be the following instead since the original code hard-coded port 5000:
app.listen(process.env.PORT, () => {
console.log(`server started on port ${process.env.PORT}`)
});
To allow for this I have added the PORT to the npm scripts, including adding a start:dev so you can run it like Heroku does from the compiled typescript.
"start:dev": "PORT=5000 node dist/index.js",
"dev": "PORT=5000 nodemon --exec ts-node src/index.ts --watch src",
Or it can be set in a .env file:
PORT=5000
NPM dependencies
Heroku will NOT install dev dependencies (neither will any other cloud provider). Therefore you need to move some dependencies to the main block. For example, a NestJS application has these as Dev Dependencies and they need to be moved:
#nestjs/cli
Dummy data
I added this constructor to the MoviesApi.ts:
constructor() {
// setup some dummy data
movies.push({
name: 'Pirates of the caribbean',
rating: 8.5
})
movies.push({
name: 'Star Wars: A new hope',
rating: 8.7
})
}
Heroku
Now deploy to Heroku
Setup an account if you don't already have one and create an app on Heroku
In your terminal:
heroku login
heroku create moviesheroku // this needs to be unique
You may need to add the returned git url as a remote (check with git remote -v):
git remote add heroku <git url>
Lookup or search for buildpacks with (the next step already specifies those I use):
Lookup at: https://devcenter.heroku.com/articles/buildpacks#officially-supported-buildpacks
Search with:
heroku buildpacks:search typescript
Add buildpacks:
heroku buildpacks:add zidizei/typescript
heroku buildpacks:add heroku/nodejs
Confirm buildpacks:
heroku buildpacks
Commit to your local repository
git init // if not already done
git add --all
git ci -m "Initial commit. Test project all setup and should be ready to 'serve' but not yet ready to deploy to heroku"
Run with
npm dev # OR
npm run start:dev # It depends on your npm scripts
Test with postman or similar or run this from the command-line:
curl http://localhost:5000/movies
Test that it transpiles with npm run build
Update the npm scripts so that after installation (npm install) on Heroku, it will build it before attempting to npm run start
"postinstall": "npm run build" # Depends on your npm scripts
Commit to local repository:
git add --all
git ci -m "Now it should deploy, build and run on heroku"
Deploy to heroku. It should build and start up.
git push heroku master
Test (assuming the app you heroku created is moviesheroku - adjust accordingly)
curl https://moviesheroku.herokuapp.com/movies
Variations
Procfile
I haven't specified a Procfile telling Heroku anything about the app. Fortunately it creates its own defaults by determining that this is a node + npm app. However you can explicitly define this and will need to perform this action if you have multiple apps or similar. You could add a Procfile to contain (this is the default):
web: npm start
Node and NPM version
Heroku also defaults to using one of the most recent versions of these. You could explicitly set the versions at the top-level in the package.json file like:
"engines": {
"node": "10.x",
"npm": "6.x"
},
Although if you don't specify a npm version then Heroku will use a sensible default for the version of node.
Concluding thoughts
I had this going in only a couple hours. The main issues I needed to work out is that typescript has to be local, not global. And the buildpacks. The PORT is an issue also though every cloud provider requires the use of process.env.PORT so this was obvious to me.
Azure was a nightmare and took days, but that was mainly because the workplace I was at insisted on using Windows servers. Long story and I won't go in to it.
AWS was so convoluted. I didn't get the instance I had working after trying for a day. however I do need to try again. The app I was trying used the https://tsed.io/ library. Simple Node / Typescript / Express apps should work out quite easily.
(*) - the sunsetting of documentation was a little bit surprising though given it happened over 2 years ago I guess it wasn't something I used. And I always thought that the Q&A was the easiest place for documentation.
Code
.gitignore
node_modules
dist
coverage
.jest.config.js
module.exports = {
preset: 'ts-jest',
testEnvironment: 'node'
};
package.json
{
"name": "movies",
"version": "1.0.0",
"description": "Example from https://amenallah.com/node-js-typescript-jest-express-starter/ but then modify and / or show steps for how to deploy this Typescript NodeJS Express RESTful app to Heroku.",
"main": "index.js",
"scripts": {
"build": "rimraf dist && tsc",
"postinstall": "npm run build",
"start": "node dist/index.js",
"start:dev": "PORT=5000 node dist/index.js",
"dev": "PORT=5000 nodemon --exec ts-node src/index.ts --watch src",
"test": "jest --watch",
"coverage": "jest --coverage"
},
"keywords": [],
"author": "",
"license": "ISC",
"devDependencies": {
"#types/express": "^4.17.2",
"#types/jest": "^24.0.25",
"#types/node": "^13.1.2",
"jest": "^24.9.0",
"nodemon": "^2.0.2",
"rimraf": "^3.0.0",
"ts-jest": "^24.2.0",
"ts-node": "^8.5.4",
"typescript": "^3.7.4"
},
"dependencies": {
"body-parser": "^1.19.0",
"express": "^4.17.1"
}
}
tsconfig.json
{
"compilerOptions": {
"target": "es5",
"module": "commonjs",
"outDir": "dist",
"sourceMap": false,
"allowSyntheticDefaultImports": true,
"baseUrl": ".",
"paths": {
"*": [
"node_modules/",
],
"typings/*": [
"src/typings/*"
]
},
},
"include": [
"src/**/*.ts"
],
"exclude": [
"src/test/**/*.spec.ts"
]
}
src/api/MoviesApi.ts
import IResource from "typings/IResource";
let movies: object[] = []
export default class MoviesApi implements IResource {
constructor() {
// setup some dummy data
movies.push({
name: 'Pirates of the caribbean',
rating: 8.5
})
movies.push({
name: 'Star Wars: A new hope',
rating: 8.7
})
}
create(data: any): any {
movies.push(data)
return data
}
findMany(): any[] {
return movies;
}
}
src/test/api/Movies.spec.ts
import IResource from '../typings/IResource'
import MoviesApi from '../api/MoviesApi'
const moviesApi: IResource = new MoviesApi()
describe('Movies API', () => {
it('should create a new movie', () => {
const movieData: object = {
name: 'Pirates of the caribbean',
rating: 8.5
};
const movie: object = moviesApi.create(movieData);
expect(movie).toEqual(movieData)
})
});
src/typings/IResource/index.d.ts
export default interface IResource {
create(data: any): any
findMany(): any[]
}
src/index.ts
import * as express from 'express'
import * as bodyParser from 'body-parser'
import MoviesApi from './api/MoviesApi'
const app = express();
const moviesApi = new MoviesApi();
app.use(bodyParser.json());
app.post('/movies', (req: express.Request, res: express.Response) => {
res.json(moviesApi.create(req.body))
});
app.get('/movies', (req: express.Request, res: express.Response) => {
res.json(moviesApi.findMany())
});
app.listen(process.env.PORT, () => {
console.log(`server started on port ${process.env.PORT}`)
});

Loopback 4 deployment in heroku, lb-tsc not found error

I'm trying to deploy a loopback 4 app into heroku.
But after publishing it npm-start command not working in heroku console.
its throwing sh: 1: lb-tsc not found.
package.json is as follows
"devDependencies": {
"#loopback/build": "^3.0.0",
"#loopback/eslint-config": "^5.0.0",
"#loopback/testlab": "^1.10.0",
"#types/node": "^10.17.6",
"#typescript-eslint/eslint-plugin": "^2.10.0",
"#typescript-eslint/parser": "^2.10.0",
"eslint": "^6.7.2",
"eslint-config-prettier": "^6.7.0",
"eslint-plugin-eslint-plugin": "^2.1.0",
"eslint-plugin-mocha": "^6.2.2",
"source-map-support": "^0.5.16",
"typescript": "~3.7.3"},
"scripts": {
"build": "lb-tsc",
"build:watch": "lb-tsc --watch",
"clean": "lb-clean dist *.tsbuildinfo",
.......
"lb-tsc": "lb-tsc",
"postinstall": "npm run lb-tsc"
}
Creating a Procfile in the root of the project containing web: node . fixed this for me. Without it, Heroku will default to starting the app by calling npm run which tries to run the build process, and since #loopback/build is set up as a dev dependency by default, this results in the lb-tsc not found error.
When heroku runs node application the value of process.env.NODE_ENV is "production" you may check it from heroku terminal bash by typing node and then process.env
And this means that dev dependencies are not resolved.
Below steps work fine to me
Open package.json file copy all from dev dependeny section and paste it to dependency section in package.json
git add . then git commit and then git push heroku master
Another Solution:
After pushing files to heroku using git push heroku master go to heroku terminal from https://dashboard.heroku.com/ and start console and then run command node dist/index.js so this command will start loopBack application make sure dist folder is available.
I have tried many solutions and it works when I do the following things :
Make sure heroku has a nodeJs builpack running in your terminal
heroku buildpacks:set heroku/nodejs
Then, create a Procfile to the root of your project and add :
web: node index.js
Finally add a heroku-postbuild script :
"heroku-postbuild": "npm run build"
Hope it helps !
Try to install it in the command line:
npm i -g #loopback/cli
npm i -g #loopback/build
I'm using it in macos from command line.
I read somewhere to replace web: slc run with web: node . in Procfile, and it seems to be working in Heroku! I do see the explorer and can use all the endpoints.
I mention this also in this Github issue:
https://github.com/strongloop/loopback.io/issues/810

NextJS cannot find a valid build in the '.next' directory

I looked at the following question before asking this one but I believe mine is different because I am not using Docker: Nextjs fails to find valid build in the '.next' directory in production node_env
I also tried this approach of removing the '.next' folder but still get the same issue.
After fixing a host of other issues, I am down to one I cannot seem to resolve. When I try to deploy to Heroku I keep getting the following error:
node server.js
Could not find a valid build in the '.next' directory! Try building your app with 'next build' before starting the server.
Here is my package.json file:
{
"name": "StarterApp",
"version": "1.0.0",
"engines": {
"node": "10.4.1"
},
"description": "",
"main": "index.js",
"scripts": {
"test": "mocha",
"dev": "node server.js"
},
"author": "",
"license": "ISC",
"dependencies": {
"express": "4.16.3",
"fs-extra": "^5.0.0",
"ganache-cli": "^6.1.3",
"mocha": "^5.2.0",
"next": "^4.2.3",
"next-routes": "^1.4.2",
"node-gyp": "^3.7.0",
"react": "^16.4.1",
"react-dom": "^16.4.1",
"rebuild": "^0.1.2",
"semantic-ui-css": "^2.3.2",
"semantic-ui-react": "^0.79.1",
"sha3": "^1.2.2",
"solc": "^0.4.24",
"truffle-hdwallet-provider": "0.0.3",
"web3": "^1.0.0-beta.34"
}
}
Server.js file:
const { createServer } = require('http');
const next = require('next');
const app = next({
dev: process.env.NODE_ENV !== 'production'
});
const routes = require('./routes');
const handler = routes.getRequestHandler(app);
app.prepare().then(() => {
createServer(handler).listen(5000, (err) => {
if (err) throw err;
console.log('Ready on localhost:5000');
});
});
The app deploys without issue locally but I get this error when deploying to Heroku. What am I doing wrong?
npm run build
then
npm run start
solved my problem.
First
npm run-script build
Then
npm run start
Just see the error carefully:
Error: Could not find a production build in the 'E:\Developer's Area\weatherteller\.next' directory. Try building your app with 'next build' before s at Server.readBuildId (E:\Developer's Area\weatherteller\node_modules\next\dist\next-server\server\next-server.js:146:355)
at new Server (E:\Developer's Area\weatherteller\node_modules\next\dist\next-server\server\next-server.js:3:120)
at createServer (E:\Developer's Area\weatherteller\node_modules\next\dist\server\next.js:2:638)
at start (E:\Developer's Area\weatherteller\node_modules\next\dist\server\lib\start-server.js:1:323)
at nextStart (E:\Developer's Area\weatherteller\node_modules\next\dist\cli\next-start.js:19:125)
at E:\Developer's Area\weatherteller\node_modules\next\dist\bin\next:27:115
while running
npm start
It's not able to locate the production build which is required to launch the next app. While creating next app using
npm install next react react-dom --save
.next folder was not created so you need to create the .next folder first using
npm build
which will consist of all your production build files.
After npm build the folder will be created and you can run your app using
npm start
Also, make sure these scripts are in your next app
"scripts": {
"dev": "next",
"build": "next build",
"start": "next start"
},
Hope this resolves your error 😀😀
I had the same issue once.
First, remove package-lock.json or yarn.lock files and node_modules folder and make sure you install all the packages again with the yarn command.
I had to run yarn build first and then the yarn start command was working fine afterward.
Also if the currently used port is taken by another app you will have issues running your dev environment. You can easily fix that by going into the package.json file and modifying the "dev" script like this: "dev": PORT=7080 next dev".
Also possibly you are mixing Next.js with React because in Next.js you should use yarn dev to start your project for development instead of yarn start.
I hope this was helpful to you.
NextJS building may be (depending on your project size), be extremely large, something that can cost you money during deploys.
You can apply the following to your package.json
{
"script": {
"build": "next build",
"heroku-postbuild": "npm run build",
"start": "next start"
}
}
I was getting this error when trying to start a production server from the build directory after setting.
distDir: 'build',
actual error
Error: Could not find a production build in the '/home/username/awesome-app/build/build' directory. Try building your app with 'next build' before starting the production server. https://nextjs.org/docs/messages/production-start-no-build-id
and my start command
$ next start build
so I moved the next build directory to another directory named build and it works, and if you are using environment variable put that file inside the build directory.

Deploying Node.js app to Heroku. Error NPM_CONFIG_LOGLEVEL=error

I am deploying my node.js application on heroku but when i run my app it shows me Application error and when i check my logs file i found NPM_CONFIG_LOGLEVEL=error
My package.json file is:
{
"name": "wework-1",
"version": "1.0.0",
"description": "We Work Meteor, a job board and developer directory for Meteor specific work https://www.weworkmeteor.com",
"main": "",
"engines": {
"node": "= 4.5.0",
"npm": "= 3.9.6"
},
"scripts": {
"test": "echo \"Error: no test specified\" && exit 1",
"lint": "eslint .",
"pretest": "npm run lint --silent"
},
"repository": {
"type": "git",
"url": "git+https://github.com/rohitchaudhary701/wework-1.git"
}
}
My logs file is:
-----> Node.js app detected
-----> Creating runtime environment
NPM_CONFIG_LOGLEVEL=error
NPM_CONFIG_PRODUCTION=true
NODE_VERBOSE=false
NODE_ENV=production
NODE_MODULES_CACHE=true
-----> Installing binaries
engines.node (package.json): = 4.5.0
engines.npm (package.json): = 3.9.6
Resolving node version = 4.5.0 via semver.io...
Downloading and installing node 4.5.0...
Resolving npm version = 3.9.6 via semver.io...
Downloading and installing npm 3.9.6 (replacing version 2.15.9)...
-----> Restoring cache
Loading 2 from cacheDirectories (default):
- node_modules
- bower_components (not cached - skipping)
-----> Building dependencies
Installing node modules (package.json)
-----> Caching build
Clearing previous node cache
Saving 2 cacheDirectories (default):
- node_modules
- bower_components (nothing to cache)
-----> Build succeeded!
! This app may not specify any way to start a node process
https://devcenter.heroku.com/articles/nodejs-support#default-web-process-type
-----> Discovering process types
Procfile declares types -> (none)
Default types for buildpack -> web
-----> Compressing...
Done: 12.7M
-----> Launching...
Released v6
https://whispering-cliffs-66861.herokuapp.com/ deployed to Heroku
App url is https://whispering-cliffs-66861.herokuapp.com/
From your logs:
This app may not specify any way to start a node process
You probably need to do two things:
add start script in package.json
make sure you listen on the port in process.env.PORT
Take a look at this example:
https://github.com/rsp/node-live-color
See package.json and the start script:
"scripts": {
"start": "node server.js"
},
See:
https://github.com/rsp/node-live-color/blob/master/package.json#L6
And see the port number initialization:
const port = process.env.PORT || 3338;
// ...
server.listen(port, () => {
console.log(`Listening on http://localhost:${port}/`);
});
See:
https://github.com/rsp/node-live-color/blob/master/server.js#L13
https://github.com/rsp/node-live-color/blob/master/server.js#L46-L48
If you want easier deploy with Deploy to Heroku button then you may also need an app.json file:
https://github.com/rsp/node-live-color/blob/master/app.json
But for manual deploys you should only need a start script in package.json so that you app could be started with npm start and your app needs to take the port to listen to from the PORT environment variable.
You can test it with locally running:
PORT=2255 npm start
and making sure that you can access your app on http://localhost:2255/ for this and any other port you specify. If you cannot start your app with the above command then your app is unlikely to run on Heroku. You could also have a Procfile presend but without it you should at least have npm start working, see:
https://devcenter.heroku.com/articles/procfile
https://devcenter.heroku.com/articles/nodejs-support
You seem to be trying to deploy a Meteor app to Heroku.
Heroku is not as integrated with Meteor as Galaxy is, or as Modulus / Xervo used to be.
Heroku will detect a node-like app, but you will need first to convert your Meteor app into a Node.js app, typically using meteor build command and uploading the resulting server bundle, or using some MUP thing.
A simple alternative is to use a 3rd party Buildpack, which will do the conversion for you once you upload your Meteor app to Heroku.
You will find plenty resources for that on the above link or here on SO.
See for example: Heroku errors with Meteor 1.4.1.1
Note: the NPM_CONFIG_LOGLEVEL=error line is a setting, not an actual error…
What does your Procfile look like? Make sure you don't have web: node app.js in the Procfile. I had the same error and didn't need to use the Procfile. Once I removed it started working.
For me, it turned out i required a package that was not in my package.json (dependency), when I added it, the application started working.

How to deploy node that uses Gulp to heroku

I'm using gulp and also gulp plugins like gulp-minify-css, gulp-uglify etc (that listed as npm dependencies for my application).
Also I don't commit npm_modules folder and public folder, where all generated files are. And I can't figure out how to build my app (I have gulp build command) after deploy and setup my server (it's already looking for public folder).
It seems me a bad idea to commit before upload. Maybe there are some gentle decisions... Any thoughts?
Forked from: How to deploy node app that uses grunt to heroku
I was able to get this to work by adding this into my "package.json" file:
"scripts": {
"start": "node app",
"postinstall": "gulp default"
}
The postinstall script is run after the build pack. Check this for more information. The only annoying thing is that all of your dependencies have to live under "dependencies" instead of having separate "devDependencies"
I didn't need to do anything else with buildpacks or configuration. This seems like the simplest way to do it.
I wrote about the process I used here
You can do it!
There were a few key measures that helped me along the way:
heroku config:set NODE_ENV=production - to set your environment to 'production'
heroku config:set BUILDPACK_URL=https://github.com/krry/heroku-buildpack-nodejs-gulp-bower - to enable a customised Heroku buildpack. I incorporated elements of a few to make one that worked for me.
A gulp task entitled heroku:production that performs the build tasks that need to happen on the heroku server when NODE_ENV===production. Here's mine:
var gulp = require('gulp')
var runSeq = require('run-sequence')
gulp.task('heroku:production', function(){
runSeq('clean', 'build', 'minify')
})
clean, build, and minify are, of course separate gulp tasks that do the magic gulpage
If your application lives in /app.js, either:
(A) make a Procfile in the project root that contains only: web: node app.js, or
(B) add a start script to your package.json:
"name": "gulp-node-app-name",
"version": "10.0.4",
"scripts": {
"start": "node app.js"
},
And like #Zero21xxx says, put your gulp modules in your normal dependencies list in package.json, not in the devDependencies, which get overlooked by the buildpack, which runs npm install --production
The easiest way I found was:
Setup gulp on package.json scripts area:
"scripts": {
"build": "gulp",
"start": "node app.js"
}
Heroku will run build before starting the app.
Include gulp on dependencies instead of devDevependencies, otherwise Heroku won't be able to find it.
There is more relevant info about it on Heroku Dev Center: Best Practices for Node.js Development
How to deploy to Heroku (or Azure) with git-push
// gulpfile.js
var gulp = require('gulp');
var del = require('del');
var push = require('git-push');
var argv = require('minimist')(process.argv.slice(2));
gulp.task('clean', del.bind(null, ['build/*', '!build/.git'], {dot: true}));
gulp.task('build', ['clean'], function() {
// TODO: Build website from source files into the `./build` folder
});
gulp.task('deploy', function(cb) {
var remote = argv.production ?
{name: 'production', url: 'https://github.com/<org>/site.com', branch: 'gh-pages'},
{name: 'test', url: 'https://github.com/<org>/test.site.com', branch: 'gh-pages'};
push('./build', remote, cb);
});
Then
$ gulp build --release
$ gulp deploy --production
See also
https://github.com/koistya/git-push
https://github.com/kriasoft/react-starter-kit (tools/deploy.js)
There's a specific startup script that Heroku provides;
"scripts": {
"start": "nodemon app.js",
"heroku-postbuild": "gulp"
}
note that in your gulpfile.js (gulpfile.babel.js if you es6-ifed your gulp build process), you should have a task name default which will be automatically run after the dependencies are installed via Heroku.
https://devcenter.heroku.com/articles/nodejs-support#heroku-specific-build-steps
Heroku finds that there is a gulpfile in your project and expects there to be a heroku:production task (in the gulpfile). So all you need to do is register a task that matches that name:
gulp.task("heroku:production", function(){
console.log('hello'); // the task does not need to do anything.
});
This is enough for heroku to not reject your app.
I had to take a slightly different to get this working because I'm using browsersync:
package.json
"scripts": {
"start": "gulp serve"
}
gulp.js
gulp.task('serve', function() {
browserSync({
server: {
baseDir: './'
},
port: process.env.PORT || 5000
});
gulp.watch(['*.html', 'css/*.css', 'js/*.js', 'views/*.html', 'template/*.html', './*.html'], {cwd: 'app'}, reload);
});
Setting the port to be environment port is important to prevent error when deploying in Heroku. I did not need to set a postinstall script.
It's possible to piggyback any command you want over the top of npm install. Much like the linked question in your post, you can add an install directive in scripts within package.json that will run after all the node deps have been installed that does the build.
Your main issue will be sorting out the correct relative paths for everything.
{
...
scripts:{
install: "YOUR GULP BUILD COMMAND"
}
...
}

Resources