MeanJs应用程序无法在Heroku中正常工作,但在本地工作

时间:2016-12-11 17:01:16

标签: node.js heroku npm gulp meanjs

我的应用程序适用于本地的" heroku local"," npm start:prod"和" gulp prod",但不能在heroku中部署,我不知道为什么。
理论上一切都很好,工作正常 在heroku的日志中显示:

2016-12-07T18:44:16.948060+00:00 app[web.1]: > Coach@0.5.0 start:prod /app
2016-12-07T18:44:16.948061+00:00 app[web.1]: > gulp prod
2016-12-07T18:44:16.948062+00:00 app[web.1]: 
2016-12-07T18:44:16.969499+00:00 app[web.1]: sh: 1: gulp: not found
2016-12-07T18:44:16.989774+00:00 app[web.1]: 
2016-12-07T18:44:17.002307+00:00 app[web.1]: npm ERR! Linux 3.13.0-100-generic*emphasized text*
2016-12-07T18:44:17.002945+00:00 app[web.1]: npm ERR! argv "/app/.heroku/node/bin/node" "/app/.heroku/node/bin/npm" "run" "start:prod"
2016-12-07T18:44:17.003066+00:00 app[web.1]: npm ERR! node v6.9.2
2016-12-07T18:44:17.003500+00:00 app[web.1]: npm ERR! npm  v4.0.3
2016-12-07T18:44:17.003739+00:00 app[web.1]: npm ERR! file sh
2016-12-07T18:44:17.004160+00:00 app[web.1]: npm ERR! code ELIFECYCLE
2016-12-07T18:44:17.004382+00:00 app[web.1]: npm ERR! errno ENOENT
2016-12-07T18:44:17.005072+00:00 app[web.1]: npm ERR! syscall spawn
2016-12-07T18:44:17.005472+00:00 app[web.1]: npm ERR! Coach@0.5.0 start:prod: `gulp prod`
2016-12-07T18:44:17.005655+00:00 app[web.1]: npm ERR! spawn ENOENT
2016-12-07T18:44:17.006076+00:00 app[web.1]: npm ERR! 
2016-12-07T18:44:17.006269+00:00 app[web.1]: npm ERR! Failed at the Coach@0.5.0 start:prod script 'gulp prod'.
2016-12-07T18:44:17.006429+00:00 app[web.1]: npm ERR! Make sure you have the latest version of node.js and npm installed.
2016-12-07T18:44:17.006603+00:00 app[web.1]: npm ERR! If you do, this is most likely a problem with the Coach package,
2016-12-07T18:44:17.006941+00:00 app[web.1]: npm ERR! not with npm itself.
2016-12-07T18:44:17.007120+00:00 app[web.1]: npm ERR! Tell the author that this fails on your system:
2016-12-07T18:44:17.007791+00:00 app[web.1]: npm ERR!     gulp prod
2016-12-07T18:44:17.007953+00:00 app[web.1]: npm ERR! You can get information on how to open an issue for this project with:
2016-12-07T18:44:17.008116+00:00 app[web.1]: npm ERR!     npm bugs Coach
2016-12-07T18:44:17.008288+00:00 app[web.1]: npm ERR! Or if that isn't available, you can get their info via:
2016-12-07T18:44:17.008626+00:00 app[web.1]: npm ERR!     npm owner ls Coach
2016-12-07T18:44:17.008792+00:00 app[web.1]: npm ERR! There is likely additional logging output above.
2016-12-07T18:44:17.019467+00:00 app[web.1]: 
2016-12-07T18:44:17.019744+00:00 app[web.1]: npm ERR! Please include the following file with any support request:
2016-12-07T18:44:17.019893+00:00 app[web.1]: npm ERR!     /app/npm-debug.log
2016-12-07T18:44:17.196342+00:00 heroku[web.1]: State changed from starting to crashed
2016-12-07T18:44:17.155015+00:00 heroku[web.1]: Process exited with status 1

我的gulp.js文件是:

'use strict';

/**
 * Module dependencies.
 */
