iT邦幫忙

第 11 屆 iT 邦幫忙鐵人賽

DAY 30
5
Modern Web

從 Hooks 開始,讓你的網頁 React 起來系列 第 30

[Day 30 - 臺灣好天氣] 發布上 Github Pages 不夠,還要變成手機 App!還有那些重要但故意先不告訴你的內容

昨天我們已經把「即時天氣 App」發佈到 Github Pages 上了並且正名為「臺灣好天氣」。

但是這類型的天氣 App 如果可以安裝到手機上的話有多好呢?

今天就讓我們來看看如何把「臺灣好天氣」變成一個可以下載到手機裝置上的 Web App 吧!最後會列出一些 「那些重要但故意不告訴你的內容」 。如此,這一系列 30 天的鐵人賽也就圓滿了!筆者也差不多可以來好好休息圓寂了!

Imgur

把網頁做成手機可安裝的 App!?

Progressive Web App (PWA) 中文稱作「漸進式網頁應用程式」,這是 Google 這幾年一直致力在推廣的網頁技術。第一次看到這個詞彙時就和我聽到 Application Programming Interface (API) 一樣一頭霧水。到底「漸進式」指的是什麼!?

簡單來說,PWA 在網頁的基礎上添加了許多功能,可以帶給使用者更好的瀏覽體驗,特別是在手機裝置上的感覺更佳明顯,讓使用者感覺上像是在開一個手機 App 而不是開啟網站。 PWA 的功能非常豐富,而漸進式的意思就是指你不用把這些功能一次全部到位,可以漸漸地一點一點加進去就可以。因為詳細的功能非常多,更多的說明可以參考 GoogleMDN 的文件。

把即時天氣 App 包成 PWA

當我們透過 Create React App 來建立 React 應用程式時,Create React App 已經幫我們把許多 PWA 需要使用的工具都已經放進去了,只是需要我們手動開啟它。

首先進到專案中的 ./src/index.js 這支檔案, 將 PWA 中的 Service Worker 功能打開,只需把原本的 serviceWorker.unregister() 改成 serviceWorker.register() 即可:

Imgur

Service Worker 算是在 PWA 中蠻核心的功能,它可以把網頁應用程式暫存(cache)下來,讓使用者下次點開的時候速度有感提升,並且可以讓這個網頁就像 App 一樣不用透過 App Store 就安裝在手機上,有需要的時候甚至可以在離線狀況下存取這個網站(但是當然就不能更新資料)。

下載 PWA 使用的圖示

因為現在可以讓使用者像是安裝 App 一樣,所以會需要使用到 App 的圖示,這些圖示同樣放在 Dropbox 上可供下載,在原本天氣圖示的檔案內,多了一個名為 app-icons 的資料夾,裡面放置了 App 需要用來顯示的圖示,把它們全部搬到 ./public/ 資料夾內:

Imgur

定義 PWA 的說明檔 - manifest.json

在這裏並不會用到太多其他的 PWA 功能,而是希望可以讓它看起來更像個原生的 App,並且可以下載到手機上使用。在專案建立好時 ./public 資料夾中已經有一支 manifest.json,這裡會定義和這個 PWA 有端的說明,讓瀏覽器知道下載下來時要使用什麼 Logo、顯示什麼顏色等等。

./public/manifest.json 中加入以下設定檔:

{
  "short_name": "臺灣好天氣",
  "name": "臺灣好天氣-即時縣市天氣",
  "icons": [
    {
      "src": "icon@x48.png",
      "type": "image/png",
      "sizes": "48 × 48"
    },
    {
      "src": "icon@96.png",
      "type": "image/png",
      "sizes": "96x96"
    },
    {
      "src": "icon@144.png",
      "type": "image/png",
      "sizes": "144x144"
    },
    {
      "src": "icon@192.png",
      "type": "image/png",
      "sizes": "192x192"
    },
    {
      "src": "icon@512.png",
      "type": "image/png",
      "sizes": "512x512"
    }
  ],
  "start_url": ".",
  "display": "standalone",
  "orientation": "portrait-primary",
  "theme_color": "#1f2022",
  "background_color": "#1f2022"
}

