本文分享自華為雲社群《将 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
2. 開啟靜态網站托管并上傳網站
2.1 建立桶并開啟靜态網站托管
進入對象存儲控制台,點選右上角建立桶。
這裡桶名需要注意下,全局唯一,不能與其他人的重複,桶政策選擇公共讀
注意:開啟公共讀後,任何人均能通路你桶内的資料!!強烈建議這個桶僅用作靜态網站托管,不要存放隐私資料
注意:開啟公共讀後,任何人均能通路你桶内的資料!!強烈建議這個桶僅用作靜态網站托管,不要存放隐私資料
注意:開啟公共讀後,任何人均能通路你桶内的資料!!強烈建議這個桶僅用作靜态網站托管,不要存放隐私資料
建立後點選桶名,進入桶配置,點選靜态網站托管,配置靜态網站
此處示例項目比較簡單,預設首頁和預設 404 頁面均填寫 index.html,不需要配置重定向規則
這個網址即是網站位址
此時點選打開會提示 404,因為我們還沒有上傳網站檔案,接下來會上傳網站檔案并配置 Gzip 壓縮。
2.1.2 配置域名解析
在配置靜态網站時,可以看到有提示從 22 年 3 月開始 OBS 禁止通過預設域名(桶通路域名或靜态網站通路域名)使用靜态網站托管功能。如果是新建立的桶,必須要配置桶域名才能通路。
點選左側域名管理,點選綁定使用者域名
設定完成後,需要去自己的域名供應商處将域名 CNAME 指向 OBS 桶域名,等待一會兒解析生效。
2.2 上傳靜态網站并配置 Gzip 壓縮
這裡先講兩個錯誤步驟和錯誤的原因原因,太長不看可跳轉 # 2.2.2 正确方案 ,更推薦直接參考 # 3 更進一步--自動設定中繼資料
2.2.1 試錯手動方案
由于對象存儲的對象名強唯一的,即并不會自動把 xxx.js 指向 xxx.js.gz,此時如果直接把 dist 目錄下檔案上傳到對象存儲并開啟靜态網站托管,會發現浏覽器找不到 .gz 檔案,會報錯 404,頁面一片空白。
手動版解決方法非常粗暴,直接上傳前把檔案名字尾 .gz 去掉再上傳就行,這裡需要記下來都改了哪些檔案的字尾,一會兒要用到。
去除字尾後,請求沒報錯 404 了,但是頁面還是一片空白,這又是為啥?
原因是浏覽器是根據伺服器發來的請求頭來判斷收到的檔案到底是什麼類型,再決定該如何處理,如果内容被壓縮了,就必須要顯示的告訴浏覽需要解壓後才能使用。Nginx 配置後,會自動給響應加上說明告知浏覽器,但是對象存儲不會主動告知,需要我們處理。
手動處理方法也很粗暴,挨個去設定中繼資料添加 Content-Encoding: gzip,此處使用 OBS Browser+ 工具,浏覽器操作類似。
2.2.2 正确方案
- 手動将所有對象的 .gz 字尾去掉
- 挨個去給去過字尾的對象添加中繼資料:Content-Encoding: gzip
3. 更進一步 —— 自動設定中繼資料
本文用的示例項目比較簡單,隻有三個檔案需要改,手工改還不麻煩,但是對與複雜項目可能要幾十上百個檔案,處理起來就非常麻煩,程式員的思路就是能代碼解決就不要動手,這裡我們使用 資料工坊 DWR 服務自動改檔案名 + 改字尾。這裡的介紹比較簡單,如果想使用 DWR 進行更為複雜的操作,可以參考這篇博文對象存儲隻能按檔案名搜尋? 用 DWR + ElasticSearch 實作檔案名、檔案内容、圖檔文字的模糊搜尋!-雲社群-華為雲
3.1 建立函數
首先進入 FunctionGraph 服務,建立一個修改檔案名和中繼資料的 Serverless 函數。記得切換下 region,選擇目标 OBS 桶所在 Region。
函數内容為
# -*- 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'])
添加 OBS SDK 依賴包
3.2 建立工作流
進入 DWR 服務控制台,點選建立工作流
在左側算子目錄找到自定義,拖到中間添加連接配接線并在右側選擇函數,點選儲存
儲存後會進入到工作流管理,點選建立觸發器
桶名選擇靜态網站托管的桶,事件源類型為 ObjectCreated,即任何上傳行為均會觸發,字尾填寫 .gz,即隻有壓縮類型的檔案才會觸發。
3.3 上傳檔案
重新在 Vue 項目根目錄運作 npm run build 打包項目,這次不需要再去手動改字尾了,直接把打包後結果整個拖入到上傳框點選上傳
4. 驗證已開啟 Gzip 壓縮
配置完成後,再次通路靜态網站位址,發現已經成功,分析請求響應内容也都是壓縮後的
點選下方,第一時間了解華為雲新鮮技術~
華為雲部落格_大資料部落格_AI部落格_雲計算部落格_開發者中心-華為雲