2015-06-25 5 views
1

Я новичок в разработке среднего стека.Как связать сервер и клиент с grunt.js?

У меня есть проект, в котором необходимо добавить пользовательский интерфейс, который компилируется через grunt.

Мой сервер, начиная с команды node server и gruntfile, скомпилирует всю мою клиентскую сторону. Но мне нужен мой сервер запускать grunt и компилировать все представления. Я добавил grunt-express, добавил его к задачам, но когда я делаю grunt serve, на нем нет серверной части. Он остался на порту 3000.

Как я могу реализовать две стороны компиляции grunt?

Gruntfile.js

"use strict"; 
var LIVERELOAD_PORT, lrSnippet, mountFolder; 

LIVERELOAD_PORT = 35728; 

lrSnippet = require("connect-livereload")({ 
    port: LIVERELOAD_PORT 
}); 

mountFolder = function(connect, dir) { 
    return connect["static"](require("path").resolve(dir)); 
}; 

module.exports = function(grunt) { 
    var yeomanConfig; 
    require("load-grunt-tasks")(grunt); 
    require("time-grunt")(grunt); 
    yeomanConfig = { 
    app: "client", 
    dist: "dist", 
    docs: "documentation" 
    }; 
    try { 
    yeomanConfig.app = require("./bower.json").appPath || yeomanConfig.app; 
    } catch (_error) {} 
    grunt.initConfig({ 
    yeoman: yeomanConfig, 
    serverJS: ["Gruntfile.js", "server.js", "config/**/*.js", "app/**/*.js"], 
    watch: { 
     express: { 
     files: [ 
      "app/**/*.js", 
      "config/{,*/}*.js", 
      "server.js", 
      "Gruntfile.js" 
     ], 
     tasks: "express:dev", 
     options: { 
      nospawn: true 
     } 
     }, 
     compass: { 
     files: ["<%= yeoman.app %>/styles/**/*.{scss,sass}"], 
     tasks: ["compass:server"] 
     }, 
     less: { 
     files: ["<%= yeoman.app %>/styles-less/**/*.less"], 
     tasks: ["less:server"] 
     }, 
     jade: { 
     files: ["<%= yeoman.docs %>/jade/*.jade"], 
     tasks: ["jade:docs"] 
     }, 
     livereload: { 
     options: { 
      livereload: LIVERELOAD_PORT 
     }, 
     files: [ 
      "<%= yeoman.app %>/index.html", 
      "<%= yeoman.app %>/app/**/*.html", 
      "<%= yeoman.app %>/app/**/*.js", 
      "<%= yeoman.app %>/styles/**/*.scss", 
      "<%= yeoman.app %>/styles-less/**/*.less", 
      ".tmp/styles/**/*.css", 
      "<%= yeoman.app %>/images/**/*.{png,jpg,jpeg,gif,webp,svg}", 
      "<%= yeoman.docs %>/jade/*.jade" 
     ] 
     } 
    }, 
    express: { 
     server: { 
     options : { 
      port: 3000, 
      script: 'server.js' 
     } 
     } 
    }, 
    connect: { 
     options: { 
     port: 5000, 
     hostname: "localhost" 
     }, 
     livereload: { 
     options: { 
      middleware: function(connect) { 
      return [lrSnippet, mountFolder(connect, ".tmp"), mountFolder(connect, yeomanConfig.app)]; 
      } 
     } 
     }, 
     docs: { 
     options: { 
      middleware: function(connect) { 
      return [lrSnippet, mountFolder(connect, yeomanConfig.docs)]; 
      } 
     } 
     }, 
     test: { 
     options: { 
      middleware: function(connect) { 
      return [mountFolder(connect, ".tmp"), mountFolder(connect, "test")]; 
      } 
     } 
     }, 
     dist: { 
     options: { 
      middleware: function(connect) { 
      return [mountFolder(connect, yeomanConfig.dist)]; 
      } 
     } 
     } 
    }, 
    open: { 
     server: { 
     url: "http://localhost:<%= connect.options.port %>" 
     } 
    }, 
    clean: { 
     dist: { 
     files: [ 
      { 
      dot: true, 
      src: [".tmp", "<%= yeoman.dist %>/*", "!<%= yeoman.dist %>/.git*"] 
      } 
     ] 
     }, 
     all: [".tmp", ".sass-cache", "readme.md", "client/bower_components", "documentation/jade", "documentation/config.codekit", "landing/jade", "landing/config.codekit", "node_modules", ".git"], 
     server: ".tmp" 
    }, 
    jshint: { 
     options: { 
     jshintrc: ".jshintrc" 
     }, 
     all: ["Gruntfile.js", "<%= yeoman.app %>/scripts/**/*.js"] 
    }, 
    injector: { 
     options: { 
     relative: true 
     }, 
     local_dependencies: { 
     files: { 
      "<%= yeoman.app %>/index.html": [ 
      "<%= yeoman.app %>/app/**/*.module.js", 
      "<%= yeoman.app %>/app/**/*.js", 
      "!" + "<%= yeoman.app %>/**/*.spec.js" 
      ] 
     } 
     }, 
    }, 
    jade: { 
     docs: { 
     options: { 
      pretty: true 
     }, 
     files: { 
      "<%= yeoman.docs %>/index.html": ["<%= yeoman.docs %>/jade/index.jade"] 
     } 
     } 
    }, 
    compass: { 
     options: { 
     sassDir: "<%= yeoman.app %>/styles", 
     cssDir: ".tmp/styles", 
     generatedImagesDir: ".tmp/styles/ui/images/", 
     imagesDir: "<%= yeoman.app %>/styles/ui/images/", 
     javascriptsDir: "<%= yeoman.app %>/scripts", 
     fontsDir: "<%= yeoman.app %>/fonts", 
     importPath: "<%= yeoman.app %>/bower_components", 
     httpImagesPath: "styles/ui/images/", 
     httpGeneratedImagesPath: "styles/ui/images/", 
     httpFontsPath: "fonts", 
     relativeAssets: true 
     }, 
     dist: { 
     options: { 
      outputStyle: 'compressed', 
      debugInfo: false, 
      noLineComments: true 
     } 
     }, 
     server: { 
     options: { 
      debugInfo: true 
     } 
     }, 
     forvalidation: { 
     options: { 
      debugInfo: false, 
      noLineComments: false 
     } 
     } 
    }, 
    less: { 
     server: { 
     options: { 
      strictMath: true, 
      dumpLineNumbers: true, 
      sourceMap: true, 
      sourceMapRootpath: "", 
      outputSourceFiles: true 
     }, 
     files: [ 
      { 
      expand: true, 
      cwd: "<%= yeoman.app %>/styles-less", 
      src: "main.less", 
      dest: ".tmp/styles", 
      ext: ".css" 
      } 
     ] 
     }, 
     dist: { 
     options: { 
      cleancss: true, 
      report: 'min' 
     }, 
     files: [ 
      { 
      expand: true, 
      cwd: "<%= yeoman.app %>/styles-less", 
      src: "main.less", 
      dest: ".tmp/styles", 
      ext: ".css" 
      } 
     ] 
     } 
    }, 
    useminPrepare: { 
     html: "<%= yeoman.app %>/index.html", 
     options: { 
     dest: "<%= yeoman.dist %>", 
     flow: { 
      steps: { 
      js: ["concat"], 
      css: ["cssmin"] 
      }, 
      post: [] 
     } 
     } 
    }, 
    usemin: { 
     html: ["<%= yeoman.dist %>/**/*.html", "!<%= yeoman.dist %>/bower_components/**"], 
     css: ["<%= yeoman.dist %>/styles/**/*.css"], 
     options: { 
     dirs: ["<%= yeoman.dist %>"] 
     } 
    }, 
    htmlmin: { 
     dist: { 
     options: {}, 
     files: [ 
      { 
      expand: true, 
      cwd: "<%= yeoman.app %>", 
      src: ["*.html", "views/*.html"], 
      dest: "<%= yeoman.dist %>" 
      } 
     ] 
     } 
    }, 
    copy: { 
     dist: { 
     files: [ 
      { 
      expand: true, 
      dot: true, 
      cwd: "<%= yeoman.app %>", 
      dest: "<%= yeoman.dist %>", 
      src: [ 
       "favicon.ico", 
       "bower_components/font-awesome/css/*", 
       "bower_components/font-awesome/fonts/*", 
       "bower_components/weather-icons/css/*", 
       "bower_components/weather-icons/fonts/*", 
       "bower_components/weather-icons/font/*", 
       "fonts/**/*", 
       "i18n/**/*", 
       "images/**/*", 
       "styles/fonts/**/*", 
       "styles/img/**/*", 
       "styles/ui/images/*", 
       "app/**/*.html" 
      ] 
      }, { 
      expand: true, 
      cwd: ".tmp", 
      dest: "<%= yeoman.dist %>", 
      src: ["styles/**", "assets/**"] 
      }, { 
      expand: true, 
      cwd: ".tmp/images", 
      dest: "<%= yeoman.dist %>/images", 
      src: ["generated/*"] 
      } 
     ] 
     }, 
     styles: { 
     expand: true, 
     cwd: "<%= yeoman.app %>/styles", 
     dest: ".tmp/styles/", 
     src: "**/*.css" 
     } 
    }, 
    concurrent: { 
     server: ["compass:server", "copy:styles"], 
     dist: ["compass:dist", "copy:styles", "htmlmin"], 
     lessServer: ["less:server", "copy:styles"], 
     lessDist: ["less:dist", "copy:styles", "htmlmin"] 
    }, 
    cssmin: { 
     options: { 
     keepSpecialComments: '0' 
     }, 
     dist: {} 
    }, 
    concat: { 
     options: { 
     separator: grunt.util.linefeed + ';' + grunt.util.linefeed 
     }, 
     dist: {} 
    }, 
    uglify: { 
     options: { 
     mangle: false, 
     compress: { 
      drop_console: true 
     } 
     }, 
     dist: { 
     files: { 
      "<%= yeoman.dist %>/scripts/app.js": [".tmp/**/*.js", "<%= yeoman.app %>/scripts/**/*.js", "!<%= yeoman.app %>/scripts/vendors/**"] 
     } 
     } 
    } 
    }); 
    grunt.registerTask("docs", function() { 
    return grunt.task.run(["jade:docs", "connect:docs", "open", "watch"]); 
    }); 
    grunt.registerTask("server", function(target) { 
    if (target === "dist") { 
     return grunt.task.run(["serve:dist"]); 
    } 
    return grunt.task.run(["serve"]); 
    }); 
    grunt.registerTask("serve", function(target) { 
    if (target === "dist") { 
     return grunt.task.run(["build", "open", "connect:dist:keepalive"]); 
    } 
    return grunt.task.run(["clean:server", "concurrent:server", "express:server", "connect:livereload", "open", "watch"]); 
    }); 
    grunt.registerTask("build", ["clean:dist", "useminPrepare", "concurrent:dist", "copy:dist", "cssmin", "concat", "uglify", "usemin"]); 
    return grunt.registerTask("default", ["serve"]); 
}; 

