تطبيق ويب تقدمي
تطبيقات الويب التقدمية (أو PWAs) هي تطبيقات ويب تقدم تجربة مشابهة للتطبيقات الأصلية. هناك عوامل كثيرة قد تساهم في ذلك، وأهمها قدرة التطبيق على العمل عند انقطاع الاتصال. يتحقق ذلك باستخدام تقنية ويب تُسمى Service Workers.
سيركز هذا القسم على إضافة تجربة عمل دون اتصال إلى تطبيقنا. سنحقق ذلك باستخدام مشروع من Google باسم Workbox، وهو يوفر أدوات تساعد على تسهيل إعداد دعم العمل دون اتصال لتطبيقات الويب.
لا نعمل دون اتصال حاليًا
حتى الآن، كنا نعرض المخرجات بالوصول مباشرة إلى نظام الملفات المحلي. لكن عادةً يصل المستخدم الحقيقي إلى تطبيق الويب عبر الشبكة؛ حيث يتواصل المتصفح مع خادم يقدّم الملفات المطلوبة (مثل ملفات .html و .js و .css).
لذلك دعنا نختبر التجربة الحالية باستخدام خادم بميزات أساسية. سنستخدم حزمة http-server: npm install http-server --save-dev. سنعدّل أيضًا قسم scripts في ملف package.json لإضافة سكربت start:
package.json
{
...
"scripts": {
- "build": "webpack"
+ "build": "webpack",
+ "start": "http-server dist"
},
...
}ملاحظة: يكتب webpack DevServer في الذاكرة افتراضيًا. سنحتاج إلى تفعيل خيار devserverdevmiddleware.writeToDisk حتى يتمكن http-server من خدمة الملفات من مجلد ./dist.
إذا لم تكن قد فعلت ذلك سابقًا، فنفّذ الأمر npm run build لبناء مشروعك. ثم نفّذ الأمر npm start. ينبغي أن ينتج عن ذلك المخرجات التالية:
> http-server dist
Starting up http-server, serving dist
Available on:
http://xx.x.x.x:8080
http://127.0.0.1:8080
http://xxx.xxx.x.x:8080
Hit CTRL-C to stop the serverإذا فتحت المتصفح على http://localhost:8080 (أي http://127.0.0.1) فينبغي أن ترى تطبيق webpack يُخدم من مجلد dist. إذا أوقفت الخادم ثم حدّثت الصفحة، فلن يكون تطبيق webpack متاحًا بعد ذلك.
هذا ما نهدف إلى تغييره. عند الوصول إلى نهاية هذا القسم، ينبغي أن نتمكن من إيقاف الخادم، ثم تحديث الصفحة، ومع ذلك سنظل نرى تطبيقنا.
إضافة Workbox
لنضف ملحق Workbox الخاص بـ webpack ونعدّل ملف webpack.config.js:
npm install workbox-webpack-plugin --save-devwebpack.config.js
import path from "node:path";
import { fileURLToPath } from 'node:url';
import HtmlWebpackPlugin from "html-webpack-plugin";
+ import WorkboxPlugin from "workbox-webpack-plugin";
const __filename = fileURLToPath(import.meta.url);
const __dirname = path.dirname(__filename);
export default {
entry: {
app: './src/index.js',
print: './src/print.js',
},
plugins: [
new HtmlWebpackPlugin({
- title: 'Output Management',
+ title: 'Progressive Web Application',
}),
+ new WorkboxPlugin.GenerateSW({
+ // تشجع هذه الخيارات ServiceWorkers على العمل سريعًا
+ // ولا تسمح لأي SWs "قديمة" متأخرة بالبقاء
+ clientsClaim: true,
+ skipWaiting: true,
+ }),
],
output: {
filename: '[name].bundle.js',
path: path.resolve(__dirname, 'dist'),
clean: true,
},
};بعد ذلك، لنرَ ما يحدث عند تنفيذ npm run build:
...
Asset Size Chunks Chunk Names
app.bundle.js 545 kB 0, 1 [emitted] [big] app
print.bundle.js 2.74 kB 1 [emitted] print
index.html 254 bytes [emitted]
precache-manifest.b5ca1c555e832d6fbf9462efd29d27eb.js 268 bytes [emitted]
service-worker.js 1 kB [emitted]
...كما ترى، أصبح لدينا الآن ملفان إضافيان يتم توليدهما: service-worker.js والملف الأطول اسمًا precache-manifest.b5ca1c555e832d6fbf9462efd29d27eb.js. ملف service-worker.js هو ملف Service Worker، أما precache-manifest.b5ca1c555e832d6fbf9462efd29d27eb.js فهو ملف يحتاجه service-worker.js حتى يعمل. غالبًا ستكون الملفات المولّدة لديك مختلفة، لكن ينبغي أن تجد ملف service-worker.js هناك.
إذن وصلنا الآن إلى مرحلة إنتاج Service Worker. ما الخطوة التالية؟
تسجيل Service Worker الخاص بنا
لنسمح لـ Service Worker بالعمل عبر تسجيله. سنفعل ذلك بإضافة كود التسجيل التالي:
index.js
import _ from 'lodash';
import printMe from './print.js';
+ if ('serviceWorker' in navigator) {
+ window.addEventListener('load', () => {
+ navigator.serviceWorker.register('/service-worker.js').then(registration => {
+ console.log('SW registered: ', registration);
+ }).catch(registrationError => {
+ console.log('SW registration failed: ', registrationError);
+ });
+ });
+ }نفّذ npm run build مرة أخرى لبناء نسخة من التطبيق تتضمن كود التسجيل. ثم اخدمها باستخدام npm start. انتقل إلى http://localhost:8080 وألقِ نظرة على وحدة التحكم. ينبغي أن ترى في مكان ما:
SW registeredوالآن لنختبر ذلك. أوقف الخادم وحدّث الصفحة. إذا كان متصفحك يدعم Service Workers، فينبغي أن تظل ترى تطبيقك. لكنه هذه المرة تم تقديمه بواسطة Service Worker الخاص بك وليس بواسطة الخادم.
الخاتمة
لقد بنيت تطبيقًا يعمل دون اتصال باستخدام مشروع Workbox. وبدأت رحلة تحويل تطبيق الويب الخاص بك إلى PWA. قد ترغب الآن في التفكير في خطوات أبعد. يمكنك العثور على مورد جيد يساعدك في ذلك هنا.



