2014-03-12 53 views
4

我正在使用Express构建Web应用程序。我想合并,缩小和服务.js文件。我写了一个中间件,这是我的代码:使用Express合并,缩小和提供JavaScript文件,但不会缩小响应

var fs = require('fs'), 
    path = require('path'), 
    uglify = require('uglify-js'), 
    cache = '', 
    scriptsDir = path.join(__dirname, '../scripts'), 
    files = fs.readdirSync(scriptsDir); 

// Sync read is not a problem since the following code is executed on startup 
files.forEach(function(fname) { 
    if (/^.*\.js$/.test(fname)) { 
     cache += fs.readFileSync(path.join(scriptsDir, fname), 'utf8').toString(); 
    } 
}); 
cache = uglify.minify(cache, { fromString: true }).code; 

module.exports = function(req, res, next) { 
    if (req.url === '/js/all.js') 
     res.end(cache); 
    else 
     next(); 
}; 

中间件是这样使用:

app.use(compress()); 
[...] 
app.use(app.router); 
app.use(jsMerger); // Here is my middleware 
app.use(express.static(path.join(__dirname, '../public'))); 

的问题是不gzip压缩响应。此外,响应中还有“无标题”(我的意思是,没有缓存标题,没有etags; static中间件提供的其他资源具有这些标题)。这是回应:

X-Powered-By: Express 
Transfer-Encoding: chunked 
Date: Wed, 12 Mar 2014 14:04:19 GMT 
Connection: keep-alive 

我错过了什么吗?如何压缩响应?

+0

有关进一步参考,uglify = require('uglify-js')行会导入uglify.js2库(https://github.com/mishoo/UglifyJS2) – mneri

回答

1

添加该行后res.set('Content-Type', 'text/javascript') Express将gzip响应。该代码是

module.exports = function(req, res, next) { 
    if (req.url === '/js/all.js') { 
     res.set('Content-Type', 'text/javascript'); 
     res.end(cache); 
    } else { 
     next(); 
    } 
}; 

现在响应的标题是:

X-Powered-By: Express 
Vary: Accept-Encoding 
Transfer-Encoding: chunked 
Date: Wed, 12 Mar 2014 14:45:45 GMT 
Content-Type: text/javascript 
Content-Encoding: gzip 
Connection: keep-alive 

这样做的原因是compress中间件是如何设计的。只有符合筛选条件的要求

app.use(express.compress({ 
    filter : function(req, res) { 
     return /json|text|javascript/.test(res.getHeader('Content-Type')); 
    } 
}); 

压缩应用:你可以提供一个filter选项compress。的默认筛选器是:

function(req, res){ 
    return /json|text|javascript|dart|image\/svg\+xml|application\/x-font-ttf|application\/vnd\.ms-opentype|application\/vnd\.ms-fontobject/.test(res.getHeader('Content-Type')); 
}; 

如果你不提供Content-Type头,请求将无法通过过滤器,并表示不会gzip压缩的响应。