umi + express启用gzip的坑

1、umi 通过chainWebpack配置webpack插件compression-webpack-plugin压缩js、css文件,直接在构建产物中压缩好.gz文件去部署,详细不多说,可以参照这篇博客:

umi3分包优化,提升首屏加载时间

2、服务器使用express部署,网上大多数是关于ngix的配置,关于express启用gzip都是使用compression中间件开启gzip。

问题1:

compression中间件不会去使用部署时构建出来的.gz文件,还是根据请求路径去找到原文件再压缩(这就是另外一种gzip压缩解决方案:服务器压缩,这会造成服务器性能下降),因为我已经使用webpack构建压缩了,所以考虑不使用该中间件,自己写逻辑。

PS:不知道是我项目版本比较低,还是其他问题,各种测试后,compression中间件的确是忽略了部署的.gz文件,自己去压缩原文件。这里不太明白,有大佬指导具体细节可以指导一下。

问题2:

然而自己写的逻辑中,js返回没问题,css样式表返回后浏览器无法识别,最后发现是express服务器会根据实际资源文件类型去设置Content-type,返回的文件是.gz,所以css、js的响应头Content-type都变成了application/gzip,导致浏览器无法识别css样式表。

最终版本如下:compression-webpack-plugin 压缩了js和css,生成同名的.gz文件,express服务器存在请求资源同名.gz文件时,返回.gz文件,并设置正确的响应头

app.use(function (req, res, next) {
    // ps:不要使用compression中间件,compression中间件不会使用已经存在.gz文件,还是会根据请求资源路径去压缩
    const fullPath = path.join(__dirname, `\\dist\\${req.originalUrl}.gz`);
    // 手动检测是否存在同名.gz压缩文件,且浏览器支持gzip 则返回对应的文件
    if (fs.existsSync(fullPath) && req.headers['accept-encoding'].includes('gzip')) {
        // 告诉浏览器用gzip编码格式来解析
        res.setHeader('Content-Encoding', 'gzip')
        // 此处根据请求路径去设置响应类型,服务器默认根据资源类型设置响应类型,会导致层叠样式表响应类型浏览器无法识别的情况。
        if (/\.js$/.test(req.originalUrl)) {
            res.setHeader('Content-type', 'application/javascript; charset=UTF-8');
        }
        if (/\.css$/.test(req.originalUrl)) {
            res.setHeader('Content-type', 'text/css; charset=UTF-8');
        }
        // 并把对应的“.gz”格式文件发送给浏览器。
        res.sendFile(fullPath);
    } else {
        next();
    }
});
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值