var _ = require('lodash'),
  fs = require('fs'),
  defaultAssets = require('./config/assets/default'),
  testAssets = require('./config/assets/test'),
  testConfig = require('./config/env/test'),
  glob = require('glob'),
  gulp = require('gulp'),
  babel = require('gulp-babel'),
  gulpLoadPlugins = require('gulp-load-plugins'),
  runSequence = require('run-sequence'),
  plugins = gulpLoadPlugins({
    rename: {
      'gulp-angular-templatecache': 'templateCache'
    }
  }),
  pngquant = require('imagemin-pngquant'),
  wiredep = require('wiredep').stream,
  path = require('path'),
  endOfLine = require('os').EOL,
  protractor = require('gulp-protractor').protractor,
  webdriver_update = require('gulp-protractor').webdriver_update,
  webdriver_standalone = require('gulp-protractor').webdriver_standalone,
  del = require('del'),
  KarmaServer = require('karma').Server;

// Local settings
var changedTestFiles = [];

// Set NODE_ENV to 'test'
gulp.task('env:test', function () {
  process.env.NODE_ENV = 'test';
});

// Set NODE_ENV to 'development'
gulp.task('env:dev', function () {
  process.env.NODE_ENV = 'development';
});

// Set NODE_ENV to 'production'
gulp.task('env:prod', function () {
  process.env.NODE_ENV = 'production';
});

// Nodemon task
gulp.task('nodemon', function () {
  return plugins.nodemon({
    script: 'server.js',
    nodeArgs: ['--debug'],
    ext: 'js,html',
    verbose: true,
    watch: _.union(defaultAssets.server.views, defaultAssets.server.allJS, defaultAssets.server.config)
  });
});

// Nodemon task without verbosity or debugging
gulp.task('nodemon-nodebug', function () {
  return plugins.nodemon({
    script: 'server.js',
    ext: 'js,html',
    watch: _.union(defaultAssets.server.views, defaultAssets.server.allJS, defaultAssets.server.config)
  });
});

// Watch Files For Changes
gulp.task('watch', function () {
  // Start livereload
  plugins.refresh.listen();

  // Add watch rules
  gulp.watch(defaultAssets.server.views).on('change', plugins.refresh.changed);
  gulp.watch(defaultAssets.server.allJS, ['eslint']).on('change', plugins.refresh.changed);
  gulp.watch(defaultAssets.client.js, ['eslint']).on('change', plugins.refresh.changed);
  gulp.watch(defaultAssets.client.css, ['csslint']).on('change', plugins.refresh.changed);
  gulp.watch(defaultAssets.client.sass, ['sass', 'csslint']).on('change', plugins.refresh.changed);
  gulp.watch(defaultAssets.client.less, ['less', 'csslint']).on('change', plugins.refresh.changed);

  if (process.env.NODE_ENV === 'production') {
    gulp.watch(defaultAssets.server.gulpConfig, ['templatecache', 'eslint']);
    gulp.watch(defaultAssets.client.views, ['templatecache']).on('change', plugins.refresh.changed);
  } else {
    gulp.watch(defaultAssets.server.gulpConfig, ['eslint']);
    gulp.watch(defaultAssets.client.views).on('change', plugins.refresh.changed);
  }
});

// Watch server test files
gulp.task('watch:server:run-tests', function () {
  // Start livereload
  plugins.refresh.listen();

  // Add Server Test file rules
  gulp.watch([testAssets.tests.server, defaultAssets.server.allJS], ['test:server']).on('change', function (file) {
    changedTestFiles = [];

    // iterate through server test glob patterns
    _.forEach(testAssets.tests.server, function (pattern) {
      // determine if the changed (watched) file is a server test
      _.forEach(glob.sync(pattern), function (f) {
        var filePath = path.resolve(f);

        if (filePath === path.resolve(file.path)) {
          changedTestFiles.push(f);
        }
      });
    });

    plugins.refresh.changed();
  });
});

// CSS linting task
gulp.task('csslint', function () {
  return gulp.src(defaultAssets.client.css)
    .pipe(plugins.csslint('.csslintrc'))
    .pipe(plugins.csslint.formatter());
    // Don't fail CSS issues yet
    // .pipe(plugins.csslint.failFormatter());
});

