記一次基於react、cra2、typescript的pwa專案由開發到部署(一)

holyZhengs發表於2018-10-29

titleimage

上一篇“記錄一次基於vue、typescript、pwa的專案由開發到部署”,釋出後,忙於秋招的樓主我,終於有時間來寫這篇文章。最近秋招也挺順利,拿到了網易廣州崗的offer,對目前想留在廣州發展的我來說真是太合適不過了。在最近的反思中,樓主我也意識到了自己存在過於急功近利的毛病,前端是一個更新迭代很快的行業,最忌諱的就是浮躁的心態,所以樓主決定要好好調整自己,要有工匠精神和延時滿足的意識。以後的文章也要好好調整,儘可能的寫細寫好。

下面進入正題,本篇文章介紹如何基於目前的create-react-app(目前的專案cra版本為2.0.3)利用workbox開發一款pwa,並將其釋出到自己的伺服器。

為什麼要做這個專案?

  1. 因為pwa已經是家喻戶曉的概念了
  2. create-react-app2 提供了對pwa的支援
  3. cra2釋出後,基於cra2開發pwa的文章較少
  4. 對react技術棧實踐練手
  5. 搞事情

先來說一下專案,這次的專案和上一篇基於vue的專案是同一個專案,可以說是用react的重構,用途是用來瀏覽學校心理學院部分實驗資訊,因為樓主用vue較多,所以這個專案也是react的練手專案,為了多實踐,專案中還用到了react-redux去進行狀態管理(專案引入redux的目的只是為了實踐),react-router進行路由控制。看一下效果:

bereactshow

可以看到,我們從手機桌面的一級入口,在斷網的條件下,依舊絲滑的開啟了app,而且帶有過渡動畫,並正常的訪問了實驗資料,這就是pwa,擁有原生app般的體驗,又擁有web的輕便。下面我們來看看,如何基於create-react-app2與workbox如何實現這個專案。

cra2 給我們帶來了什麼pwa特性?

note:部分連結需要梯子

我們的專案是基於 create-react-app 2 ,cra2提供了對pwa的支援,可以讓我們可選的將我們的app 升級為 pwa。 關於cra2新增的新特性,可以在這裡看what's new about cra2,看一下目前cra2到底提供了什麼關於pwa的支援。首先我們利用cra2生成一個專案,:

npx create-react-app my-app
複製程式碼

可以看到在src檔案目錄下有一個serviceWorker.js檔案,這個檔案看起來很複雜,其實就是檢查一下環境變數是否為“production”,且當前瀏覽器是否相容service worker。 再來看一下我們的 index.js 檔案,可以看到最後面有一句:

serviceWorker.unregister();
複製程式碼

如果我們想要使用cra2提供的pwa特性的話,我們需要將 serviceWorker.unregister() 改為 serviceWorker.register(),然後我們打包我們的專案,在打包得到的build資料夾下我們可以看到生成了一個server-worker.js檔案 和 preche-manifest.xxxxxxxxx.js 和一個manifest.json。

其中的server-worker.js中規定了我們如何快取我們的資源,preche-manifest 中列出了我們的靜態資源 利用上一篇關於vue-cli 和pwa 中提到的web server工具 web-server-for-chrome

web server
為我們打包得到的build資料夾下的程式碼建一個服務並訪問。 然後開啟chrome控制檯的Application檢視,發現它幫助我們快取了我們的靜態檔案。

react-default-pwa

我們把網斷開,可以發現,我們的app依舊能正常開啟。這就是目前的cra2(2.0.3)給我們提供的預設的pwa特性。預設的為我們生成一個service-worker.js快取我們的app shell,使得它可以在離線時正常的開啟。

限制性

這足夠了嗎?很明顯是不夠的。在實際情況中,除了快取我們的app shell,我們往往需要動態的對我們的路由和請求的資料進行快取,這本來是一件很正常的事情,也就是說,我們需要去定製自己的servive worker去實現自己想要的功能。

但是在目前的cra2中,並沒有提供這麼一個方式讓我們去定製自己的service-worker,除非你eject我們的專案,將所以的配置檔案暴露出來,但是eject是一個不可逆的過程,將我們的配置檔案暴露出來也是一個不優雅的做法。所以我們需要另開途徑來實現我們的需求。

為什麼 create-react-app 沒提供定製service worker 的方法?

其實並不是cra2不提供相應的定製方法,目前cra2 也在準備實現相應的功能,我們可以看一下下面幾個issue或request。

  1. Custom ServiceWorker config #2237 開發者huygn提出在create-react-app支援pwa後是否能夠讓開發者自定義相關配置

issueCustomPwa

但是react.js的工作人員gaearon迴應短期內沒有此打算,未來或許會實現該想法,並關閉了此issue。

responseForCustomPwa

  1. Import scripts in Service Worker #2714 開發者piotr-cz提出了一個方案,給create-react-app提了一個request,為當時create-react-app所使用的SWPrecacheWebpackPlugin外掛提供一個importScripts選項,可以讓我們在專案的public目錄下定製自己的service worker

requestForCustomPwa

但是最終還是被create-react-app的合作作者Timer關閉了這個request,因為有開發者提出了更合理的實現方式

responseForRequest

  1. Workbox service worker #4169 開發者davejm 提出了更合理的方案,並且被採納。davejm 提議將sw-precache-webpack-plugin換成Workbox webpack plugin,並提供對應的配置檔案。

requestForWorkbox

從這些資料中可以看到,在將來,我們或許就可以像在vue-cli3.0中一樣定製自己service worker了,配置的方式便是在根目錄下建立 cra.config.js檔案,然後寫入類似下面的配置程式碼:

module.exports = {
  workbox: {
    method: 'inject',
    config: {
      swSrc: 'src/my-custom-service-worker.js'
    }
  }
}
複製程式碼

這裡不得不感嘆一下react社群的力量。

現在怎麼辦?

既然目前還沒有提供定製service worker的方法,那麼我們應該怎麼做呢?關於如何實現這個app:

  1. 在現階段基於create-react-app的專案中,如何利用workbox自定義自己的service worker。
  2. 如何編寫service worker檔案以快取我們的靜態檔案和請求的資料
  3. 如何部署我們的專案到自己的伺服器上,享受pwa的快感

樓主打算在下一篇文章中給大家介紹,因為樓主發現與其長篇大論把所有內容都放在同一篇文章,不如分開幾篇細細的講要有效果。

感興趣的同學可以掃描下面二維碼體驗專案:

note:

  1. 建議用uc瀏覽器開啟,因為uc瀏覽器對pwa的支援較好。
  2. "新增到桌面的提示" 需要短時間多次進入web app 才會觸發

qrcode

專案地址:browseExpByReact

如果感興趣,可以對比著基於vue的實現來看: browseExpByVue

相關文章