استفاده از Workbox بدون پیش کش

تا کنون، این مستندات در زمینه پیش کش (precaching) بسیار مفید بوده است و اغلب ابزارهای ساخت generateSW و injectManifest را لمس کرده است. در حالی که دلایل خوبی برای گنجاندن منطق پیش کش در سرویس کار خود وجود دارد، برای استفاده از Workbox نیازی به استفاده از پیش کش ندارید.

شاید پروژه شما فقط به ذخیره سازی در زمان اجرا نیاز داشته باشد، یا شاید بخواهید روش تمیزتری برای ادغام API های سرویس دهنده، مانند فشار وب ، داشته باشید. این موارد زمانی است که شما نمی خواهید از ابزارهای ساخت 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 نقاط ورودی را در پیکربندی 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 وضعیتی مشابه با بسته وب است، به جز اینکه چندین نقطه ورودی به عنوان اشیاء پیکربندی جداگانه صادر شده در یک آرایه مشخص شده اند:

// 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 با «توسعه» یا «production» در صورت فعال بودن کوچک‌سازی می‌شود.

بدون باندلر با استفاده از 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 که به آن‌ها علاقه دارید، یک کارگر خدماتی را به صورت دستی بسازید.