// ESLint JS linting task
gulp.task('eslint', function () {
  var assets = _.union(
    defaultAssets.server.gulpConfig,
    defaultAssets.server.allJS,
    defaultAssets.client.js,
    testAssets.tests.server,
    testAssets.tests.client,
    testAssets.tests.e2e
  );

  return gulp.src(assets)
    .pipe(plugins.eslint())
    .pipe(plugins.eslint.format());
});

// JS minifying task
gulp.task('uglify', function () {
  var assets = _.union(
    defaultAssets.client.js,
    defaultAssets.client.templates
  );
  del(['public/dist/*']);

  return gulp.src(assets)
    .pipe(plugins.ngAnnotate())
    .pipe(babel())
    .pipe(plugins.uglify({
      mangle: false
    }))
    .pipe(plugins.concat('application.min.js'))
    .pipe(plugins.rev())
    .pipe(gulp.dest('public/dist'));
});

// CSS minifying task
gulp.task('cssmin', function () {
  return gulp.src(defaultAssets.client.css)
    .pipe(plugins.csso())
    .pipe(plugins.concat('application.min.css'))
    .pipe(plugins.rev())
    .pipe(gulp.dest('public/dist'));
});

// Sass task
gulp.task('sass', function () {
  return gulp.src(defaultAssets.client.sass)
    .pipe(plugins.sass())
    .pipe(plugins.autoprefixer())
    .pipe(gulp.dest('./modules/'));
});

// Less task
gulp.task('less', function () {
  return gulp.src(defaultAssets.client.less)
    .pipe(plugins.less())
    .pipe(plugins.autoprefixer())
    .pipe(gulp.dest('./modules/'));
});

// Imagemin task
gulp.task('imagemin', function () {
  return gulp.src(defaultAssets.client.img)
    .pipe(plugins.imagemin({
      progressive: true,
      svgoPlugins: [{ removeViewBox: false }],
      use: [pngquant()]
    }))
    .pipe(gulp.dest('public/dist/img'));
});

// wiredep task to default
gulp.task('wiredep', function () {
  return gulp.src('config/assets/default.js')
    .pipe(wiredep({
      ignorePath: '../../'
    }))
    .pipe(gulp.dest('config/assets/'));
});

// wiredep task to production
gulp.task('wiredep:prod', function () {
  return gulp.src('config/assets/production.js')
    .pipe(wiredep({
      ignorePath: '../../',
      fileTypes: {
        js: {
          replace: {
            css: function (filePath) {
              var minFilePath = filePath.replace('.css', '.min.css');
              var fullPath = path.join(process.cwd(), minFilePath);
              if (!fs.existsSync(fullPath)) {
                return '\'' + filePath + '\',';
              } else {
                return '\'' + minFilePath + '\',';
              }
            },
            js: function (filePath) {
              var minFilePath = filePath.replace('.js', '.min.js');
              var fullPath = path.join(process.cwd(), minFilePath);
              if (!fs.existsSync(fullPath)) {
                return '\'' + filePath + '\',';
              } else {
                return '\'' + minFilePath + '\',';
              }
            }
          }
        }
      }
    }))
    .pipe(gulp.dest('config/assets/'));
});

// Copy local development environment config example
gulp.task('copyLocalEnvConfig', function () {
  var src = [];
  var renameTo = 'local-development.js';

  // only add the copy source if our destination file doesn't already exist
  if (!fs.existsSync('config/env/' + renameTo)) {
    src.push('config/env/local.example.js');
  }

  return gulp.src(src)
    .pipe(plugins.rename(renameTo))
    .pipe(gulp.dest('config/env'));
});

// Make sure upload directory exists
gulp.task('makeUploadsDir', function () {
  return fs.mkdir('modules/users/client/img/profile/uploads', function (err) {
    if (err && err.code !== 'EEXIST') {
      console.error(err);
    }
  });
});

