将 Vue.js 项目部署至静态网站托管,并开启 Gzip 压缩

举报
云存储开发者支持团队 发表于 2022/11/28 20:13:11 2022/11/28
【摘要】 关于使用 Nginx 开启静态网站 Gzip 压缩的教程已经有很多了,但是好像没几个讲怎么在对象存储的静态网站中开启 Gzip 压缩。其实也不复杂,我们一起来看下~

将 Vue.js 项目部署至静态网站托管,并开启 Gzip 压缩

关于使用 Nginx 开启静态网站 Gzip 压缩的教程已经有很多了,但是好像没几个讲怎么在对象存储的静态网站中开启 Gzip 压缩。其实也不复杂,我们一起来看下~

1. 打包项目

1.1 先安装 compression-webpack-plugin 插件:
npm install compression-webpack-plugin --save-dev

1.2 在 vue.config.js 中开启压缩插件(项目下没有此文件可以在根目录下创建):

const CompressionWebpackPlugin = require('compression-webpack-plugin');
module.exports = defineConfig({
    transpileDependencies: true,
    configureWebpack: config => {
        config.externals = {}
        if (process.env.NODE_ENV === 'production') {
            return {
                plugins: [new CompressionWebpackPlugin({
                    test: /\.js$|\.html$|\.css/, // 压缩文件的后缀
                    threshold: 1024,  // 对超过 1k 的文件进行压缩
                    deleteOriginalAssets: true, // 不需要保留压缩前文件
                })]
            }
        }
    }
})

1.3 运行 npm run build 打包项目,打包后打开打包产物目录,可以看到文件后缀有 .gz
打包结果.PNG

2. 开启静态网站托管并上传网站

2.1 创建桶并开启静态网站托管

进入对象存储控制台,点击右上角创建桶。
创建桶.PNG

这里桶名需要注意下,全局唯一,不能与其他人的重复,桶策略选择公共读

创建桶2.PNG

注意:开启公共读后,任何人均能访问你桶内的数据!!强烈建议这个桶仅用作静态网站托管,不要存放隐私数据
注意:开启公共读后,任何人均能访问你桶内的数据!!强烈建议这个桶仅用作静态网站托管,不要存放隐私数据
注意:开启公共读后,任何人均能访问你桶内的数据!!强烈建议这个桶仅用作静态网站托管,不要存放隐私数据

创建后点击桶名,进入桶配置,点击静态网站托管,配置静态网站
配置静态网站.PNG

此处示例项目比较简单,默认首页和默认 404 页面均填写 index.html,不需要配置重定向规则
配置静态网站2.PNG

这个网址即是网站地址

配置静态网站3.PNG

此时点击打开会提示 404,因为我们还没有上传网站文件,接下来会上传网站文件并配置 Gzip 压缩。

配置静态网站4.PNG

2.1.2 配置域名解析

在配置静态网站时,可以看到有提示从 22 年 3 月开始 OBS 禁止通过默认域名(桶访问域名或静态网站访问域名)使用静态网站托管功能。如果是新创建的桶,必须要配置桶域名才能访问。

点击左侧域名管理,点击绑定用户域名
绑定域名.PNG
绑定域名2.PNG

设置完成后,需要去自己的域名供应商处将域名 CNAME 指向 OBS 桶域名,等待一会儿解析生效。

2.2 上传静态网站并配置 Gzip 压缩

这里先讲两个错误步骤和错误的原因原因,太长不看可跳转 # 2.2.2 正确方案 ,更推荐直接参考 # 3 更进一步--自动设置元数据

2.2.1 试错手动方案

由于对象存储的对象名强唯一的,即并不会自动把 xxx.js 指向 xxx.js.gz,此时如果直接把 dist 目录下文件上传到对象存储并开启静态网站托管,会发现浏览器找不到 .gz 文件,会报错 404,页面一片空白。

浏览器报错.PNG

手动版解决方法非常粗暴,直接上传前把文件名后缀 .gz 去掉再上传就行,这里需要记下来都改了哪些文件的后缀,一会儿要用到。

改后缀.PNG

去除后缀后,请求没报错 404 了,但是页面还是一片空白,这又是为啥?

浏览器报错2.PNG

原因是浏览器是根据服务器发来的请求头来判断收到的文件到底是什么类型,再决定该如何处理,如果内容被压缩了,就必须要显示的告诉浏览需要解压后才能使用。Nginx 配置后,会自动给响应加上说明告知浏览器,但是对象存储不会主动告知,需要我们处理。

