如何将mean.js部署到生产中?

时间:2016-06-06 03:44:10

标签: node.js gruntjs yeoman meanjs gruntfile

我已经建立了一个自动生成器 - mean.js app

我已经设置了一个aws ec2 linux实例,我已经安装了nginx作为服务器,我已经将节点设置为代理服务器 我已经设置了端口 我使用grunt来构建我的dist文件夹,其中包括application.js,application.css,templates.js,vendor.js和vendor.css

我无法在本地或远程运行这些文件,它只能在我使用开发环境并加载80个单独的js文件的站点,而不是我的新的uglified,连接的生产文件,所以我想知道什么我在dist文件夹中丢失了? (或一般而言)

我遵循了本教程:https://blog.dylants.com/2014/11/19/bundling-production-assets-for-mean-js/ 最初,在运行grunt构建时,我只获得了application.js和application.css文件

我尝试运行grunt prod并获得

Warning: Task "jshint:all" failed. Used --force, continuing.

Running "eslint:target" (eslint) task

Running "csslint:all" (csslint) task
Warning: Unable to read ".csslintrc" file (Error code: ENOENT). Used --force, continuing.

Running "ngAnnotate:production" (ngAnnotate) task
>> 1 file successfully generated.

Running "loadConfig" task
Warning: angular is not defined Used --force, continuing.

Running "ngtemplates:mean" (ngtemplates) task
File public/dist/templates.js created.

Running "uglify:production" (uglify) task
>> 2 files created.

Running "cssmin:combine" (cssmin) task
>> 2 files created. 928.08 kB → 730.04 kB

Running "concat:production" (concat) task

Running "env:prod" (env) task

Running "mkdir:upload" task

Running "copy:localConfig" (copy) task


Running "concurrent:default" (concurrent) task
    Running "nodemon:dev" (nodemon) task
    Running "watch" task
    Waiting...
    [nodemon] 1.9.2
    [nodemon] to restart at any time, enter `rs`
    [nodemon] watching: server.js config/**/*.js modules/*/server/**/*.js
    [nodemon] starting `node --debug server.js`
    Debugger listening on port 5858

目前我刚将我的整个仓库克隆到我的实例,我知道这是不正确的,我的cpu是8%,加载时间大约是60秒。我不知道该怎么做。

production.js

'use strict';

module.exports = {
  assets: {
    lib: {
        css: "public/dist/vendor.min.css",
        js: "public/dist/vendor.min.js"
    },
    css: "public/dist/application.min.css",
    js: [
        "public/dist/application.min.js",
        "public/dist/templates.min.js"
    ]
}
};

grunt档案

'use strict';

/**
 * Module dependencies.
 */
var _ = require('lodash'),
  defaultAssets = require('./config/assets/default'),
  testAssets = require('./config/assets/test'),
  testConfig = require('./config/env/test'),
  fs = require('fs'),
  path = require('path');