// Angular template cache task
gulp.task('templatecache', function () {
  return gulp.src(defaultAssets.client.views)
    .pipe(plugins.templateCache('templates.js', {
      root: 'modules/',
      module: 'core',
      templateHeader: '(function () {' + endOfLine + ' \'use strict\';' + endOfLine + endOfLine + 'angular' + endOfLine + ' .module(\'<%= module %>\'<%= standalone %>)' + endOfLine + ' .run(templates);' + endOfLine + endOfLine + ' templates.$inject = [\'$templateCache\'];' + endOfLine + endOfLine + ' function templates($templateCache) {' + endOfLine,
      templateBody: '$templateCache.put(\'<%= url %>\', \'<%= contents %>\');',
      templateFooter: ' }' + endOfLine + '})();' + endOfLine
    }))
    .pipe(gulp.dest('build'));
});

// Mocha tests task
gulp.task('mocha', function (done) {
  // Open mongoose connections
  var mongoose = require('./config/lib/mongoose.js');
  var testSuites = changedTestFiles.length ? changedTestFiles : testAssets.tests.server;
  var error;

  // Connect mongoose
  mongoose.connect(function () {
    mongoose.loadModels();
    // Run the tests
    gulp.src(testSuites)
      .pipe(plugins.mocha({
        reporter: 'spec',
        timeout: 10000
      }))
      .on('error', function (err) {
        // If an error occurs, save it
        error = err;
      })
      .on('end', function () {
        // When the tests are done, disconnect mongoose and pass the error state back to gulp
        mongoose.disconnect(function () {
          done(error);
        });
      });
  });
});

// Prepare istanbul coverage test
gulp.task('pre-test', function () {

  // Display coverage for all server JavaScript files
  return gulp.src(defaultAssets.server.allJS)
    // Covering files
    .pipe(plugins.istanbul())
    // Force `require` to return covered files
    .pipe(plugins.istanbul.hookRequire());
});

// Run istanbul test and write report
gulp.task('mocha:coverage', ['pre-test', 'mocha'], function () {
  var testSuites = changedTestFiles.length ? changedTestFiles : testAssets.tests.server;

  return gulp.src(testSuites)
    .pipe(plugins.istanbul.writeReports({
      reportOpts: { dir: './coverage/server' }
    }));
});

// Karma test runner task
gulp.task('karma', function (done) {
  new KarmaServer({
    configFile: path.join(__dirname, '/karma.conf.js')
  }, done).start();
});

// Run karma with coverage options set and write report
gulp.task('karma:coverage', function(done) {
  new KarmaServer({
    configFile: path.join(__dirname, '/karma.conf.js'),
    preprocessors: {
      'modules/*/client/views/**/*.html': ['ng-html2js'],
      'modules/core/client/app/config.js': ['coverage'],
      'modules/core/client/app/init.js': ['coverage'],
      'modules/*/client/*.js': ['coverage'],
      'modules/*/client/config/*.js': ['coverage'],
      'modules/*/client/controllers/*.js': ['coverage'],
      'modules/*/client/directives/*.js': ['coverage'],
      'modules/*/client/services/*.js': ['coverage']
    },
    reporters: ['progress', 'coverage'],
    coverageReporter: {
      dir: 'coverage/client',
      reporters: [
        { type: 'lcov', subdir: '.' }
        // printing summary to console currently weirdly causes gulp to hang so disabled for now
        // https://github.com/karma-runner/karma-coverage/issues/209
        // { type: 'text-summary' }
      ]
    }
  }, done).start();
});

// Drops the MongoDB database, used in e2e testing
gulp.task('dropdb', function (done) {
  // Use mongoose configuration
  var mongoose = require('./config/lib/mongoose.js');

  mongoose.connect(function (db) {
    db.connection.db.dropDatabase(function (err) {
      if (err) {
        console.error(err);
      } else {
        console.log('Successfully dropped db: ', db.connection.db.databaseName);
      }
      db.connection.db.close(done);
    });
  });
});

// Downloads the selenium webdriver
gulp.task('webdriver_update', webdriver_update);

// Start the standalone selenium server
// NOTE: This is not needed if you reference the
// seleniumServerJar in your protractor.conf.js
gulp.task('webdriver_standalone', webdriver_standalone);

