,方便開發者管理緩存機制,也提高開發者的開發效率。
安裝
npm install –save-dev workbox-cli
設定指令
打開package.json
“scripts”: {
…
“generate-sw”: “workbox generate:sw”
},
新增一組指令碼generate-sw
現在就可以透過npm run generate-sw產生Service worker的檔案。
執行 npm run generate-sw
要快取的副檔名
Service Worker建置的路徑和檔名(注意不要取跟我們設定的service-worker.js同名不然會被取代)
要不要將這些設定儲存到設定檔
接著,就會自動產生Service worker的檔案了。
打開產生的Service Worker檔案
const fileManifest = [
{
“url”: “404.html”,
“revision”: “a4e2271d19eb1f6f93a15e1b7a4e74dd”
},
…
]
會看到根目錄底下,所有的資源都存在fileManifest的物件中,revision後面則是hash過的字串。
拉到最下面
const workboxSW = new self.WorkboxSW();
workboxSW.precache(fileManifest);
這邊建立一個Workbox Service Worker並且透過precache()將物件的資源全部快取起來,這就跟我們剛開始學快取的時候,載入網頁預先存取的快取效果一樣。
但現在產生的檔案是將所有資源都快取起來,這並不是我們期望的,
因此我們可以來改workbox-cli-config.js,當再跑產生檔案時,會根據這檔案設定的內容去產生Service Worker,上面我們選擇的設定都可以在此檔案中找到。
module.exports = {
“globDirectory”: “public\\”,
“globPatterns”: [
“**/*.{html,ico,json,js,css,JPG,PNG,png}”
],
“swDest”: “public/workbox-sw-v1.js”,
“globIgnores”: [
“..\\workbox-cli-config.js”
]
};
globDirectory是網站根目錄的位置
globPatterns內容放要快取的檔案格式
swDest檔案輸出的位置
globIgnores不放入快取名單的資源
設定客製預先快取的內容
module.exports = {
“globDirectory”: “public\\”,
“globPatterns”: [
“**/*.{html,ico,json,js,css}”,
“src/images/*.{jpg,JPG,png,PNG}”
],
“swDest”: “public/workbox-sw-v1.js”,
“globIgnores”: [
“..\\workbox-cli-config.js”,
“aboutUs/**”
]
};
稍微修改了一下globPatterns,原本會尋訪所有網站資料夾底下所有的圖檔,現在限定在src/images/資料夾底下的圖檔才快取
另外,globIgnores中加入aboutUs/資料夾底下的內容先不快取起來。
這時候問題來了,
假如原本Service Worker裡面有寫很多監聽事件,那麼現在透過設定檔產生新的Service Worker,好不容易寫好的程式不就被覆蓋了嗎?
將常用的Service Worker程式抽離
Step1: 建立新的檔案
在此建立service-worker-base.js命名隨意,這檔案會放置我們不想被覆蓋的程式。
Step2: 修改package.json
原本指令是使用workbox generate:sw,但此方法會產生一個新的檔案,
因此要改成inject:manifest藉由注入的方式合併檔案。
“scripts”: {
…
“generate-sw”: “workbox inject:manifest”
}
Step3: 修改service-worker-base.js
importScripts(‘workbox-sw.prod.v2.1.2.js’);
const workboxSW = new self.WorkboxSW();
workboxSW.precache([]);
將自動產生的service worker檔案中,使用到的檔案,和precache語法貼過來。
Step4: 修改config檔
module.exports = {
…
“swSrc”: “public/service-worker-base.js”,
…
};
設定swSrc告知要注入的檔案是哪一個。
Step5: npm run generate-sw
importScripts(‘workbox-sw.prod.v2.1.2.js’);
const workboxSW = new self.WorkboxSW();
workboxSW.precache([
{
“url”: “404.html”,
“revision”: “a4e2271d19eb1f6f93a15e1b7a4e74dd”
}
]);
執行完後,預先快取的內容正確的注入到precahce([])的陣列中。
接著處理完預先快取,那麼動態快取呢?
處理動態快取資源
//https://firebasestorage.googleapis.com/v0/b/days-pwas-practice.appspot.co
//https://fonts.gstatic.com/s/materialicons/v34/2fcrYFNaTjcS6g4U3t-Y5ZjZjT5FdEJ140U2DJYC3mY.woff2
workboxSW.router.registerRoute(/.*(?:googleapis|gstatic)\.com.*$/, workboxSW.strategies.staleWhileRevalidate({
cacheName: ‘fonts-and-firebase-images’
}));
在該專案中,我們引外用來資源的有兩個url,
藉由workboxSW.router.registerRoute(‘url規則’,要做的事情)可以去比對網址,當符合googleapis.com
或gstatic.com
兩個網址時,就進入後面的workboxSW.strategies.staleWhileRevalidate(),如同fetch到上述兩種網址時,就將資源放入fonts-and-firebase-images中。
npm run generate-sw
替換一下原本使用的Service worker,重整網頁後,會發現跟原本fetch資源後,的動態快取效果一樣。
在fetch監聽事件中,我們撰寫過,底下將文章寫入資料庫的程式。
var url = ‘https://days-pwas-practice.firebaseio.com/article.json
‘;
if(-1 < event.request.url.indexOf(url)){
event.respondWith(
fetch(event.request)
.then(function(response){
var copyRes = response.clone();
clearAllData(‘article’)
.then(function(){
return copyRes.json();
})
.then(function(data){
console.log(‘copyRes.json()’,data);
for(var key in data){
console.log(‘key’,key);
writeData(‘article’,data[key]);
}
});
return response;
})
);
}
我們可以很簡單的移植這段程式,到workbox的程式碼中,如下
workboxSW.router.registerRoute(‘https://days-pwas-practice.firebaseio.com/article.json
‘, function(args){
return fetch(args.event.request)
.then(function(response){
var copyRes = response.clone();
clearAllData(‘article’)
.then(function(){
return copyRes.json();
})
.then(function(data){
console.log(‘copyRes.json()’,data);
for(var key in data){
console.log(‘key’,key);
writeData(‘article’,data[key]);
}
});
return response;
})
}
);
前面的參數放入url,當fetch到該網址時,則進入此功能(handleFetch),
裡面的功能根原本一樣,一樣能透過event.request捕抓到資源,並達到原本要做的事情。
转载请注明:XAMPP中文组官网 » Day29-Workbox Tool