部署在 Heroku 上的 Grunt 应用程序……下一步是什么?……我的应用程序无法启动

Grunt app deployed on Heroku ... and what's next ?... my app doesn't start

我有一个带有 gruntfile 的基本节点应用程序,我在部署时遇到了一些困难。所以我做了一个新的 grunt 任务,做了一些改变。 然后部署就可以了。

但现在当我打开我的应用程序时。我有一个空白页。 它不加载 appConfig.app 目录。

我可能错过了一些我想不通的大事。我以为 grunt connect 可以连接,但似乎 server.js 正在等待什么。

注意:我想我这里不需要快递。

以下是不同的文件:

Gruntfile.js

'use strict';

module.exports = function (grunt) {

require('load-grunt-tasks')(grunt);
require('time-grunt')(grunt);
var modRewrite = require('connect-modrewrite');

// Configurable paths for the application
var appConfig = {
    app: require('./bower.json').appPath || 'app',
    dist: 'dist'
};

//Environment vars
var envConfig = {
    dev: {
        //baseUrl: 'http://localhost:3000',
        loginUrl: 'http://demo.lvh.me:9000',
        uploadUrl: 'anuploadurl/upload'
    },
    prod: {
        baseUrl: 'http://aprodurl',
        loginUrl: 'an herokuapp url'
    }
};


// Define the configuration for all the tasks
grunt.initConfig({

    appConf: appConfig,

    // Empties folders to start fresh
    clean: {
        dist: {
            files: [{
                dot: true,
                src: [
                    '.tmp',
                    '<%= appConf.dist %>/{,*/}*',
                    '!<%= appConf.dist %>/.git*'
                ]
            }],
            options: {
                force: true //since dist directory is outside, we must use force flag.
            }
        },
        server: '.tmp'
    },

    //server settings
    ngconstant: {
        // Options for all targets
        options: {
            space: '  ',
            wrap: '\'use strict\';\n\n {%= __ngModule %}',
            name: 'config'
        },
        // Environment targets
        development: {
            options: {
                dest: 'app/config.js'
            },
            constants: envConfig.dev
        },
        production: {
            options: {
                dest: '<%= appConf.app %>/config.js'
            },
            constants: envConfig.prod
        }
    },

    // Automatically inject Bower components into the app
    wiredep: {
        app: {
            src: ['<%= appConf.app %>/index.html'],
            ignorePath: /\.\.\//,
            'options': {
                'overrides': {
                    'semantic-ui': {
                        'main': ['dist/semantic.css', 'dist/semantic.js']
                    }
                }
            }
        }
    },

    // Copies remaining files to places other tasks can use
    copy: {
        dist: {
            files: [{
                expand: true,
                dot: true,
                cwd: '<%= appConf.app %>/*',
                dest: '<%= appConf.dist %>',
                src: [
                    '*.{ico,png,txt}',
                    '{,*/}*.html',
                    'images/{,*/}*.{webp}',
                    'fonts/*'
                ]
            }, {
                expand: true,
                cwd: '<%= appConf.app %>/images',
                dest: '<%= appConf.dist %>/images',
                src: ['generated/*']
            }, { // not in use
                expand: true,
                cwd: 'bower_components/font-awesome',
                src: 'fonts/*',
                dest: '<%= appConf.dist %>'
            }]
        },
        styles: {
            files: [
                {
                    expand: true,
                    cwd: '<%= appConf.app %>/*',
                    dest: '<%= appConf.dist %>/styles',
                    src: '{,*/}*.css'
                }
            ]
        }
    },

    // Run some tasks in parallel to speed up the build process
    concurrent: {
        server: [
            'copy:styles'
        ],
        test: [
            'copy:styles'
        ],
        dist: [
            'copy:styles',
            'svgmin'
        ]
    },

    // Add vendor prefixed styles
    autoprefixer: {
        options: {
            browsers: ['last 1 version']
        },
        dist: {
            files: [{
                expand: true,
                cwd: '<%= appConf.app %>/*',
                src: '{,*/}*.css',
                dest: '<%= appConf.dist %>/styles/'
            }]
        }
    },

    // The actual grunt server settings
    connect: {
        options: {
            port: 9000,
            // Change this to '0.0.0.0' to access the server from outside.
            hostname: '0.0.0.0',
            livereload: 35729
        },
        livereload: {
            options: {
                open: true,
                middleware: function (connect) {
                    return [
                        modRewrite(['^[^\.]*$ /index.html [L]']),
                        connect.static('.tmp'),
                        connect().use(
                            '/bower_components',
                            connect.static('./bower_components')
                        ),
                        connect.static(appConfig.app)
                    ];
                }
            }
        },
        test: {
            options: {
                port: 9001,
                middleware: function (connect) {
                    return [
                        rewriteRulesSnippet,
                        connect.static('.tmp'),
                        connect.static('test'),
                        connect().use(
                            '/bower_components',
                            connect.static('./bower_components')
                        ),
                        connect.static(appConfig.app)
                    ];
                }
            }
        },
        dist: {
            options: {
                port:process.env.PORT,
                open: true,
                base: '<%= appConf.app %>'
            }
        }
    },

    // Make sure code styles are up to par and there are no obvious mistakes
    jshint: {
        options: {
            jshintrc: '.jshintrc',
            reporter: require('jshint-stylish')
        },
        all: {
            src: [
                'Gruntfile.js',
                'server.js',
                '<%= appConf.app %>/{,*/}*.js'
            ]
        }
    },

    // Watches files for changes and runs tasks based on the changed files
    watch: {
        bower: {
            files: ['bower.json'],
            tasks: ['wiredep']
        },
        js: {
            files: ['<%= appConf.app %>/{,**/}*.js'],
            tasks: ['newer:jshint:all'],
            options: {
                livereload: '<%= connect.options.livereload %>'
            }
        },
        css: {
            files: ['<%= appConf.app %>/styles/{,**/}*.scss'],
            tasks: ['sass'],
            options: {
                livereload: true,
            },
        },
        styles: {
            files: [
                '<%= appConf.app %>/styles/{,**/}*.css',
                '<%= appConf.app %>/../templating/css/style.css'
            ],
            tasks: ['newer:copy:styles', 'autoprefixer']
        },
        gruntfile: {
            files: ['Gruntfile.js']
        },
        livereload: {
            options: {
                livereload: '<%= connect.options.livereload %>'
            },
            files: [
                '<%= appConf.app %>/{,**/}*.html',
                '.tmp/styles/{,**/}*.css',
                '<%= appConf.app %>/images/{,**/}*.{png,jpg,jpeg,gif,webp,svg}'
            ]
        }
    },

    sass: {
        dev: {
            options: {
                style: 'expanded'
            },
            files: [
                {
                    expand: true,
                    cwd: '<%= appConf.app %>/styles',
                    src: ['*.scss'],
                    ext: '.css',
                    dest: '<%= appConf.dist %>/styles'
                }
            ]
        }
    }

});

grunt.loadNpmTasks('grunt-sass');

// Build the development application
grunt.registerTask('serve', 'Compile then start a connect web server', function () {

    grunt.task.run([
        'clean:server',
        'ngconstant:development',
        'wiredep',
        'sass',
        'concurrent:server',
        'autoprefixer',
        'connect:livereload',
        'watch'
    ]);
});

 // Build the production application
grunt.registerTask('build', 'Compile app on production settings', function () {

    grunt.task.run([
        'clean:server',
        'ngconstant:production',
        'wiredep',
        'sass',
        'concurrent:server',
        'autoprefixer',
        'connect:dist'
    ]);
});

};