最後因為有些 PWA 的設定在 iOS 裝置上需要額外設定,因此我們需要把它們設定在 ./public/index.html 中:

<!-- ./public/index.html -->
<!DOCTYPE html>
<html lang="zh-Hant">
  <head>
    <meta charset="utf-8" />
    <link rel="shortcut icon" href="%PUBLIC_URL%/icon@48.png" />
    <meta
      name="viewport"
      content="width=device-width, initial-scale=1.0, user-scalable=1.0, minimum-scale=1.0, maximum-scale=1.0, shrink-to-fit=no"
    />
    <meta name="theme-color" content="#1f2022" />
    <link rel="manifest" href="%PUBLIC_URL%/manifest.json" />

    <!-- PWA settings for ios device -->
    <link rel="apple-touch-icon" href="%PUBLIC_URL%/icon@48.png" />
    <link
      rel="apple-touch-icon"
      sizes="96x96"
      href="%PUBLIC_URL%/icon@96.png"
    />
    <link
      rel="apple-touch-icon"
      sizes="144x144"
      href="%PUBLIC_URL%/icon@144.png"
    />
    <link
      rel="apple-touch-icon"
      sizes="192x192"
      href="%PUBLIC_URL%/icon@192.png"
    />
    <link
      rel="apple-touch-icon"
      sizes="512x512"
      href="%PUBLIC_URL%/icon@512.png"
    />
    <link rel="apple-touch-startup-image" href="%PUBLIC_URL%/launch.png" />
    <meta name="apple-mobile-web-app-title" content="臺灣好天氣" />
    <meta name="apple-mobile-web-app-capable" content="yes" />
    <meta name="apple-mobile-web-app-status-bar-style" content="#1f2022" />
    <meta name="description" content="臺灣好天氣-即時縣市天氣" />
    <title>臺灣好天氣-即時縣市天氣</title>
  </head>
  <body>
    <noscript>You need to enable JavaScript to run this app.</noscript>
    <div id="root"></div>
  </body>
</html>

發佈應用程式

當我們都做好設定後,一樣只需要在使用 npm 的指令就可以發布到 Github 上了:

# 在專案資料夾下
npm run deploy

安裝在電腦上

發佈完之後,當你用瀏覽器 Chrome 開啟台灣好天氣這個網站時,因為已經符合 PWA 的規範,所以會自動跳出提示來詢問使用者是否要安裝:

Imgur

安裝後就會出現在應用程式列表中:

Imgur

打開來就像一個原生的 App,但其實是包著 App 外皮的網頁:

Imgur

是不是看起來很棒啊!

安裝在手機上

同樣的,讓我們來看看手機的畫面。當手機進入到這個頁面時,瀏覽器同樣會偵測到有符合 PWA 的規範,因此會跳出下載的按鈕或提示:

Imgur

當我們把它安裝到手機後,它就像一般的手機 App 一樣,打開的時候會有一個漸變的啟動畫面,並且可以解除安裝:

Imgur

那些相當重要但故意先不告訴你的地方

終於完成 30 天這一系列鐵人賽的內容了,下面這些是我認為相當重要但故意先不告訴你的地方:

不希望你看完這 30 天的內容後就覺得學會了 React

說真的這只是個開始,我希望的是這 30 天的內容能讓你對 React 有一個概念,接著你就可以閱讀 React 的官方文件;我希望你能夠越來越習慣閱讀官方文件,未來不論你想要換到哪一個框架或學習其他語言,千萬不要忘了回頭閱讀官方文件,那通常會是最清楚詳細的

在 React 中過去多是用 class 在定義組件

在這 30 天中,我們都是使用函式來定義組件(Functional Components),因為 React Hooks 的功能讓我們可以把要做的事情都在 Functional Components 內完成;但在還沒有 React Hooks 前多數的組件都是用 class 定義的,因此若想看懂其他人寫的 React 程式碼,還是勢必要回頭補齊 Class-Components 的部分,這裡除了推薦 React 官方的 Getting Started之外,我認為 Codecademy 上也可以幫助你補齊這個部分。