// Protractor test runner task
gulp.task('protractor', ['webdriver_update'], function () {
  gulp.src([])
    .pipe(protractor({
      configFile: 'protractor.conf.js'
    }))
    .on('end', function() {
      console.log('E2E Testing complete');
      // exit with success.
      process.exit(0);
    })
    .on('error', function(err) {
      console.error('E2E Tests failed:');
      console.error(err);
      process.exit(1);
    });
});

// Lint CSS and JavaScript files.
gulp.task('lint', function (done) {
  runSequence('less', 'sass', ['csslint', 'eslint'], done);
});

// Lint project files and minify them into two production files.
gulp.task('build', function (done) {
  runSequence('env:dev', 'wiredep:prod', 'lint', ['uglify', 'cssmin'], done);
});

// Run the project tests
gulp.task('test', function (done) {
  runSequence('env:test', 'test:server', 'karma', 'nodemon', 'protractor', done);
});

gulp.task('test:server', function (done) {
  runSequence('env:test', ['copyLocalEnvConfig', 'makeUploadsDir', 'dropdb'], 'lint', 'mocha', done);
});

// Watch all server files for changes & run server tests (test:server) task on changes
gulp.task('test:server:watch', function (done) {
  runSequence('test:server', 'watch:server:run-tests', done);
});

gulp.task('test:client', function (done) {
  runSequence('env:test', 'lint', 'dropdb', 'karma', done);
});

gulp.task('test:e2e', function (done) {
  runSequence('env:test', 'lint', 'dropdb', 'nodemon', 'protractor', done);
});

gulp.task('test:coverage', function (done) {
  runSequence('env:test', ['copyLocalEnvConfig', 'makeUploadsDir', 'dropdb'], 'lint', 'mocha:coverage', 'karma:coverage', done);
});

// Run the project in development mode
gulp.task('default', function (done) {
  runSequence('env:dev', ['copyLocalEnvConfig', 'makeUploadsDir'], 'lint', ['nodemon', 'watch'], done);
});

// Run the project in debug mode
gulp.task('debug', function (done) {
  runSequence('env:dev', ['copyLocalEnvConfig', 'makeUploadsDir'], 'lint', ['nodemon-nodebug', 'watch'], done);
});

// Run the project in production mode
gulp.task('prod', function (done) {
  runSequence(['copyLocalEnvConfig', 'makeUploadsDir', 'templatecache'], 'build', 'env:prod', 'lint', ['nodemon-nodebug', 'watch'], done);
});

我的package.json是:

{
  "name": "Coach",
  "description": "Una ayuda simple para mejorar la gestion y los procedimientos del día a día en un callcenter.",
  "version": "0.5.0",
  "meanjs-version": "0.5.0",
  "private": false,
  "author": "Diego A. Zapata Häntsch",
  "license": "MIT",
  "repository": {
    "type": "git",
    "url": "https://github.com/meanjs/mean.git"
  },
  "engines": {
    "node": "6.9.2",
    "npm": "4.0.3"
  },
  "scripts": {
    "update": "npm update && npm prune && bower install --allow-root && bower prune --allow-root",
    "clean": "rm -rf node_modules/ public/lib/",
    "reinstall": "npm cache clean && npm run clean && npm install",
    "start": "gulp",
    "start:prod": "gulp prod",
    "start:debug": "node-debug --web-host 0.0.0.0 server.js & gulp debug",
    "gulp": "gulp",
    "lint": "gulp lint",
    "test": "gulp test",
    "test:server": "gulp test:server",
    "test:server:watch": "gulp test:server:watch",
    "test:client": "gulp test:client",
    "test:e2e": "gulp test:e2e",
    "test:coverage": "gulp test:coverage",
    "postinstall": "bower install --allow-root && bower prune --allow-root",
    "generate-ssl-certs": "scripts/generate-ssl-certs.sh"
  },
  "dependencies": {
    "acl": "~0.4.9",
    "async": "~2.1.4",
    "body-parser": "~1.15.2",
    "bower": "~1.8.0",
    "chalk": "~1.1.3",
    "compression": "~1.6.2",
    "connect-flash": "~0.1.1",
    "connect-mongo": "~1.3.2",
    "cookie-parser": "~1.4.3",
    "crypto": "0.0.3",
    "express": "~4.14.0",
    "express-hbs": "^1.0.3",
    "express-session": "~1.14.2",
    "file-stream-rotator": "~0.0.7",
    "generate-password": "~1.2.0",
    "glob": "~7.1.1",
    "grunt": "1.0.1",
    "grunt-cli": "~1.2.0",
    "gulp-eslint": "^3.0.1",
    "gulp-uglify": "^2.0.0",
    "gulp-wiredep": "~0.0.0",
    "helmet": "~3.1.0",
    "jasmine-core": "~2.5.2",
    "lodash": "~4.17.2",
    "lusca": "~1.4.1",
    "method-override": "~2.3.7",
    "mocha": "~3.2.0",
    "moment": "^2.17.1",
    "mongoose": "~4.7.1",
    "morgan": "~1.7.0",
    "multer": "~1.2.0",
    "nodemailer": "~2.6.4",
    "owasp-password-strength-test": "~1.3.0",
    "passport": "~0.3.2",
    "passport-facebook": "~2.1.1",
    "passport-github": "~1.1.0",
    "passport-google-oauth": "~1.0.0",
    "passport-linkedin": "~1.0.0",
    "passport-local": "~1.0.0",
    "passport-paypal-openidconnect": "~0.1.1",
    "passport-twitter": "~1.0.4",
    "phantomjs-prebuilt": "~2.1.13",
    "serve-favicon": "~2.3.2",
    "showdown": "^1.5.1",
    "socket.io": "^1.7.1",
    "swig": "~1.4.2",
    "upndown": "^2.0.2",
    "validator": "~6.2.0",
    "winston": "^2.3.0",
    "wiredep": "~4.0.0"
  },
  "devDependencies": {
    "babel-preset-latest": "^6.16.0",
    "coveralls": "~2.11.15",
    "del": "^2.2.2",
    "eslint": "~3.11.1",
    "eslint-config-airbnb": "~13.0.0",
    "gulp": "~3.9.1",
    "gulp-angular-templatecache": "~2.0.0",
    "gulp-autoprefixer": "~3.1.1",
    "gulp-babel": "^6.1.2",
    "gulp-concat": "~2.6.1",
    "gulp-csslint": "~1.0.0",
    "gulp-csso": "~2.0.0",
    "gulp-eslint": "~3.0.1",
    "gulp-imagemin": "~3.1.1",
    "gulp-istanbul": "~1.1.1",
    "gulp-less": "~3.3.0",
    "gulp-load-plugins": "~1.4.0",
    "gulp-mocha": "~3.0.1",
    "gulp-ng-annotate": "~2.0.0",
    "gulp-nodemon": "~2.2.1",
    "gulp-protractor": "~3.0.0",
    "gulp-refresh": "~1.1.0",
    "gulp-rename": "~1.2.2",
    "gulp-rev": "^7.1.2",
    "gulp-sass": "~2.3.2",
    "gulp-uglify": "~2.0.0",
    "gulp-util": "~3.0.7",
    "imagemin-pngquant": "~5.0.0",
    "istanbul": "~0.4.5",
    "karma": "~1.3.0",
    "karma-chrome-launcher": "~2.0.0",
    "karma-coverage": "~1.1.1",
    "karma-firefox-launcher": "~1.0.0",
    "karma-jasmine": "~1.0.2",
    "karma-ng-html2js-preprocessor": "~1.0.0",
    "karma-phantomjs-launcher": "~1.0.2",
    "lcov-result-merger": "~1.2.0",
    "mock-fs": "~3.12.1",
    "node-inspector": "~0.12.8",
    "run-sequence": "~1.2.2",
    "semver": "~5.3.0",
    "should": "~11.1.1",
    "supertest": "~2.0.1"
  }
}

1 个答案:

答案 0 :(得分:0)

Heroku没有安装你的dev依赖项,所以你没有吞咽。

至少你必须做以下事情:

"heroku-postbuild": "npm install gulp && gulp"

请参阅https://devcenter.heroku.com/articles/nodejs-support#customizing-the-build-process