SvelteKit . में MSW

SvelteKit में स्थानीय विकास के लिए MSW को कैसे कार्यान्वित करें?

SvelteKit में MSW का उपयोग करना

यह एक ट्यूटोरियल है जो आपको दिखाएगा कि आपके SvelteKit एप्लिकेशन में "मॉक सर्विस वर्कर" लाइब्रेरी, जिसे MSW कहा जाता है, को कैसे लागू किया जाए। कृपया ध्यान दें कि यह मार्गदर्शिका यह नहीं दिखाती है कि MSW को जेस्ट के साथ कैसे सेट किया जाए, बल्कि लाइव डेवलपमेंट के दौरान MSW का उपयोग कैसे किया जाए।

पूर्ण कार्यान्वयन पृष्ठ के अंत में परिशिष्ट में भी spikze.club, लिंक के भंडार में उपलब्ध है।

यदि यह मार्गदर्शिका पहली बार में भारी लग सकती है, तो चिंता न करें, परिवर्तन काफी सरल हैं। स्थानीय विकास के दौरान अनुरोधों का मजाक उड़ाने के लिए SvelteKit में MSW का उपयोग करने के लिए बस थोड़ा और प्रयास करने की आवश्यकता है।

निर्भरता स्थापित करना

सबसे पहले, सभी आवश्यक निर्भरताएँ स्थापित करें।

npm i -D msw ts-node concurrently

हम सर्वर-मॉक्स भी शुरू करने के लिए "ts-नोड" का उपयोग कर रहे हैं। आगे बढ़ने से पहले, कृपया अपने SvelteKit-project के रूट में निम्न कमांड को कॉल करें।

npx msw init ./static

यह MSW द्वारा डिफ़ॉल्ट सर्विस वर्कर हैंडलर के साथ एक Javascript-फाइल जेनरेट करेगा। हम अपने SvelteKit-app के लिए "स्थैतिक" का उपयोग कर रहे हैं, क्योंकि यह सार्वजनिक निर्देशिका के बराबर है। अंत में, package.json-file को अपडेट करते हैं ताकि MSW को पता चले कि फाइल को कहां देखना है।

{
  "scripts": ...
  ...
  "msw": {
    "workerDirectory": "static"
  }
}

एक सुविधाजनक स्क्रिप्ट के रूप में, मैंने अपनी "स्क्रिप्ट्स" -कॉन्फ़िगरेशन में निम्न कमांड को भी जोड़ा है, जिसकी आवश्यकता है यदि आप क्लाइंट के साथ-साथ सर्वर (सर्वर-साइड मॉक के लिए) दोनों के माध्यम से MSW शुरू करना चाहते हैं।

{
  "scripts": {
    "dev": "svelte-kit dev",
    "dev:msw-server": "concurrently \"cd msw && ts-node server.ts\" \"npm run dev\"",
    ...
  },
}

MSW-मॉड्यूल तैयार करना

वास्तविक कोड लिखना शुरू करने से पहले, हमें SvelteKit के कॉन्फिगरेशन के साथ-साथ टाइपस्क्रिप्ट-कॉन्फ़िगरेशन में MSW के लिए अपनी नई वर्किंग डायरेक्टरी को परिभाषित करने की आवश्यकता है। हम टाइपस्क्रिप्ट-फाइल से शुरू करेंगे।

{
  "compilerOptions": {
    ...,
    "paths": {
      "$lib": ["src/lib"],
      "$lib/*": ["src/lib/*"],
      "$msw": ["src/msw"],
      "$msw/*": ["src/msw/*"]
    }
  }
}

इसके बाद, SvelteKit-config को अपडेट करते हैं।

import adapter from "@sveltejs/adapter-auto";
import preprocess from "svelte-preprocess";
import path from "path";