server.js

var http = require('http');
var port = process.env.PORT || 80;

http.createServer(function (req, res) {

    res.writeHead(200, {
        'Content-Type': 'text/html',
        'Access-Control-Allow-Origin' : '*'
    });
    //res.end('app/index.html');

}).listen(port);
console.log('Server running at port '+port);

package.js上

{
"private": true,
"engines": {
  "node": "4.2.2"
},
 "scripts": {
  "postinstall": "bower install && grunt build",
  "start": "node server.js"
 },
 "dependencies": { all the dependancies .... }
}

这是一个巨大而苛刻的调试,但我终于找到了。

它来自我遇到的多个错误和错误:

  1. 节点server.js没用
  2. 我研究了 grunt 连接方法并创建了一个生产设置
  3. 我将 grunt serve 拆分为 grunt build 任务和 webconnect 任务

  4. 然后更新了package.json文件

对于 heroku 非常重要:在 Gruntfile.js 连接对象上:

 dist: {
        options: {
            port:process.env.PORT, #<=== need to have a dynamic port env for Heroku deployment
            open: true,
            base: '<%= appConf.dist %>'
        }
    }

这是添加的 grunt 任务:

// Build the production application
grunt.registerTask('build', 'Compile on dist folder', function () {

    grunt.task.run([
        'clean:dist',
        'ngconstant:production',
        'wiredep',
        'sass',
        'concurrent:dist',
        'autoprefixer:dist'
    ]);
});

// Build the production application
grunt.registerTask('webconnect', 'connect web server', function () {

    grunt.task.run([
        'connect:dist'
    ]);
});

然后 package.json :

"scripts": {
  "postinstall": "bower install && grunt build",
  "start": "grunt webconnect"
}