module.exports = function (grunt) {
  // Project Configuration
  grunt.initConfig({
    pkg: grunt.file.readJSON('package.json'),
    env: {
      test: {
        NODE_ENV: 'test'
      },
      dev: {
        NODE_ENV: 'development'
      },
      prod: {
        NODE_ENV: 'production'
      },
      build: {
        NODE_ENV: 'build'  
      },
    },
    watch: {
      serverViews: {
        files: defaultAssets.server.views,
        options: {
          livereload: true
        }
      },
      serverJS: {
        files: _.union(defaultAssets.server.gruntConfig, defaultAssets.server.allJS),
        tasks: ['jshint'],
        options: {
          livereload: true
        }
      },
      clientViews: {
        files: defaultAssets.client.views,
        options: {
          livereload: true
        }
      },
      clientJS: {
        files: defaultAssets.client.js,
        tasks: ['jshint'],
        options: {
          livereload: true
        }
      },
      clientCSS: {
        files: defaultAssets.client.css,
        tasks: ['csslint'],
        options: {
          livereload: true
        }
      },
      clientSCSS: {
        files: defaultAssets.client.sass,
        tasks: ['sass', 'csslint'],
        options: {
          livereload: true
        }
      },
      clientLESS: {
        files: defaultAssets.client.less,
        tasks: ['less', 'csslint'],
        options: {
          livereload: true
        }
      }
    },
    nodemon: {
      dev: {
        script: 'server.js',
        options: {
          nodeArgs: ['--debug'],
          ext: 'js,html',
          watch: _.union(defaultAssets.server.gruntConfig, defaultAssets.server.views, defaultAssets.server.allJS, defaultAssets.server.config)
        }
      }
    },
    concurrent: {
      default: ['nodemon', 'watch'],
      debug: ['nodemon', 'watch', 'node-inspector'],
      options: {
        logConcurrentOutput: true
      }
    },
    jshint: {
      all: {
        src: _.union(defaultAssets.server.gruntConfig, defaultAssets.server.allJS, defaultAssets.client.js, testAssets.tests.server, testAssets.tests.client, testAssets.tests.e2e),
        options: {
          jshintrc: true,
          node: true,
          mocha: true,
          jasmine: true
        }
      }
    },
    eslint: {
      options: {},
      target: _.union(defaultAssets.server.gruntConfig, defaultAssets.server.allJS, defaultAssets.client.js, testAssets.tests.server, testAssets.tests.client, testAssets.tests.e2e)
    },
    csslint: {
      options: {
        csslintrc: '.csslintrc'
      },
      all: {
        src: defaultAssets.client.css
      }
    },
    ngtemplates: {
    options: {
        htmlmin: {
            collapseWhitespace: true,
            removeComments: true
        },
        url: function(url) {
            return url.replace('public', 'assets');
        },
        prefix: "/"
    },
    'mean': {
        src: 'modules/*/client/views/**/*.html',
        dest: 'public/dist/templates.js'
        }
    },  
    ngAnnotate: {
      production: {
        files: {
          'public/dist/application.js': defaultAssets.client.js
        }
      }
    },
    uglify: {
      production: {
        options: {
          mangle: false
        },
        files: {
          'public/dist/application.min.js': 'public/dist/application.js',
          'public/dist/templates.min.js': 'public/dist/templates.js'
        }
      }
    },
    cssmin: {
      combine: {
        files: {
          'public/dist/application.min.css': defaultAssets.client.css,
          'public/dist/vendor.min.css':  defaultAssets.client.lib.css //'config/assets/build.js/assets/lib/css/*.css' //'pubic/lib/**/*.css' //'<%= vendorCSSFiles %>'
        }
      }
    },
    concat: {
    production: {
        options: {
            stripBanners: true
        },
        files: {
            "public/dist/vendor.min.js":  defaultAssets.client.lib.js //'public/lib/**/*.js' //"<%= vendorJavaScriptFiles %>"
            }
        }
    },
    sass: {
      dist: {
        files: [{
          expand: true,
          src: defaultAssets.client.sass,
          ext: '.css',
          rename: function (base, src) {
            return src.replace('/scss/', '/css/');
          }
        }]
      }
    },
    less: {
      dist: {
        files: [{
          expand: true,
          src: defaultAssets.client.less,
          ext: '.css',
          rename: function (base, src) {
            return src.replace('/less/', '/css/');
          }
        }]
      }
    },
    'node-inspector': {
      custom: {
        options: {
          'web-port': 1337,
          'web-host': 'localhost',
          'debug-port': 5858,
          'save-live-edit': true,
          'no-preload': true,
          'stack-trace-limit': 50,
          'hidden': []
        }
      }
    },
    mochaTest: {
      src: testAssets.tests.server,
      options: {
        reporter: 'spec',
        timeout: 10000
      }
    },
    mocha_istanbul: {
      coverage: {
        src: testAssets.tests.server,
        options: {
          print: 'detail',
          coverage: true,
          require: 'test.js',
          coverageFolder: 'coverage/server',
          reportFormats: ['cobertura','lcovonly'],
          check: {
            lines: 40,
            statements: 40
          }
        }
      }
    },
    karma: {
      unit: {
        configFile: 'karma.conf.js'
      }
    },
    protractor: {
      options: {
        configFile: 'protractor.conf.js',
        noColor: false,
        webdriverManagerUpdate: true
      },
      e2e: {
        options: {
          args: {} // Target-specific arguments
        }
      }
    },
    copy: {
      localConfig: {
        src: 'config/env/local.example.js',
        dest: 'config/env/local.js',
        filter: function () {
          return !fs.existsSync('config/env/local.js');
        }
      }
    }
  });

  grunt.event.on('coverage', function(lcovFileContents, done) {
    // Set coverage config so karma-coverage knows to run coverage
    testConfig.coverage = true;
    require('coveralls').handleInput(lcovFileContents, function(err) {
      if (err) {
        return done(err);
      }
      done();
    });
  });

  // Load NPM tasks
  require('load-grunt-tasks')(grunt);
  grunt.loadNpmTasks('grunt-protractor-coverage');
  grunt.loadNpmTasks('grunt-contrib-cssmin');
  grunt.loadNpmTasks('grunt-contrib-uglify');
  grunt.loadNpmTasks('grunt-contrib-concat');
  grunt.loadNpmTasks('grunt-angular-templates');    
  //new code
  grunt.task.registerTask('loadConfig', 'Task that loads the config into a grunt option.', function() {
    var init = require('./modules/core/client/app/init.js')();
    var config = require('./config/config');

    grunt.config.set('vendorJavaScriptFiles', config.assets.lib.js);
    grunt.config.set('vendorCSSFiles', config.assets.lib.css);
    grunt.config.set('applicationJavaScriptFiles', config.assets.js);
    grunt.config.set('applicationCSSFiles', config.assets.css);
});
  //new code    
  // Make sure upload directory exists
  grunt.task.registerTask('mkdir:upload', 'Task that makes sure upload directory exists.', function () {
    // Get the callback
    var done = this.async();

    grunt.file.mkdir(path.normalize(__dirname + '/modules/users/client/img/profile/uploads'));

    done();
  });

  // Connect to the MongoDB instance and load the models
  grunt.task.registerTask('mongoose', 'Task that connects to the MongoDB instance and loads the application models.', function () {
    // Get the callback
    var done = this.async();

    // Use mongoose configuration
    var mongoose = require('./config/lib/mongoose.js');

    // Connect to database
    mongoose.connect(function (db) {
      done();
    });
  });

  // Drops the MongoDB database, used in e2e testing
  grunt.task.registerTask('dropdb', 'drop the database', function () {
    // async mode
    var done = this.async();

    // Use mongoose configuration
    var mongoose = require('./config/lib/mongoose.js');

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

  grunt.task.registerTask('server', 'Starting the server', function () {
    // Get the callback
    var done = this.async();

    var path = require('path');
    var app = require(path.resolve('./config/lib/app'));
    var server = app.start(function () {
      done();
    });
  });

  // Lint CSS and JavaScript files.
  grunt.registerTask('lint', ['sass', 'less', 'jshint', 'eslint', 'csslint']);

  // Lint project files and minify them into two production files.
  //grunt.registerTask('build', ['env:dev', 'lint', 'ngAnnotate', 'uglify', 'cssmin']);
  grunt.registerTask('build', ['env:build', 'lint', 'ngAnnotate', 'loadConfig', 'ngtemplates', 'uglify', 'cssmin', 'concat']);

  // Run the project tests
  grunt.registerTask('test', ['env:test', 'lint', 'mkdir:upload', 'copy:localConfig', 'server', 'mochaTest', 'karma:unit', 'protractor']);
  grunt.registerTask('test:server', ['env:test', 'lint', 'server', 'mochaTest']);
  grunt.registerTask('test:client', ['env:test', 'lint', 'karma:unit']);
  grunt.registerTask('test:e2e', ['env:test', 'lint', 'dropdb', 'server', 'protractor']);
  // Run project coverage
  grunt.registerTask('coverage', ['env:test', 'lint', 'mocha_istanbul:coverage', 'karma:unit']);

  // Run the project in development mode
  grunt.registerTask('default', ['env:dev', 'lint', 'mkdir:upload', 'copy:localConfig', 'concurrent:default']);

  // Run the project in debug mode
  grunt.registerTask('debug', ['env:dev', 'lint', 'mkdir:upload', 'copy:localConfig', 'concurrent:debug']);

  // Run the project in production mode
  grunt.registerTask('prod', ['build', 'env:prod', 'mkdir:upload', 'copy:localConfig', 'concurrent:default']);
};

我很感激任何的帮助,谢谢! :)

1 个答案:

答案 0 :(得分:2)

我看到的主要内容(与我自己的设置相比)是ngAnnotate在任务loadConfigbuild之前调用。 loadConfig实例化一些稍后使用的变量。我会改变这个顺序。

至于其他想法,我首先会将运行grunt prod与设置为development的环境变量进行比较,看看您是否遇到与production环境相同的错误(例如,“无法读取”.csslintrc“文件”,“角度未定义”。然后,我会简化您的繁琐任务,例如,不使用concat,不使用lint等尝试。