Deploying ionic2 on Heroku


#1

I am trying to deploy an Ionic2 app on heroku, and am running into an issue where I’m getting 404 errors when the browser tries to load my various .js files in my build directory. Any suggestions on what to improve? Is there something else I need to add to ensure those files are built within Heroku?

Thanks!

To deploy my app, I did:
heroku create
git push heroku master
heroku open

browser 404 messages

MyApp.herokuapp.com/:26 GET https://MyApp.herokuapp.com/build/js/Reflect.js 
MyApp.herokuapp.com/:27 GET https://MyApp.herokuapp.com/build/js/zone.js 
MyApp.herokuapp.com/:22 GET https://MyApp.herokuapp.com/cordova.js 
MyApp.herokuapp.com/:29 GET https://MyApp.herokuapp.com/build/js/app.bundle.js 
MyApp.herokuapp.com/:22 GET https://MyApp.herokuapp.com/cordova.js 
MyApp.herokuapp.com/:24 GET https://MyApp.herokuapp.com/build/js/es6-shim.min.js 
MyApp.herokuapp.com/:26 GET https://MyApp.herokuapp.com/build/js/Reflect.js 
MyApp.herokuapp.com/:27 GET https://MyApp.herokuapp.com/build/js/zone.js 
MyApp.herokuapp.com/:29 GET https://MyApp.herokuapp.com/build/js/app.bundle.js 404 (Not Found)

package.json

{
  "dependencies": {
    "@angular/common": "2.0.0-rc.2",
    "@angular/compiler": "2.0.0-rc.2",
    "@angular/core": "2.0.0-rc.2",
    "@angular/http": "2.0.0-rc.2",
    "@angular/platform-browser": "2.0.0-rc.2",
    "@angular/platform-browser-dynamic": "2.0.0-rc.2",
    "@angular/router": "2.0.0-rc.2",
    "angular2-google-maps": "^0.12.0",
    "angular2-jwt": "0.1.16",
    "es6-shim": "^0.35.0",
    "express": "^4.14.0",
    "ionic-angular": "2.0.0-beta.9",
    "ionic-native": "1.2.4",
    "ionicons": "3.0.0",
    "reflect-metadata": "^0.1.3",
    "rxjs": "5.0.0-beta.6",
    "zone.js": "^0.6.12"
  },
  "devDependencies": {
    "del": "2.2.0",
    "gulp": "3.9.1",
    "gulp-watch": "4.3.5",
    "ionic-gulp-browserify-typescript": "^1.1.0",
    "ionic-gulp-fonts-copy": "^1.0.0",
    "ionic-gulp-html-copy": "^1.0.0",
    "ionic-gulp-sass-build": "^1.0.0",
    "ionic-gulp-scripts-copy": "^2.0.0",
    "run-sequence": "1.1.5"
  },
  "cordovaPlugins": [
    "cordova-plugin-whitelist",
    "cordova-plugin-console",
    "cordova-plugin-statusbar",
    "cordova-plugin-device",
    "cordova-plugin-splashscreen",
    "ionic-plugin-keyboard"
  ],
  "cordovaPlatforms": [
    "ios",
    {
      "platform": "ios",
      "version": "",
      "locator": "ios"
    }
  ],
  "engines": {
    "node": "5.0.0"
  },
  "scripts": {
    "start": "node server.js"
  },
  "name": "mob",
  "description": "mob: An Ionic project"
}

server.js

var express = require('express'),
app = express();
app.use(express.static('www'));
app.set('port', process.env.PORT || 5000);
app.listen(app.get('port'), function () {
    console.log('Express server listening on port ' + app.get('port'));
});

gulpfile.js

var gulp = require('gulp'),
    gulpWatch = require('gulp-watch'),
    del = require('del'),
    runSequence = require('run-sequence'),
    argv = process.argv;


/**
 * Ionic hooks
 * Add ':before' or ':after' to any Ionic project command name to run the specified
 * tasks before or after the command.
 */
gulp.task('serve:before', ['watch']);
gulp.task('emulate:before', ['build']);
gulp.task('deploy:before', ['build']);
gulp.task('build:before', ['build']);

// we want to 'watch' when livereloading
var shouldWatch = argv.indexOf('-l') > -1 || argv.indexOf('--livereload') > -1;
gulp.task('run:before', [shouldWatch ? 'watch' : 'build']);

/**
 * Ionic Gulp tasks, for more information on each see
 * https://github.com/driftyco/ionic-gulp-tasks
 *
 * Using these will allow you to stay up to date if the default Ionic 2 build
 * changes, but you are of course welcome (and encouraged) to customize your
 * build however you see fit.
 */
var buildBrowserify = require('ionic-gulp-browserify-typescript');
var buildSass = require('ionic-gulp-sass-build');
var copyHTML = require('ionic-gulp-html-copy');
var copyFonts = require('ionic-gulp-fonts-copy');
var copyScripts = require('ionic-gulp-scripts-copy');

