漸進式網頁應用程式:使用工作人員

1. 歡迎

在本實驗室中,您將使用現有的網頁應用程式,並新增網頁工作站,在兩個開啟的視窗之間共用狀態。這是漸進式網頁應用程式研討會的一系列隨附程式碼研究室中的第八個。先前的程式碼研究室是「Service Worker Includes」。這是本系列程式碼研究室的最後一個。

課程內容

  • 在多個開啟的視窗之間新增共用工作站
  • 使用 Comlink 簡化 worker 的工作

注意事項

  • JavaScript

軟硬體需求

2. 開始設定

首先,請複製或下載完成本程式碼研究室所需的範例程式碼:

如果複製存放區,請確認您位於 pwa06--working-with-workers 分支版本中。ZIP 檔案也包含該分支版本的程式碼。

這個程式碼集需要 Node.js 14 以上版本。取得程式碼後,請在程式碼資料夾中從指令列執行 npm ci,安裝所有需要的依附元件。接著執行 npm start,啟動本程式碼研究室的開發伺服器。

原始碼的 README.md 檔案會說明所有發布的檔案。此外,您在本程式碼研究室中會使用下列主要現有檔案:

金鑰檔案

  • js/preview.js - 預覽頁面 JavaScript 檔案
  • js/main.js - 主要應用程式 JavaScript 檔案

3. 編寫 Worker

目前,網頁應用程式的預覽功能只會在載入時顯示最新內容。理想情況下,使用者輸入內容時,系統會顯示即時預覽畫面。這需要編譯大量資料,並在兩個不同的開啟視窗之間傳輸。因此,我們不希望在任何開啟視窗的主執行緒上執行這項作業。請改用共用網頁工作人員。

首先,請使用下列程式碼建立 js/worker.js 檔案:

import { expose } from 'comlink';
import { marked } from 'marked';

class Compiler {
  state = {
    raw: '',
    compiled: '',
  };
  subscribers = [];

  async set(content) {
    this.state = {
      raw: content,
      compiled: marked(content),
    };

    await Promise.all(this.subscribers.map((s) => s(this.state)));
  }

  subscribe(cb) {
    this.subscribers.push(cb);
  }
}

const compiler = new Compiler();

onconnect = (e) => expose(compiler, e.ports[0]);

說明

這段程式碼會設定名為 Compiler 的類別,可設定內容,並在編譯內容後呼叫訂閱項目。由於這是共用工作站,因此只能使用這個類別的單一執行個體,因此會例項化 Compiler 的新執行個體。接著,為了讓從工作站外部使用這個類別時感覺順暢,我們使用 Comlink 公開編譯器例項,讓我們能使用其中的所有方法,就像是在使用這些方法的程式碼中宣告一樣。由於這是共用工作站,而非專屬工作站,因此必須向所有連線公開。

4. 將內容傳送給 Worker

建立工作站後,我們現在需要將內容傳送至工作站。如要這麼做,請更新 js/main.js 以執行下列操作:

  • comlink 匯入具名匯出項目 wrap
  • 建立名為 worker 的新模組類型 Shared Worker,將其類型設為 module,然後使用 new URL 模式 (new URL('./worker.js', import.meta.url)) 指向該模組
  • 建立 compiler 變數,將 wrap 設為 worker.port
  • 在編輯器的更新函式 (editor.onUpdate) 中,將內容儲存到資料庫後,請等待 compiler.set 完成,並傳入內容

說明

包裝 Comlink 匯出內容後,公開的類別方法就能像未跨工作人員界線共用一樣使用,但現在所有內容都是非同步。由於這是共用工作站,而非專屬工作站,因此 Comlink 需要包裝工作站的埠,而非工作站本身。現在,每當編輯器更新時,內容就會傳送至工作站進行處理!

5. 更新預覽頁面

最後一個步驟是將編譯的內容從共用工作站移至預覽畫面!設定方式大致相同,但由於函式無法在工作人員界線之間傳遞,因此必須改用函式的 Proxy。Comlink 再次派上用場。更新 js/preview.js 以執行下列操作:

  • comlink 匯入具名匯出項目 wrapproxy
  • 建立並包裝共用工作站,做法與 js/main.js 相同
  • 使用 Proxy 函式呼叫編譯器的 subscribe 方法,將傳入資料的 compiled 屬性設為預覽區域的內部 HTML

完成後,開啟預覽畫面,在編輯器中開始輸入內容,您會發現 Markdown 會自動編譯並即時顯示在預覽區域中,而且不會封鎖任何頁面的主要執行緒!

6. 恭喜!

您已學會如何使用共用 Worker 在多個 PWA 執行個體之間共用狀態。