【问题标题】:How to bind server and client at grunt.js?如何在 grunt.js 上绑定服务器和客户端?
【发布时间】:2015-06-25 16:54:04
【问题描述】:

我是平均堆栈开发的新手。

我有一个项目,需要添加一个通过 grunt 编译的用户界面。

我的服务器从命令node server 开始,gruntfile 编译我所有的客户端。但我需要我的 grunt 启动服务器并编译所有视图。 我添加了grunt-express,将其添加到任务中,但是当我创建grunt serve 时,上面没有服务器端。它停留在 3000 端口。

如何在 grunt compile 上实现两个方面?

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') + '"');
});

【问题讨论】:

    标签: node.js gruntjs grunt-express


    【解决方案1】:

    好的。我用grunt-connect-proxy 解决了它。我添加了连接任务代理,它终于可以工作了。这是 gruntfile 的所有代码:

    "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"]);
    };
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2012-10-17
      • 1970-01-01
      • 1970-01-01
      • 2013-02-23
      • 2012-05-15
      • 1970-01-01
      • 2023-03-21
      • 1970-01-01
      相关资源
      最近更新 更多