1. שלום
במעבדה הזו, תוסיפו web worker לאפליקציית אינטרנט קיימת כדי לשתף את הסטטוס בין שני חלונות פתוחים. זוהי הסדנה השמינית בסדרת סדנאות קוד שנועדו ללוות את סדנת Progressive Web App. ה-codelab הקודם היה Service Worker Includes. זהו ה-codelab האחרון בסדרה.
מה תלמדו
- הוספת SharedWorker בין כמה חלונות פתוחים
- שימוש ב-Comlink כדי לעבוד עם עובדים בקלות רבה יותר
מה חשוב לדעת
- JavaScript
מה צריך
- דפדפן שתומך בעובדי אינטרנט משותפים
2. טיפים להגדרה
כדי להתחיל, משכפלים או מורידים את הקוד לתחילת הדרך שנדרש להשלמת ה-Codelab הזה:
אם משכפלים את המאגר, חשוב לוודא שנמצאים בהסתעפות pwa06--working-with-workers
. קובץ ה-ZIP מכיל גם את הקוד של הענף הזה.
בסיס הקוד הזה דורש Node.js בגרסה 14 ומעלה. אחרי שהקוד זמין, מריצים את הפקודה npm ci
משורת הפקודה בתיקיית הקוד כדי להתקין את כל התלויות שצריך. לאחר מכן, מריצים את הפקודה npm start
כדי להפעיל את שרת הפיתוח של ה-codelab.
קובץ README.md
של קוד המקור מספק הסבר לכל הקבצים המופצים. בנוסף, אלה הקבצים הקיימים העיקריים שתעבדו איתם במהלך ה-codelab הזה:
קבצים חשובים
-
js/preview.js
– תצוגה מקדימה של קובץ JavaScript של הדף -
js/main.js
– קובץ JavaScript של האפליקציה הראשית
3. כתיבת Worker
בשלב הזה, פונקציונליות התצוגה המקדימה של אפליקציית האינטרנט מציגה רק את התוכן העדכני ביותר בזמן הטעינה. הכי טוב יהיה להציג תצוגה מקדימה בזמן אמת בזמן שהמשתמש מקליד. לשם כך צריך לקמפל כמויות גדולות של נתונים ולהעביר אותם בין שני חלונות פתוחים שונים. לכן, אנחנו לא רוצים לבצע את הפעולה הזו בשרשור הראשי של אף אחד מהחלונות הפתוחים. במקום זאת, נשתמש ב-Web 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
, שמאפשרת להגדיר תוכן ולאפשר קריאה למינויים אחרי שהתוכן עובר קומפילציה. מכיוון שמדובר ב-worker משותף, צריך להשתמש רק במופע אחד של המחלקה הזו, ולכן נוצר מופע חדש של Compiler
. לאחר מכן, כדי שהעבודה עם המחלקה הזו תהיה חלקה מחוץ ל-worker, נעשה שימוש ב-Comlink כדי לחשוף את מופע הקומפיילר, וכך אפשר להשתמש בכל השיטות שבו כאילו הוא הוגדר בקוד שמשתמש בו. מכיוון שמדובר ב-worker משותף ולא ב-worker ייעודי, הוא צריך להיות חשוף לכל החיבורים.
4. שליחת תוכן לעובד
אחרי שיצרנו את ה-Worker, אנחנו צריכים לשלוח אליו תוכן. כדי לעשות זאת, מעדכנים את js/main.js
כך שיבצע את הפעולות הבאות:
- ייבוא של הייצוא בעל השם
wrap
מ-comlink
- יוצרים Shared Worker חדש מסוג מודול בשם
worker
, מגדירים את הסוג שלו ל-module
ומפנים אליו באמצעות התבניתnew URL
(new URL('./worker.js', import.meta.url)
) - יוצרים משתנה
compiler
שwrap
מייצג אתworker.port
- בפונקציית העדכון של העורך (
editor.onUpdate
), אחרי ששומרים את התוכן במסד הנתונים, מחכים עד ש-compiler.set
יסיים את הפעולה, ומעבירים את התוכן
הסבר
כשעוטפים ייצוא של Comlink, אפשר להשתמש בדברים כמו שיטות של מחלקות חשופות כאילו הם לא שותפו בין גבולות של Worker, למעט העובדה שעכשיו הכול אסינכרוני. מכיוון שמדובר ב-worker משותף ולא ב-worker ייעודי, Comlink צריך לעטוף את הפורט של ה-worker ולא את ה-worker עצמו. מעכשיו, בכל פעם שמתבצע עדכון בעורך, התוכן יישלח אל העובד כדי שיטפל בו.
5. עדכון דף התצוגה המקדימה
השלב האחרון הוא להוציא את התוכן שעבר קומפילציה מה-shared worker אל התצוגה המקדימה. ההגדרה של הפונקציה הזו דומה מאוד, אבל מכיוון שאי אפשר להעביר פונקציות בין גבולות של Worker, צריך להשתמש במקום זאת ב-proxy של הפונקציה. שוב, Comlink כאן כדי לעזור. צריך לעדכן את js/preview.js
כדי לבצע את הפעולות הבאות:
- ייבוא של הייצואים בעלי השם
wrap
ו-proxy
מ-comlink
- יוצרים את העובד המשותף ועוטפים אותו כמו שמתואר ב
js/main.js
- מפעילים את השיטה
subscribe
של הקומפיילר עם פונקציית proxy שמגדירה את המאפייןcompiled
של הנתונים הנכנסים ל-HTML הפנימי של אזור התצוגה המקדימה
אחרי שמסיימים, פותחים את התצוגה המקדימה, מתחילים להקליד בעורך ונהנים לראות את קובץ ה-Markdown מתקמפל באופן אוטומטי ומופיע בזמן אמת באזור התצוגה המקדימה, בלי לחסום את השרשור הראשי של אף אחד מהדפים.
6. מעולה!
למדתם איך להשתמש ב-Shared Worker כדי לשתף מצב בין כמה מופעים של PWA.