手动处理方法也很粗暴,挨个去设置元数据添加 Content-Encoding: gzip,此处使用 OBS Browser+ 工具,浏览器操作类似。

修改元数据.PNG

修改元数据2.PNG

2.2.2 正确方案

  1. 手动将所有对象的 .gz 后缀去掉
  2. 挨个去给去过后缀的对象添加元数据:Content-Encoding: gzip

3. 更进一步 —— 自动设置元数据

本文用的示例项目比较简单,只有三个文件需要改,手工改还不麻烦,但是对与复杂项目可能要几十上百个文件,处理起来就非常麻烦,程序员的思路就是能代码解决就不要动手,这里我们使用 数据工坊 DWR 服务自动改文件名 + 改后缀。这里的介绍比较简单,如果想使用 DWR 进行更为复杂的操作,可以参考这篇博文

3.1 创建函数

首先进入 FunctionGraph 服务,创建一个修改文件名和元数据的 Serverless 函数。记得切换下 region,选择目标 OBS 桶所在 Region。

创建函数.PNG
创建函数2.PNG

函数内容为

# -*- coding:utf-8 -*-

from urllib.parse import unquote_plus

from obs import ObsClient, SetObjectMetadataHeader


def handler(event, context):
    # 获取桶名与对象名
    region_id, bucket_name, object_name = get_obs_obj_info(event.get("Records", None)[0])
    context.getLogger().info(f"bucket name: {bucket_name}, object key: {object_name}")
    ak = context.getAccessKey()
    sk = context.getSecretKey()
    server = 'obs.' + region_id + '.myhuaweicloud.com'
    obs_client = ObsClient(access_key_id=ak, secret_access_key=sk, server=server)

    # 获取对象
    object_content = obs_client.getObject(bucket_name, object_name, loadStreamInMemory=False)

    # 去掉 .gz 后缀
    new_object_name = object_name[:-3]
    # 重新上传
    resp = obs_client.putObject(bucket_name, new_object_name, content=object_content.body.response)
    # 设置元数据
    headers = SetObjectMetadataHeader(contentEncoding="gzip")
    obs_client.setObjectMetadata(bucket_name, new_object_name, headers=headers)

    context.getLogger().info("Upload Success")
    return


def get_obs_obj_info(record):
    if 's3' in record:
        s3 = record['s3']
        return record["eventRegion"], s3['bucket']['name'], unquote_plus(s3['object']['key'])
    else:
        obs_info = record['obs']
        return record["eventRegion"], obs_info['bucket']['name'], \
               unquote_plus(obs_info['object']['key'])

创建函数3.PNG

添加 OBS SDK 依赖包
创建函数4.PNG

创建函数5.PNG

3.2 创建工作流

进入 DWR 服务控制台,点击创建工作流

创建工作流.PNG

在左侧算子目录找到自定义,拖到中间添加连接线并在右侧选择函数,点击保存

创建工作流2.PNG

保存后会进入到工作流管理,点击创建触发器

创建工作流3.PNG

桶名选择静态网站托管的桶,事件源类型为 ObjectCreated,即任何上传行为均会触发,后缀填写 .gz,即只有压缩类型的文件才会触发。

创建工作流4.PNG

3.3 上传文件

重新在 Vue 项目根目录运行 npm run build 打包项目,这次不需要再去手动改后缀了,直接把打包后结果整个拖入到上传框点击上传

上传文档.PNG

4. 验证已开启 Gzip 压缩

配置完成后,再次访问静态网站地址,发现已经成功,分析请求响应内容也都是压缩后的

访问成功.PNG

【版权声明】本文为华为云社区用户原创内容,转载时必须标注文章的来源(华为云社区)、文章链接、文章作者等基本信息, 否则作者和本社区有权追究责任。如果您发现本社区中有涉嫌抄袭的内容,欢迎发送邮件进行举报,并提供相关证据,一经查实,本社区将立刻删除涉嫌侵权内容,举报邮箱: cloudbbs@huaweicloud.com
  • 点赞
  • 收藏
  • 关注作者

评论(0

0/1000
抱歉,系统识别当前为高风险访问,暂不支持该操作

全部回复

上滑加载中

设置昵称

在此一键设置昵称,即可参与社区互动!

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。