استخدام Workbox بدون تخزين مؤقت مسبق

حتى الآن، لاقت هذه المستندات أهمية كبيرة في ما يتعلّق بالتخزين المؤقت، وغالبًا ما تتناول أدوات إنشاء generateSW وinjectManifest. على الرغم من وجود الكثير من الأسباب الوجيهة لتضمين منطق التخزين المؤقت المسبق في عامل الخدمة، ليس عليك استخدام التخزين المؤقت لاستخدام Workbox.

ربما يحتاج مشروعك فقط إلى التخزين المؤقت في وقت التشغيل، أو ربما تريد طريقة أوضح لدمج واجهات برمجة تطبيقات مشغّلي الخدمات، مثل web Push. هذه هي الحالات التي لن تحتاج فيها إلى استخدام أدوات إصدار Workbox، وهذا ما تتناوله هذه المقالة.

عند استخدام حزمة

تعتبر برامج الحزم بارزة في مجال تطوير الويب، ومن المحتمل أن يستخدم مشروعك أحد هذه الحزم. وفي هذه الحالة، من المهمّ معرفة أنّك لن تحتاج إلى استخدام مكوّن إضافي للحِزم (مثل workbox-webpack-plugin) إذا لم تكن تُخزَّن مسبقًا في أي وقت. ستتعامل مع عامل الخدمة كنقطة إدخال منفصلة في طلبك.

في جذر دليل المصدر لمشروعك، عليك إنشاء مشغّل خدمات واستخدام أي وحدات Workspace التي يتطلبها تطبيقك. في ما يلي مثال يتم فيه إعداد استراتيجيات التخزين المؤقت للانتقال وطلبات مواد عرض الصور في حالات Cache منفصلة بدلاً من ذلك، بدون الحاجة إلى التخزين المؤقت:

// sw.js
import {NetworkFirst, CacheFirst} from 'workbox-strategies';
import {registerRoute, NavigationRoute, Route} from 'workbox-routing';

const navigationRoute = new NavigationRoute(new NetworkFirst({
  cacheName: 'navigations'
}));

const imageAssetRoute = new Route(({request}) => {
  return request.destination === 'image';
}, new CacheFirst({
  cacheName: 'image-assets'
}));

registerRoute(navigationRoute);
registerRoute(imageAssetRoute);

من هنا، تكون مسألة تحديد عامل الخدمة هذا كنقطة دخول في الحزمة التي تختارها. في ما يلي بعض الأمثلة على كيفية إجراء ذلك في بعض الحزم الشائعة.

حزمة ويب

تقبل webpack نقاط الدخول في إعدادات entry. وهناك بعض الأمور التي يجب أن تكون على دراية بها عند استخدام هذا المنهج:

  1. لضمان توفُّر مشغّل الخدمات على أوسع نطاق ممكن، ستحتاج إلى عرضه في جذر دليل الإخراج.
  2. لست بحاجة إلى إصدار نسخة من مشغّل الخدمات، لأنّ التحديثات التي تُجرى على مشغّل الخدمة ستعمل على إنشاء علامات تجزئة جديدة قد تؤدي إلى نشر العديد من عاملي الخدمة على موقعك الإلكتروني.

لاستيفاء الشروط المذكورة أعلاه، يمكن تمرير دالة إلى output.filename والتي تتحقّق مما إذا كانت نقطة الدخول الحالية التي تتم معالجتها هي نقطة دخول مشغّل الخدمات. وبخلاف ذلك، تتم كتابة الملفات المكرّرة إلى وجهاتها العادية.

// webpack.config.js
import process from 'process';

const isProd = process.env.NODE_ENV === 'production';

export default {
  mode: isProd ? 'production' : 'development',
  context: process.cwd(),
  entry: {
    // Service worker entry point:
    sw: './src/sw.js',
    // Application entry point:
    app: './src/index.js'
  },
  output: {
    filename: ({runtime}) => {
      // Check if the current filename is for the service worker:
      if (runtime === 'sw') {
        // Output a service worker in the root of the dist directory
        // Also, ensure the output file name doesn't have a hash in it
        return '[name].js';
      }

      // Otherwise, output files as normal
      return 'js/[name].[contenthash:8].js';
    },
    path: './dist',
    publicPath: '/',
    clean: true
  }
};

دمج القنوات

يتشابه العرض الإجمالي مع حزمة الويب، باستثناء أنّه يتم تحديد نقاط إدخال متعددة ككائنات ضبط منفصلة يتم تصديرها في مصفوفة:

// rollup.config.js
import { nodeResolve } from '@rollup/plugin-node-resolve';
import replace from '@rollup/plugin-replace';

// Plugins common to both entry points
const plugins = [
  nodeResolve(),
];

export default [
  // Application entry point
  {
    input: './src/index.js',
    output: {
      dir: './dist/js',
      format: 'esm'
    },
    plugins
  },
  // Service worker entry point
  {
    input: './src/sw.js',
    output: {
      file: './dist/sw.js',
      format: 'iife'
    },
    plugins: [
      ...plugins,
      // This @rollup/plugin-replace instance replaces process.env.NODE_ENV
      // statements in the Workbox libraries to match your current environment.
      // This changes whether logging is enabled ('development') or disabled ('production').
      replace({
        'process.env.NODE_ENV': JSON.stringify(process.env.NODE_ENV || 'production')
      })
    ]
  }
];

إسبيل

يوفر esbuild واجهة سطر أوامر بسيطة:

npx esbuild ./src/sw.js --bundle --minify --outfile=./dist/sw.js

سيختبر esbuild محلّ process.env.NODE_ENV بـ "التطوير" بشكل تلقائي، أو بـ "الإنتاج" في حال تفعيل التصغير.

بدون استخدام حزمة على "workbox-sw"

قد لا يستخدم مشروعك حزمة حتى. يمكن لـ "workbox-sw" تحميل وقت تشغيل Workbox من شبكة توصيل المحتوى (CDN) ضِمن مشغّل الخدمات وبدون خطوة إصدار في حال استيراده باستخدام importScripts:

// sw.js

// Imports Workbox from the CDN. Note that "6.2.0" of the URL
// is the version of the Workbox runtime.
importScripts('https://storage.googleapis.com/workbox-cdn/releases/6.2.0/workbox-sw.js');

const navigationRoute = new workbox.routing.NavigationRoute(new workbox.strategies.NetworkFirst({
  cacheName: 'navigations'
}));

const imageAssetRoute = new workbox.routing.Route(({request}) => {
  return request.destination === 'image';
}, new workbox.strategies.CacheFirst({
  cacheName: 'image-assets'
}));

workbox.routing.registerRoute(navigationRoute);
workbox.routing.registerRoute(staticAssetRoute);

إذا لم يكن هناك احتمال كبير بتحميل وقت تشغيل Workbox من شبكة توصيل المحتوى (CDN)، يمكنك استخدام workbox-sw مع عناوين URL المحلية.

الخاتمة

والآن بعد أن تعرفت على كيفية استخدام Workbox بدون التخزين المؤقت مسبقًا، لم تعد مرتبطًا بأداة تجميع أو أداة إنشاء معيّنة. يمنحك ذلك مرونة في تصميم عامل خدمات باستخدام أجزاء فقط من رمز التخزين المؤقت لوقت التشغيل في Workbox الذي تهتم به.