/** @type {import('@sveltejs/kit').Config} */
const config = {
  // Consult https://github.com/sveltejs/svelte-preprocess
  // for more information about preprocessors
  preprocess: preprocess(),
  kit: {
    adapter: adapter(),
    vite: {
      ...,
      resolve: {
        alias: {
          $msw: path.resolve("./src/msw"),
          $lib: path.resolve("./src/lib")
        }
      }
    }
  }

मोक्स और हैंडलर्स जोड़ना

ठीक है, आपने इसे गाइड के पहले भाग के माध्यम से बनाया है! अब हम वास्तविक कोड जोड़ेंगे जो MSW का उपयोग करते समय निष्पादित हो जाता है। कृपया ध्यान दें कि यह एक न्यूनतम उदाहरण है, इसलिए मैंने यह जोड़ा कि यह सब काम करने के लिए क्या आवश्यक है, लेकिन अब और नहीं।

जैसा कि आपने SvelteKit-config में हमारे परिवर्तनों से अनुमान लगाया होगा, सभी कोड "msw" नामक एक नई निर्देशिका में रखे जाएंगे, जो सीधे "src" में रहता है।

|- app/
|-- src/
|--- pages/
|--- msw/
|---- fixtures/
...

जोड़ने के लिए अगले मॉड्यूल के लिए कोड यहां दिया गया है। आपको बस उन्हें कॉपी-पेस्ट करने में सक्षम होना चाहिए, फ़ाइल का नाम + निर्देशिका पथ शीर्ष पर प्रत्येक ब्लॉक में एक टिप्पणी के रूप में लिखा गया है।

//
// app/src/msw/handlers.server.ts
//

import { rest } from "msw";
import { values } from "./fixtures/msw-demo";

export const handlers = [
  // Here, you can mock absolute URL requests,
  // e.g. to a database. For the current implementation,
  // no data is mocked in this place.
  //
  // Note: This is also the place to mock absolute
  // SSR-imports. Everything in 'handlers.workers.ts'
  // is mocked client-side.
];
//
// app/src/msw/handlers.worker.ts
//

import { rest } from "msw";
import { values } from "./fixtures/msw-demo";

// Mock relative URLs that map to your
// routes' data endpoints. This mock only
// happens for client-side requests.
//
// Note that if you use shadow endpoints, this still works
// as the endpoint gets created by SvelteKit.
export const handlers = [
  rest.get("/msw/demo/__data.json", (req, res, ctx) => {
    return res(ctx.status(200), ctx.json({ values }));
  })
];
//
// app/src/msw/server.ts
//

import { setupServer } from "msw/node";
import { handlers } from "./handlers.server";

export const server = setupServer(...handlers);
//
// app/src/msw/worker.ts 
//

import { setupWorker } from "msw";
import { handlers } from "./handlers.worker";

export const worker = setupWorker(...handlers);
//
// app/src/msw/fixtures/msw-demo.ts
//

export const values = ["foo", "bar"];
//
// app/src/msw/index.ts 
//

import { browser, dev } from "$app/env";

/**
 * Lazy-inject the MSW handler
 * so that no errors happen during
 * build/runtime due to invalid
 * imports from server/client.
 */
export async function inject() {
  if (dev && browser) {
    const { worker } = await import("../msw/worker");
    // For live development, I disabled all warnings
    // for requests that are not mocked. Change how
    // you think it best fits your project.
    return worker.start({ onUnhandledRequest: "bypass" }).catch(console.warn);
  }
  if (dev && !browser) {
    const { server } = await import("../msw/server");
    // Same as in worker-mock above.
    return server.listen({ onUnhandledRequest: "bypass" });
  }
}

एमएसडब्ल्यू शुरू करना

लाइव डेवलपमेंट के दौरान MSW का उपयोग करते समय एक चुनौती यह है कि हमें यह सुनिश्चित करना होगा कि कोई दौड़ की स्थिति न हो। हमें निष्पादन के आदेश को परिभाषित करना होगा, अन्यथा सभी अनुरोध किए जाने के बाद MSW का सेवा कार्यकर्ता सक्रिय हो सकता है।

इस लक्ष्य को पूरा करने के लिए, हम अपनी रूट लेआउट-फाइल को संशोधित करते हैं। चूंकि यह फ़ाइल प्रत्येक पृष्ठ के लिए माउंट की गई है, यह MSW समाप्त होने तक आगे के सभी निष्पादन को अवरुद्ध करने के लिए एक अच्छी जगह है।

<script>
  import "../app.css";
  import { dev } from "$app/env";
  
  // Loaded from .env.local, guide covers this
  // step in a moment.
  const isMswEnabled = dev && import.meta.env.VITE_MSW_ENABLED === "true";
  // Flag to defer rendering of components
  // until certain criteria are met on dev,
  // e.g. MSW init.
  let isReady = !isMswEnabled;
  
  if (isMswEnabled) {
    import("$msw")
      .then((res) => res.inject())
      .then(() => (isReady = true));
  }
</script>

{#if isReady}
  <slot />
{/if}

डेमो पेज जोड़ना

निम्नलिखित कोड स्निपेट केवल दो डेमो पेज और इस ट्यूटोरियल में उपयोग किए गए एक एंडपॉइंट के लिए सामग्री दिखाते हैं।

<!-- app/src/routes/msw/index.svelte -->

<script>
  import DisplayProse from "$lib/display/views/DisplayProse.svelte";
  import ProminentDisplayTitle from "$lib/display/views/ProminentDisplayTitle.svelte";
  import PageLayout from "$lib/layout/views/PageLayout.svelte";
  import SectionLayout from "$lib/layout/views/SectionLayout.svelte";
</script>

<PageLayout>
  <SectionLayout withContentTopSpacing withHeaderSpacing>
    <ProminentDisplayTitle slot="header" color="primary">MSW Landing Page</ProminentDisplayTitle>
    <DisplayProse>
      <p>
        This compoonent has no purpose other than being part of an MSW demo implementation. See <a
          href="https://flaming.codes"
          alt="Link to flaming.codes with blog posts">flaming.codes</a
        > for more details.
      </p>
      <p>
        This page doesn't fetch any data for shows how client-side fetches are mocked with MSW in
        SvelteKit.
      </p>
      <p>Simply click the link below to access the page with data.</p>
      <p>
        <a href="/msw/demo" alt="Link to demo page with data">msw/demo</a>
      </p>
    </DisplayProse>
  </SectionLayout>
</PageLayout>
<!-- app/src/routes/msw/demo.svelte -->

<script lang="ts">
  import ProminentDisplayTitle from "$lib/display/views/ProminentDisplayTitle.svelte";
  import PageLayout from "$lib/layout/views/PageLayout.svelte";
  import SectionLayout from "$lib/layout/views/SectionLayout.svelte";
  export let values: string[];
</script>

<PageLayout>
  <SectionLayout withHeaderSpacing withContentTopSpacing>
    <ProminentDisplayTitle slot="header" color="primary">MSW Demo</ProminentDisplayTitle>
    <p>
      This compoonent has no purpose other than being part of an MSW demo implementation. See <a
        href="https://flaming.codes"
        alt="Link to flaming.codes with blog posts">flaming.codes</a
      > for more details.
    </p>
    <p>
      Values: {values}
    </p>
  </SectionLayout>
</PageLayout>
//
// app/src/routes/msw/demo.ts
//

import type { RequestHandler } from "@sveltejs/kit";

// Just for demo purposes.
export const get: RequestHandler = async () => ({
  status: 200,
  body: {
    values: ["production", "data", "not", "msw"]
  }
});

एक पर्यावरण चर जोड़ना

हम लगभग कर चुके हैं। हमारे परिवेश में "VITE_MSW_ENABLED" -ध्वज जोड़ने की कमी है। हम ध्वज को पकड़ने के लिए हमारी फ़ाइल के रूप में ".env.local" का उपयोग कर रहे हैं, क्योंकि यह Vite द्वारा उपभोग किया जाएगा और git में नहीं जोड़ा जाएगा।

VITE_MSW_ENABLED=true

आवेदन चल रहा है

ठीक है, अब सब कुछ उपयोग के लिए तैयार होना चाहिए! क्लाइंट पर मॉकिंग सक्षम करने के लिए, बस सुनिश्चित करें कि ध्वज सेट है। क्लाइंट-साइड अनुरोधों का मजाक उड़ाने के लिए सामान्य "देव" -कमांड चलाएँ।

npm run dev

सर्वर-साइड अनुरोधों का भी मज़ाक उड़ाने के लिए, बस उस नई कमांड को चलाएँ जिसे हमने शुरुआत में जोड़ा था।

npm run dev:msw-server

अब आप स्थानीय विकास के दौरान समापन बिंदुओं का मजाक उड़ाने के लिए तैयार हैं। जैसा कि कोड उदाहरण में बताया गया है, इस डेमो पेज में सर्वर-साइड मॉक शामिल नहीं हैं, हालांकि इसके लिए सब कुछ तैयार किया गया है। इसका मतलब यह है कि स्थानीय रूप से, MSW-कॉल तभी ट्रिगर होता है जब आप लिंक पर एक क्लिक के माध्यम से डेमो साइट के इंडेक्स-पेज से वास्तविक डेमो-पेज पर नेविगेट करते हैं।

सर्वर-अनुरोधों का अनुकरण करने के लिए, आपके पास अधिक जटिल समापन बिंदु होंगे जो डेटाबेस से डेटा भी प्राप्त करेंगे। सर्वर-हैंडलर में उन अनुरोधों का मजाक उड़ाया जा सकता है। ध्यान दें कि सर्वर-मॉक्स के लिए, केवल निरपेक्ष URL ही मान्य होते हैं।