server.js

var express   = require('express'), 
    fs    = require('fs'), 
    passport  = require('passport'), 
    mongoose  = require('mongoose'), 
    http   = require('http'), 
    app    = express(), 
    server   = require('http').createServer(app), 
    config   = require('./config/environment'), 
    auth   = require('./config/middlewares/authorization'), 
    models_path  = __dirname + '/app/models', 
    routes_path  = __dirname + '/app/routes'; 
fs.readdirSync(models_path).forEach(function (file) { 
    require(models_path + '/' + file); 
}); 

app.set('port', process.env.OPENSHIFT_NODEJS_PORT || 3000); 
app.set('ipaddr', process.env.OPENSHIFT_NODEJS_IP || 'localhost'); 

require('./config/express')(app, config, passport); 
require('./config/passport')(passport, config); 

fs.readdirSync(routes_path).forEach(function (file) { 
    require(routes_path + '/' + file)(app, passport, auth); 
}); 

mongoose.connect(config.db); 
server.listen(app.get('port'), app.get('ipaddr'), function(){ 
    console.log('Express server listening on IP/hostname: "' + app.get('ipaddr') + '" and port: "' + app.get('port') + '"'); 
}); 

ответ

1

Ok. Я решил это с grunt-connect-proxy. Я добавил, чтобы подключиться к прокси-серверу, и он работает окончательно. Вот весь код файла grunt:

"use strict"; 
var LIVERELOAD_PORT, lrSnippet, mountFolder, proxySnippet; 

LIVERELOAD_PORT = 35728; 

lrSnippet = require("connect-livereload")({ 
    port: LIVERELOAD_PORT 
}); 

mountFolder = function(connect, dir) { 
    return connect["static"](require("path").resolve(dir)); 
}; 

module.exports = function(grunt) { 
    var yeomanConfig; 
    proxySnippet = require("grunt-connect-proxy/lib/utils").proxyRequest; 
    require("load-grunt-tasks")(grunt); 
    require("time-grunt")(grunt); 
    yeomanConfig = { 
    app: "client", 
    dist: "dist", 
    docs: "documentation" 
    }; 
    try { 
    yeomanConfig.app = require("./bower.json").appPath || yeomanConfig.app; 
    } catch (_error) {} 
    grunt.initConfig({ 
    yeoman: yeomanConfig, 
    appFiles: { 
     serverJS: ["Gruntfile.js", "server.js", "config/{,*/}*.js", "app/**/*.js"] 
    }, 
    watch: { 
     express: { 
     files: "<%= appFiles.serverJS %>", 
     tasks: "express:dev", 
     options: { 
      nospawn: true 
     } 
     }, 
     compass: { 
     files: ["<%= yeoman.app %>/styles/**/*.{scss,sass}"], 
     tasks: ["compass:server"] 
     }, 
     less: { 
     files: ["<%= yeoman.app %>/styles-less/**/*.less"], 
     tasks: ["less:server"] 
     }, 
     jade: { 
     files: ["<%= yeoman.docs %>/jade/*.jade"], 
     tasks: ["jade:docs"] 
     }, 
     livereload: { 
     options: { 
      livereload: LIVERELOAD_PORT 
     }, 
     files: [ 
      "<%= yeoman.app %>/index.html", 
      "<%= yeoman.app %>/app/**/*.html", 
      "<%= yeoman.app %>/app/**/*.js", 
      "<%= yeoman.app %>/styles/**/*.scss", 
      "<%= yeoman.app %>/styles-less/**/*.less", 
      ".tmp/styles/**/*.css", 
      "<%= yeoman.app %>/images/**/*.{png,jpg,jpeg,gif,webp,svg}", 
      "<%= yeoman.docs %>/jade/*.jade" 
     ] 
     } 
    }, 
    express: { 
     server: { 
     options : { 
      port: 3000, 
      script: 'server.js' 
     } 
     } 
    }, 
    connect: { 
     options: { 
     port: 5000, 
     hostname: "localhost" 
     }, 
     proxies: [ 
     { 
      context: "/", 
      host: "localhost", 
      port: 3000 + "", 
      https: false, 
      changeOrigin: false 
     } 
     ], 
     livereload: { 
     options: { 
      middleware: function(connect) { 
      return [lrSnippet, mountFolder(connect, ".tmp"), mountFolder(connect, yeomanConfig.app), proxySnippet]; 
      } 
     } 
     }, 
     docs: { 
     options: { 
      middleware: function(connect) { 
      return [lrSnippet, mountFolder(connect, yeomanConfig.docs)]; 
      } 
     } 
     }, 
     test: { 
     options: { 
      middleware: function(connect) { 
      return [mountFolder(connect, ".tmp"), mountFolder(connect, "test")]; 
      } 
     } 
     }, 
     dist: { 
     options: { 
      middleware: function(connect) { 
      return [mountFolder(connect, yeomanConfig.dist)]; 
      } 
     } 
     } 
    }, 
    open: { 
     server: { 
     url: "http://localhost:<%= connect.options.port %>" 
     } 
    }, 
    clean: { 
     dist: { 
     files: [ 
      { 
      dot: true, 
      src: [".tmp", "<%= yeoman.dist %>/*", "!<%= yeoman.dist %>/.git*"] 
      } 
     ] 
     }, 
     all: [".tmp", ".sass-cache", "readme.md", "client/bower_components", "documentation/jade", "documentation/config.codekit", "landing/jade", "landing/config.codekit", "node_modules", ".git"], 
     server: ".tmp" 
    }, 
    jshint: { 
     options: { 
     jshintrc: ".jshintrc" 
     }, 
     all: ["Gruntfile.js", "<%= yeoman.app %>/scripts/**/*.js"] 
    }, 
    injector: { 
     options: { 
     relative: true 
     }, 
     local_dependencies: { 
     files: { 
      "<%= yeoman.app %>/index.html": [ 
      "<%= yeoman.app %>/app/**/*.module.js", 
      "<%= yeoman.app %>/app/**/*.js", 
      "!" + "<%= yeoman.app %>/**/*.spec.js" 
      ] 
     } 
     }, 
    }, 
    jade: { 
     docs: { 
     options: { 
      pretty: true 
     }, 
     files: { 
      "<%= yeoman.docs %>/index.html": ["<%= yeoman.docs %>/jade/index.jade"] 
     } 
     } 
    }, 
    compass: { 
     options: { 
     sassDir: "<%= yeoman.app %>/styles", 
     cssDir: ".tmp/styles", 
     generatedImagesDir: ".tmp/styles/ui/images/", 
     imagesDir: "<%= yeoman.app %>/styles/ui/images/", 
     javascriptsDir: "<%= yeoman.app %>/scripts", 
     fontsDir: "<%= yeoman.app %>/fonts", 
     importPath: "<%= yeoman.app %>/bower_components", 
     httpImagesPath: "styles/ui/images/", 
     httpGeneratedImagesPath: "styles/ui/images/", 
     httpFontsPath: "fonts", 
     relativeAssets: true 
     }, 
     dist: { 
     options: { 
      outputStyle: 'compressed', 
      debugInfo: false, 
      noLineComments: true 
     } 
     }, 
     server: { 
     options: { 
      debugInfo: true 
     } 
     }, 
     forvalidation: { 
     options: { 
      debugInfo: false, 
      noLineComments: false 
     } 
     } 
    }, 
    less: { 
     server: { 
     options: { 
      strictMath: true, 
      dumpLineNumbers: true, 
      sourceMap: true, 
      sourceMapRootpath: "", 
      outputSourceFiles: true 
     }, 
     files: [ 
      { 
      expand: true, 
      cwd: "<%= yeoman.app %>/styles-less", 
      src: "main.less", 
      dest: ".tmp/styles", 
      ext: ".css" 
      } 
     ] 
     }, 
     dist: { 
     options: { 
      cleancss: true, 
      report: 'min' 
     }, 
     files: [ 
      { 
      expand: true, 
      cwd: "<%= yeoman.app %>/styles-less", 
      src: "main.less", 
      dest: ".tmp/styles", 
      ext: ".css" 
      } 
     ] 
     } 
    }, 
    useminPrepare: { 
     html: "<%= yeoman.app %>/index.html", 
     options: { 
     dest: "<%= yeoman.dist %>", 
     flow: { 
      steps: { 
      js: ["concat"], 
      css: ["cssmin"] 
      }, 
      post: [] 
     } 
     } 
    }, 
    usemin: { 
     html: ["<%= yeoman.dist %>/**/*.html", "!<%= yeoman.dist %>/bower_components/**"], 
     css: ["<%= yeoman.dist %>/styles/**/*.css"], 
     options: { 
     dirs: ["<%= yeoman.dist %>"] 
     } 
    }, 
    htmlmin: { 
     dist: { 
     options: {}, 
     files: [ 
      { 
      expand: true, 
      cwd: "<%= yeoman.app %>", 
      src: ["*.html", "views/*.html"], 
      dest: "<%= yeoman.dist %>" 
      } 
     ] 
     } 
    }, 
    copy: { 
     dist: { 
     files: [ 
      { 
      expand: true, 
      dot: true, 
      cwd: "<%= yeoman.app %>", 
      dest: "<%= yeoman.dist %>", 
      src: [ 
       "favicon.ico", 
       "bower_components/font-awesome/css/*", 
       "bower_components/font-awesome/fonts/*", 
       "bower_components/weather-icons/css/*", 
       "bower_components/weather-icons/fonts/*", 
       "bower_components/weather-icons/font/*", 
       "fonts/**/*", 
       "i18n/**/*", 
       "images/**/*", 
       "styles/fonts/**/*", 
       "styles/img/**/*", 
       "styles/ui/images/*", 
       "app/**/*.html" 
      ] 
      }, { 
      expand: true, 
      cwd: ".tmp", 
      dest: "<%= yeoman.dist %>", 
      src: ["styles/**", "assets/**"] 
      }, { 
      expand: true, 
      cwd: ".tmp/images", 
      dest: "<%= yeoman.dist %>/images", 
      src: ["generated/*"] 
      } 
     ] 
     }, 
     styles: { 
     expand: true, 
     cwd: "<%= yeoman.app %>/styles", 
     dest: ".tmp/styles/", 
     src: "**/*.css" 
     } 
    }, 
    concurrent: { 
     server: ["compass:server", "copy:styles"], 
     dist: ["compass:dist", "copy:styles", "htmlmin"], 
     lessServer: ["less:server", "copy:styles"], 
     lessDist: ["less:dist", "copy:styles", "htmlmin"] 
    }, 
    cssmin: { 
     options: { 
     keepSpecialComments: '0' 
     }, 
     dist: {} 
    }, 
    concat: { 
     options: { 
     separator: grunt.util.linefeed + ';' + grunt.util.linefeed 
     }, 
     dist: {} 
    }, 
    uglify: { 
     options: { 
     mangle: false, 
     compress: { 
      drop_console: true 
     } 
     }, 
     dist: { 
     files: { 
      "<%= yeoman.dist %>/scripts/app.js": [".tmp/**/*.js", "<%= yeoman.app %>/scripts/**/*.js", "!<%= yeoman.app %>/scripts/vendors/**"] 
     } 
     } 
    } 
    }); 
    grunt.registerTask("docs", function() { 
    return grunt.task.run(["jade:docs", "connect:docs", "open", "watch"]); 
    }); 
    grunt.registerTask("server", function(target) { 
    if (target === "dist") { 
     return grunt.task.run(["serve:dist"]); 
    } 
    return grunt.task.run(["serve"]); 
    }); 
    grunt.registerTask("serve", function(target) { 
    if (target === "dist") { 
     return grunt.task.run(["build", "open", "connect:dist:keepalive"]); 
    } 
    return grunt.task.run(["clean:server", "concurrent:server", "configureProxies", "express:server", "connect:livereload", "open", "watch"]); 
    }); 
    grunt.registerTask("build", ["clean:dist", "useminPrepare", "concurrent:dist", "copy:dist", "cssmin", "concat", "uglify", "usemin"]); 
    return grunt.registerTask("default", ["serve"]); 
}; 
Смежные вопросы