我正在使用 Cloudfront 和 S3 部署 React 应用程序,我想启用 brotli 进行压缩。我看过一些使用 lambda@edge 解决这个问题的教程。我的 Cloudfront 发行版的行为配置如下
我还将“自动压缩对象”选项设置为“否”。我分别为源请求和查看器请求关联了以下两个 lambda 函数:
- 来源请求:
'use strict';
/**
* Funciton registered on 'Origin Request' CloudFront Event
*/
exports.handler = (event, context, callback) => {
const request = event.Records[0].cf.request;
console.log(JSON.stringify(request));
const headers = request.headers;
const isBr = headers['x-compression'] && headers['x-compression'][0].value === "br";
const isGzip = headers['x-compression'] && headers['x-compression'][0].value === "gzip";
/**
* Update request path based on custom header
*/
let extension = "";
if(isBr)
extension = ".br";
else if(isGzip)
extension = ".gzip";
request.uri = request.uri + extension;
callback(null, request);
};
- 观众要求:
'use strict';
/**
* Funciton registered on 'Viewer Request' CloudFront Event
*/
exports.handler = (event, context, callback) => {
const request = event.Records[0].cf.request;
const headers = request.headers;
console.log(JSON.stringify(request));
/**
* Detect if brotli is supported by the browser.
* Pass a custom header x-compression to be captured by the lambda in the origin-request phase.
*/
if(headers['accept-encoding'] && headers['accept-encoding'][0].value.indexOf('br') > -1) {
headers['x-compression'] = [{
key: 'X-Compression',
value: 'br'
}];
}
else if(headers['accept-encoding'] && headers['accept-encoding'][0].value.indexOf('gzip') > -1){
headers['x-compression'] = [{
key: 'X-Compression',
value: 'gzip'
}];
}
callback(null, request);
};
当我尝试在浏览器中使用 Cloudfront 的域名打开应用程序时,会抛出 Uncaught SyntaxError:bundle.js:1 中的非法字符。但是,当我使用 S3 的端点打开应用程序时,它运行良好。以下是我的webpack.config.js
:
const path = require('path');
const autoprefixer = require('autoprefixer');
const HtmlWebpackPlugin = require('html-webpack-plugin');
const CompressionPlugin = require('compression-webpack-plugin');
module.exports = {
entry: './src/index.js',
output: {
path: path.resolve(__dirname, 'dist'),
filename: 'bundle.js',
chunkFilename: '[id].js',
publicPath: ''
},
resolve: {
extensions: ['.js', '.jsx']
},
module: {
rules: [
{
test: /\.js$/,
loader: 'babel-loader',
exclude: /node_modules/
},
{
test: /\.css$/,
exclude: /node_modules/,
use: [
{ loader: 'style-loader' },
{
loader: 'css-loader',
options: {
modules: {
localIdentName: "[name]__[local]___[hash:base64:5]",
},
sourceMap: true
}
},
{
loader: 'postcss-loader',
options: {
ident: 'postcss',
plugins: () => [
autoprefixer({})
]
}
}
]
},
{
test: /\.(png|jpe?g|gif)$/,
loader: 'url-loader?limit=10000&name=img/[name].[ext]'
}
]
},
plugins: [
new HtmlWebpackPlugin({
template: __dirname + '/src/index.html',
filename: 'index.html',
inject: 'body'
}),
new CompressionPlugin({
filename: '[path].gz',
threshold: 0,
minRatio: 2,
test: /\.(js|css)$/i
}),
new CompressionPlugin({
filename: '[path].br',
algorithm: 'brotliCompress',
threshold: 0,
minRatio: 2,
test: /\.(js|css)$/i,
compressionOptions: {level: 11}
})
]
};
我已将代码放在此 GitHub 存储库中(我还上传了 dist/ 目录,这是我上传到 S3 以进行部署的目录)。我是这项技术的新手,所以我没有想法。我还尝试将 .html 和 .png 扩展名添加到 Webpack 配置文件中的插件构造函数,但这也不起作用。任何帮助将不胜感激,在此先感谢