Bre*_*row 3 node.js express html5boilerplate
我正在设置一个新项目的结构,该项目将使用Node.js和Express构建.我正在使用HTML5 Boilerplate获得最佳起点.它附带了多种类型服务器的配置文件:Apache,Nginx,Node.js等.以下是HTML5 Boilerplate团队提供的Node.js服务器配置文件:
/* h5bp server-configs project
*
* maintainer: @xonecas
* contributors: @niftylettuce
*
* NOTES:
* compression: use the compress middleware provided by connect 2.x to enable gzip/deflate compression
* http://www.senchalabs.org/connect/compress.html
*
* concatenation: use on of the following middlewares to enable automatic concatenation of static assets
* - https://github.com/mape/connect-assetmanager
* - https://github.com/TrevorBurnham/connect-assets
*/
var h5bp = module.exports,
_http = require('http'),
_parse = require('url').parse;
// send the IE=Edge and chrome=1 headers for IE browsers
// on html/htm requests.
h5bp.ieEdgeChromeFrameHeader = function () {
return function (req, res, next) {
var url = req.url,
ua = req.headers['user-agent'];
if (ua && ua.indexOf('MSIE') > -1 && /html?($|\?|#)/.test(url)) {
res.setHeader('X-UA-Compatible', 'IE=Edge,chrome=1');
}
next();
};
};
// block access to hidden files and directories.
h5bp.protectDotfiles = function () {
return function (req, res, next) {
var error;
if (/(^|\/)\./.test(req.url)) {
error = new Error(_http.STATUS_CODES[405]); // 405, not allowed
error.status = 405;
}
next(error);
};
};
// block access to backup and source files
h5bp.blockBackupFiles = function () {
return function (req, res, next) {
var error;
if (/\.(bak|config|sql|fla|psd|ini|log|sh|inc|swp|dist)|~/.test(req.url)) {
error = new Error(_http.STATUS_CODES[405]); // 405, not allowed
error.status = 405;
}
next(error);
};
};
// Do we want to advertise what kind of server we're running?
h5bp.removePoweredBy = function () {
return function (req, res, next) {
res.removeHeader('X-Powered-By');
next();
};
};
// Enable CORS cross domain rules, more info at http://enble-cors.org/
h5bp.crossDomainRules = function () {
return function (req, res, next) {
res.setHeader('Access-Control-Allow-Origin', '*');
res.setHeader('Access-Control-Allow-Headers', 'X-Requested-With');
next();
};
};
// Suppress or force 'www' in the urls
// @param suppress = boolean
h5bp.suppressWww = function (suppress) {
return function (req, res, next) {
var url = req.url;
if (suppress && /^www\./.test(url)) {
res.statusCode = 302;
res.setHeader('Location', url.replace(/^www\./,''));
}
if (!suppress && !/^www\./.test(url)) {
res.statusCode = 302;
res.setHeader('Location', "www."+url);
}
next();
};
};
// Far expire headers
// use this when not using connect.static for your own expires/etag control
h5bp.expireHeaders = function (maxAge) {
return function (req, res, next) {
res.setHeader('Cache-Control', 'public, max-age='+ (maxAge));
next();
};
};
// Etag removal
// only use this is you are setting far expires for your files
// ** WARNING ** connect.static overrides this.
h5bp.removeEtag = function () {
return function (req, res, next) {
res.removeHeader('Last-Modified');
res.removeHeader('ETag');
next();
};
};
// set proper content type
// @param mime = reference to the mime module (https://github.com/bentomas/node-mime)
h5bp.setContentType = function (mime) {
return function (req, res, next) {
// I'm handling the dependency by having it passed as an argument
// we depend on the mime module to determine proper content types
// connect also has the same dependency for the static provider
// ** @TODO ** maybe connect/express expose this module somehow?
var path = _parse(req.url).pathname,
type = mime.lookup(path);
res.setHeader('Content-Type', type);
next();
};
};
// return a express/connect server with the default middlewares.
// @param serverConstructor = express/connect server instance
// @param options = {
// root: 'path/to/public/files',
// maxAge: integer, time in miliseconds ex: 1000 * 60 * 60 * 24 * 30 = 30 days,
// mime: reference to the mime module ex: require('mime')
// }
// Depends:
// express or connect server
// mime module [optional]
h5bp.server = function (serverConstructor, options) {
var server = serverConstructor.createServer(),
stack = [
this.suppressWww(true),
this.protectDotfiles(),
this.blockBackupFiles(),
this.crossDomainRules(),
this.ieEdgeChromeFrameHeader()
//,this.expireHeaders(options.maxAge),
// this.removeEtag(),
// this.setContentType(require('mime'))
];
// express/connect
if (server.use) {
stack.unshift(serverConstructor.logger('dev'));
stack.push(
//serverConstructor.compress(), // express doesn't seem to expose this middleware
serverConstructor['static'](options.root, { maxAge: options.maxAge }), // static is a reserved
serverConstructor.favicon(options.root, { maxAge: options.maxAge }),
serverConstructor.errorHandler({
stack: true,
message: true,
dump: true
})
);
for (var i = 0, len = stack.length; i < len; ++i) server.use(stack[i]);
} else {
server.on('request', function (req, res) {
var newStack = stack,
func;
(function next (err) {
if (err) {
throw err;
return;
} else {
func = newStack.shift();
if (func) func(req, res, next);
return;
}
})();
});
}
return server;
};
Run Code Online (Sandbox Code Playgroud)
我的问题是:我究竟如何将其与Express集成?特别困扰我的代码部分是底部:
// return a express/connect server with the default middlewares.
// @param serverConstructor = express/connect server instance
// @param options = {
// root: 'path/to/public/files',
// maxAge: integer, time in miliseconds ex: 1000 * 60 * 60 * 24 * 30 = 30 days,
// mime: reference to the mime module ex: require('mime')
// }
// Depends:
// express or connect server
// mime module [optional]
h5bp.server = function (serverConstructor, options) {
var server = serverConstructor.createServer(),
stack = [
this.suppressWww(true),
this.protectDotfiles(),
this.blockBackupFiles(),
this.crossDomainRules(),
this.ieEdgeChromeFrameHeader()
//,this.expireHeaders(options.maxAge),
// this.removeEtag(),
// this.setContentType(require('mime'))
];
// express/connect
if (server.use) {
stack.unshift(serverConstructor.logger('dev'));
stack.push(
//serverConstructor.compress(), // express doesn't seem to expose this middleware
serverConstructor['static'](options.root, { maxAge: options.maxAge }), // static is a reserved
serverConstructor.favicon(options.root, { maxAge: options.maxAge }),
serverConstructor.errorHandler({
stack: true,
message: true,
dump: true
})
);
for (var i = 0, len = stack.length; i < len; ++i) server.use(stack[i]);
} else {
server.on('request', function (req, res) {
var newStack = stack,
func;
(function next (err) {
if (err) {
throw err;
return;
} else {
func = newStack.shift();
if (func) func(req, res, next);
return;
}
})();
});
}
return server;
};
Run Code Online (Sandbox Code Playgroud)
我的JavaScript并不完全处于初学者水平,但我不会说我也是先进的.这段代码超出了我的意思.关于我能阅读,观察或做什么的任何指示,以了解我在这里明显缺少的东西将不胜感激.
大多数文件由一系列函数组成,这些函数生成符合Connect中间件规范的框架(如Express)的中间件.第二个代码清单旨在创建一个使用所有这些功能的HTTP服务器.从我所知道的,看起来你应该传入你通常会调用的任何createServer内容,而h5bp将为你创建和设置.例如,如果您通常会这样做:
var express = require('express');
var server = express.createServer();
Run Code Online (Sandbox Code Playgroud)
你会转而express去h5bp.server,它会调用createServer任何你直接传递给你的东西:
var express = require('express');
var server = h5bp.server(express, options);
Run Code Online (Sandbox Code Playgroud)
经过一些设置后,它会检查服务器是否有一个名为use(行是if (server.use))的函数,如果是,则使用它将它设置的所有中间件注入服务器.如果没有,那么它假设您正在使用原始Node.js HTTP服务器,并设置必要的代码以通过stack手动传递每个项目的请求(这是Connect/Express为您所做的).
值得一提的是,在快递3(目前处于发布候选阶段),通过Express创建从节点的HTTP服务器不再继承,这样你就不会调用应用程序createServer上express; 相反,你应该只是调用express()然后将结果传递给http.createServer.(有关详细信息,请参阅Express wiki上从2.x迁移到3.x的 "应用程序功能" .)这表示此脚本与最新版本的Express不兼容.
[更新]
如果你看看testGitHub 上的目录,你可以看到一个示例应用程序:
var express = require('express'),
h5bp = require('../node.js'),
server = h5bp.server(express, {
root: __dirname,
maxAge: 1000 * 60 * 60 * 30
});
server.listen(8080);
console.log('ok');
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
4125 次 |
| 最近记录: |