var isRelease = argv.indexOf('--release') > -1;

gulp.task('watch', ['clean'], function(done){
  runSequence(
    ['sass', 'html', 'fonts', 'scripts'],
    function(){
      gulpWatch('app/**/*.scss', function(){ gulp.start('sass'); });
      gulpWatch('app/**/*.html', function(){ gulp.start('html'); });
      buildBrowserify({ watch: true }).on('end', done);
    }
  );
});

gulp.task('build', ['clean'], function(done){
  runSequence(
    ['sass', 'html', 'fonts', 'scripts'],
    function(){
      buildBrowserify({
        minify: isRelease,
        browserifyOptions: {
          debug: !isRelease
        },
        uglifyOptions: {
          mangle: false
        }
      }).on('end', done);
    }
  );
});

gulp.task('sass', buildSass);
gulp.task('html', copyHTML);
gulp.task('fonts', copyFonts);
gulp.task('scripts', copyScripts);
gulp.task('clean', function(){
  return del('www/build');
});

#2

In the .gitignore remove www/build/


#3

Thanks, I’ll try that next. I also saw a post about ensuring the gulp task is being run. I’m trying to figure out how to do that now, but something along the lines of this in package.json. Does that look like the right direction?

"scripts": {
    "postinstall": "gulp serve:before",
    "start": "node server.js"
  },

#4

Personally I don’t use "postinstall": "gulp serve:before" so I can’t tell you but I can tell you when you remove www/build in the gitignore is just a provisional solution, I don’t think this is a great solution
Try to to remove it and tell me


#5

Gotcha, thanks. Yeah I’m guessing that removing www/build from gitignore would work, but I’m going to try to get the gulp task to run first. It’s stalling on me though…

Counting objects: 3, done.
Delta compression using up to 8 threads.
Compressing objects: 100% (3/3), done.
Writing objects: 100% (3/3), 321 bytes | 0 bytes/s, done.
Total 3 (delta 2), reused 0 (delta 0)
remote: Compressing source files... done.
remote: Building source:
remote: 
remote: -----> Using set buildpack heroku/nodejs
remote: -----> Node.js app detected
remote: 
remote: -----> Creating runtime environment
remote:        
remote:        NPM_CONFIG_LOGLEVEL=error
remote:        NPM_CONFIG_PRODUCTION=true
remote:        NODE_ENV=production
remote:        NODE_MODULES_CACHE=true
remote: 
remote: -----> Installing binaries
remote:        engines.node (package.json):  5.0.0
remote:        engines.npm (package.json):   unspecified (use default)
remote:        
remote:        Downloading and installing node 5.0.0...
remote:        Using default npm version: 3.3.6
remote: 
remote: -----> Restoring cache
remote:        Loading 2 from cacheDirectories (default):
remote:        - node_modules
remote:        - bower_components (not cached - skipping)
remote: 
remote: -----> Building dependencies
remote:        Pruning any extraneous modules
remote:        Installing node modules (package.json)
remote:        
remote:        > node-sass@3.8.0 install /tmp/build_82765224f2a6c037133ff761a8118c93/node_modules/node-sass
remote:        > node scripts/install.js
remote:        
remote:        
remote:        > node-sass@3.8.0 postinstall /tmp/build_82765224f2a6c037133ff761a8118c93/node_modules/node-sass
remote:        > node scripts/build.js
remote:        
remote:        "/tmp/build_82765224f2a6c037133ff761a8118c93/node_modules/node-sass/vendor/linux-x64-47/binding.node" exists.
remote:        testing binary.
remote:        Binary is fine; exiting.
remote:        
remote:        > mob@ postinstall /tmp/build_82765224f2a6c037133ff761a8118c93
remote:        > gulp serve:before
remote:        
remote:        [19:48:08] Using gulpfile /tmp/build_82765224f2a6c037133ff761a8118c93/gulpfile.js
remote:        [19:48:08] Starting 'clean'...
remote:        [19:48:08] Finished 'clean' after 6.02 ms
remote:        [19:48:08] Starting 'watch'...
remote:        [19:48:08] Starting 'sass'...
remote:        [19:48:08] Starting 'html'...
remote:        [19:48:08] Starting 'fonts'...
remote:        [19:48:08] Starting 'scripts'...
remote:        [19:48:08] Finished 'scripts' after 71 ms
remote:        [19:48:08] Finished 'html' after 83 ms
remote:        [19:48:08] Finished 'fonts' after 83 ms
remote:        [19:48:09] Finished 'sass' after 1.15 s
remote:        9.3 MB bytes written (8.77 seconds)
remote:        [19:48:22] Finished 'watch' after 14 s
remote:        [19:48:22] Starting 'serve:before'...
remote:        [19:48:22] Finished 'serve:before' after 13 μs
remote:

#6

FYI - those files were built after I added this to my package.json file. The difference from before is that I used gulp build instead of gulp serve:before.

“scripts”: {
“postinstall”: “gulp build”,
“start”: “node server.js”
}