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

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

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

عند استخدام أداة تجميع

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

في جذر دليل مصدر مشروعك، عليك إنشاء عامل خدمة واستخدام أي وحدات Workbox يتطلبها تطبيقك. في ما يلي مثال بدون التخزين المؤقت المُسبَق، والذي يُعدّ استراتيجيات التخزين المؤقت لطلبات التنقّل ومواد عرض الصور في نُسخ منفصلة من 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

يقبل 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 هو حلّ مشابه لحلّ webpack، باستثناء أنّه يتم تحديد نقاط دخول متعددة ككائنات إعدادات منفصلة يتم تصديرها في صفيف:

// 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

توفر أداة esbuild واجهة سطر أوامر واضحة:

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

سيتولى esbuild استبدال process.env.NODE_ENV بـ "development" تلقائيًا، أو "production" في حال تفعيل التصغير.

بدون استخدام أداة تجميع باستخدام workbox-sw

قد لا يستخدم مشروعك أداة تجميع. يمكن أن تحمِّل workbox-sw وقت تشغيل Workbox نيابةً عنك من شبكة توصيل المحتوى (CDN) ضمن worker الخدمة وبدون خطوة إنشاء إذا استوردتها باستخدام 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 التي تهمّك فقط.