在 React 中過去多是透過生命週期在不同時間點做事

如果你是在 React Hooks 之前就學過 React 的話,一定聽過「生命週期」這個東西,最常見的像是 componentDidMountcomponentDidUpdatecomponentWillUnmount,但在 React Hooks 之後,這些多能用 useEffect 替代,但生命週期的概念並不是不重要,而是如同第一天時所說的,有些時候過去學過的東西,反而會讓你學新事物的時候綁手綁腳,而現在是你可以在 React 的世界中自由探索學習的時候了!

不要被過去所認識的世界束縛你

這點說起來好像很容易,但平常我有在看手機版習慣,最常看到「從 iOS 跳到 Android」或從「Android 跳到 iOS」的使用者在抱怨:「為什麼我以為用 ooo 有這個功能,換過來 xxx 之後都沒有」。

可是多數時候,當你仔細去看使用者提出的問題後,會發現其實兩個系統都有相同或類似的功能,只是可能要在不同的地方才能找到。當你一直用原本的習慣想要去接觸新事物時,將會使得你窒礙難行,但若你可以用「新事物」的角度上網查一下,常常就會發現原來換過來後也有這個功能呀!好用!

上面這些話其實是在跟我自己說的,在學習的過程中,我常對於「能達到同樣功能但卻需要用不同方式」而感到厭煩。剛開始學網頁的時候,常會覺得 HTML, CSS, JavaScript 彼此三個不是活得好好的話,為什麼後來要出模板語言(Pug、Mustache、Handlebars、EJS)、為什麼後來要有 CSS 前處理器(SASS、SCSS、PostCSS)、為什麼要有前端框架,反正後來都還是編譯成 HTML, CSS 和 JavaScript 不是嗎?

在還沒有熟悉他們之前,的確會覺得「麻煩」,覺得「阿我就繼續用 ooo 就好了啊」!但實際上這些工具很多時候都是(當時)為了想要解決某些問題而生。想像過去的我若執著於功能都一樣,而繼續用原本單純的 HTML、CSS、JavaScript,那麼不只很難繼續進步,同時也無法體會到這些工具帶給我們的愉快感和成就感。

所以,不要害怕那些許許多多聽過、沒聽過的術語和詞彙,不懂的記下來,有需要找個時間再來弄懂它,就是這樣。不要被過去所認識的世界束縛你,一起共勉。

範例程式碼

今天的程式碼同樣已經發佈到 Github 上,可以根據你的需求去檢視不同 Commit 階段的程式碼,Have Fun!

參考資源


上一篇
[Day 29 - 即時天氣] 寫網頁就是要炫耀啊,不然要幹麻?發布上 Github Pages 吧!
系列文
從 Hooks 開始,讓你的網頁 React 起來30
1
阿展展展
iT邦研究生 3 級 ‧ 2019-10-16 23:23:07

恭喜完賽
/images/emoticon/emoticon64.gif

感動你的支持!!!

0
RURU Tseng
iT邦新手 5 級 ‧ 2019-10-16 23:37:13

恭喜完賽/images/emoticon/emoticon42.gif

謝謝~也恭喜你!!!

0
Howard
iT邦新手 5 級 ‧ 2019-10-16 23:42:02

賀賀賀!!!/images/emoticon/emoticon64.gif

Howard 的爬蟲是我第一個完整看完鐵人賽的系列文!!

0
tsuifei
iT邦新手 5 級 ‧ 2019-10-17 00:00:54

恭喜完賽!
剛開賽看到這個系列眼睛都亮起來,無奈也在趕賽,現在完賽,終於可以慢慢看這一系列了~
感謝帶來好文~

謝謝你~!!恭喜一起完賽!!

0
yhlyher
iT邦新手 5 級 ‧ 2019-10-22 16:28:58

終於懂什麼是PWA了!XD感謝感謝

哈哈!我這裡沒有用到太多 PWA 的用法拉!!更多的還是要看官方文件~!!

0
Enzo
iT邦新手 5 級 ‧ 2019-11-12 17:32:32

爬完30天,好文推推~~

我要留言

立即登入留言