Author:
    Creation:2026-09-02Last update:2026-09-02

    Vite i18n: वे हिस्से जो Vite के बारे में हैं, आपके फ्रेमवर्क के नहीं

    अधिकांश "Vite i18n" ट्यूटोरियल वास्तव में React या Vue ट्यूटोरियल हैं जो केवल Vite का उपयोग करते हैं। यह लेख नीचे की परत के बारे में है: कैटलॉग कैसे आयात किए जाते हैं, Rollup उनके साथ क्या करता है, और आपने जो लेज़ी लोडिंग लिखी है वह शायद लेज़ी क्यों नहीं है।

    विषय सूची

    स्टेटिक आयात डिफ़ॉल्ट है, और यह उत्सुक (eager) है

    सबसे सरल सेटअप एक मॉड्यूल के शीर्ष पर प्रत्येक कैटलॉग को आयात करता है:

    src/i18n.ts
    import en from "./locales/en.json";
    import fr from "./locales/fr.json";
    import ja from "./locales/ja.json";
    

    इसका मतलब है कि एंट्री चंक में तीन कैटलॉग, हर पेज पर, हर उपयोगकर्ता के लिए शामिल हैं। यह दो लोकेल और सौ स्ट्रिंग्स के लिए ठीक है। दस लोकेल पर यह बंडल में सबसे बड़ा परिहार्य खर्च बन जाता है।

    import.meta.glob और वह फ्लैग जिसे हर कोई गलत समझता है

    Vite का ग्लोब आयात सामान्य समाधान है:

    ts
    const catalogs = import.meta.glob("./locales/*.json");
    
    export const loadCatalog = async (locale: string) => {
      const load = catalogs[`./locales/${locale}.json`];
      return (await load()) as Record<string, string>;
    };
    

    लेज़ी डिफ़ॉल्ट है: प्रत्येक प्रविष्टि एक फ़ंक्शन है जो एक गतिशील आयात लौटाती है, और Rollup प्रति फ़ाइल एक चंक उत्सर्जित करता है। { eager: true } जोड़ने से वे सभी आयात करने वाले मॉड्यूल में इनलाइन हो जाते हैं, जिससे बचने की आप कोशिश कर रहे थे:

    ts
    // प्रत्येक लोकेल, एंट्री चंक में। लगभग कभी नहीं जो आप चाहते हैं:
    const catalogs = import.meta.glob("./locales/*.json", { eager: true });
    

    जाल यह है कि दोनों संस्करण विकास में काम करते हैं, क्योंकि Vite अनबंडल मॉड्यूल प्रदान करता है। अंतर केवल dist में दिखाई देता है। npx vite build && npx vite preview के साथ जाँचें, फिर देखें कि एंट्री चंक में वास्तव में क्या शामिल है।

    प्रति-रूट विभाजन शायद ही कभी विभाजित होता है

    यह वह हिस्सा है जो लोगों को हैरान करता है। आप पृष्ठ के अनुसार कैटलॉग विभाजित करते हैं:

    plaintext
    locales/en/home.json
    locales/en/checkout.json
    

    फिर दो रूट दोनों checkout.json आयात करते हैं, और Rollup इसे एक साझा चंक में ले जाता है जो दोनों पर लोड होता है। Rollup का चंकिंग मॉड्यूल ग्राफ़ द्वारा संचालित होता है, आपके फ़ोल्डर नामों से नहीं: एक से अधिक प्रविष्टियों से पहुँच योग्य मॉड्यूल सामान्य हो जाता है। एक तीसरा रूट जोड़ने से कुछ नहीं बदलता है, और चौथा जोड़ने से यह अलग तरह से विभाजित हो सकता है।

    इसलिए प्रति-रूट लोकेल विभाजन केवल तभी लागू होता है जब आयात ग्राफ़ वास्तव में अलग हो। यदि यह मायने रखता है, तो इसे मानने के बजाय सत्यापित करें:

    bash
    npx vite build && npx vite-bundle-visualizer
    

    यदि आपको सीमा को बाध्य करने की आवश्यकता है, तो build.rollupOptions.output.manualChunks निकास द्वार है, जिसे हाथ से बनाए रखने की लागत चुकानी पड़ती है।

    कैटलॉग हॉट-रीलोड नहीं होते हैं

    एक घटक को संपादित करें, Vite इसे तुरंत बदल देता है। locales/fr.json को संपादित करें, और इसे कैसे आयात किया गया था इसके आधार पर, कुछ नहीं होता है। गतिशील रूप से आयातित JSON की कोई HMR सीमा नहीं होती है, इसलिए मॉड्यूल ग्राफ़ को उपभोक्ताओं को अमान्य करना नहीं पता होता है।

    लोग हर बार किसी स्ट्रिंग को छूने पर देव सर्वर को पुनरारंभ करके इसका समाधान करते हैं, आमतौर पर यह महसूस किए बिना कि यह टालने योग्य है। सुधार i18n प्लगइन का है: इसे HMR अपडेट को स्वीकार करना होगा और चल रहे ऐप में नए संदेशों को पुश करना होगा। जब आप किसी लाइब्रेरी का मूल्यांकन करते हैं, तो जाँचें कि क्या उसका Vite प्लगइन ऐसा करता है।

    define लोकेल को बेक कर देता है

    बिल्ड समय पर डिफ़ॉल्ट लोकेल को हल करना आकर्षक है:

    vite.config.ts
    export default defineConfig({
      define: {
        __DEFAULT_LOCALE__: JSON.stringify(process.env.LOCALE ?? "en"),
      },
    });
    

    define बिल्ड समय पर किया गया एक पाठ्य प्रतिस्थापन है। जब आप निर्माण करते हैं तो जो भी मान मौजूद होता है वह वही मान होता है जो शिप करता है, इसलिए यह प्रति लोकेल एक बिल्ड को बाध्य करता है। यह एक वैध रणनीति है, और Angular का आधिकारिक i18n यही करता है। यदि किसी एकल परिनियोजन को प्रत्येक भाषा की सेवा करनी है तो यह वह नहीं है जो आप चाहते हैं।

    उन मानों के लिए जो प्रति अनुरोध भिन्न होने चाहिए, उन्हें define से बाहर रखें और उन्हें रनटाइम पर हल करें।

    संदेश पार्सिंग को बिल्ड समय पर ले जाना

    इस पारिस्थितिकी तंत्र में प्रत्येक परिपक्व विकल्प अंततः वही काम करता है: ब्राउज़र में संदेशों को पार्स करना बंद करना।

    प्लगइन यह बिल्ड समय पर क्या ले जाता है
    @intlify/unplugin-vue-i18n vue-i18n संदेशों को रेंडर फ़ंक्शन में संकलित करता है
    Lingui (मैक्रो + प्लगइन) कैटलॉग निकालता और संकलित करता है, मैक्रोज़ को संदेश आईडी से बदलता है
    Paraglide (inlang) प्रत्येक संदेश को अपने स्वयं के ट्री-शेकेबल फ़ंक्शन में संकलित करता है
    vite-intlayer प्रति-घटक शब्दकोश बनाता है, अप्रयुक्त फ़ील्ड्स को हटाता और छोटा करता है

    साझा लाभ दोहरा है: रनटाइम संदेश कंपाइलर शिप होना बंद हो जाता है, और अप्रयुक्त प्रविष्टियां स्थिर रूप से हटाने योग्य हो जाती हैं। साझा लागत यह है कि आपके देव सर्वर और आपके CI दोनों को प्लगइन की आवश्यकता होती है, और एक खाली tsc या गैर-Vite परीक्षण रनर अतिरिक्त कॉन्फ़िगरेशन के बिना उत्पन्न आउटपुट को नहीं देख पाएंगे।

    SSR: कभी भी किसी मॉड्यूल में लोकेल न रखें

    यदि आप SSR जोड़ते हैं, चाहे किसी फ्रेमवर्क के माध्यम से या vite-plugin-ssr के माध्यम से, जो नियम मायने रखता है वह यह है: वर्तमान लोकेल रखने वाला एक मॉड्यूल-स्तरीय चर उस सर्वर प्रक्रिया पर प्रत्येक समवर्ती अनुरोध में साझा किया जाता है।

    ts
    // ब्राउज़र में ठीक है। सर्वर पर एक क्रॉस-रिक्वेस्ट डेटा लीक:
    export let currentLocale = "en";
    

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

    Intlayer का Vite प्लगइन

    Intlayer एक एकल प्लगइन पंजीकृत करता है जो शब्दकोश निर्माण, देव-मोड निगरानी और अनुकूलन पाइपलाइन को संभालता है:

    vite.config.ts
    import react from "@vitejs/plugin-react";
    import { defineConfig } from "vite";
    import { intlayer } from "vite-intlayer";
    
    export default defineConfig({
      plugins: [react(), intlayer()],
    });
    

    आयात पुनर्लेखन, पर्ज और मिनिफ़ाई डिफ़ॉल्ट रूप से चालू हैं। दो मुख्य फ़्लैग intlayer.config.ts में रहते हैं:

    intlayer.config.ts
    import type { IntlayerConfig } from "intlayer";
    
    const config: IntlayerConfig = {
      build: {
        purge: true, // उन सामग्री फ़ील्ड्स को छोड़ें जिन्हें कोई घटक नहीं पढ़ता है
        minify: true, // सामग्री कुंजियों का नाम बदलकर छोटे उपनाम रखें
      },
    };
    
    export default config;
    

    चूँकि सामग्री को प्रति लोकेल फ़ाइल के बजाय प्रति घटक घोषित किया जाता है, इसलिए पर्ज पास के पास काम करने के लिए एक मॉड्यूल ग्राफ़ होता है, जो निष्कासन को सुरक्षित बनाता है। विवरण बंडल अनुकूलन में।

    सामान्य गलतियाँ

    • ग्लोब पर { eager: true } जिसे आप लेज़ी लोड करना चाहते थे। देव में काम करता है, उत्पादन में सब कुछ भेजता है।
    • चंक्स का उत्पादन करने के लिए फ़ोल्डर संरचना पर भरोसा करना। Rollup आयात का अनुसरण करता है, निर्देशिकाओं का नहीं।
    • अनुवाद परिवर्तन देखने के लिए देव सर्वर को पुनरारंभ करना। यह एक अनुपस्थित HMR हैंडलर है, सामान्य नहीं।
    • define में लोकेल डालना। आपने अभी-अभी प्रति भाषा एक बिल्ड के लिए प्रतिबद्ध किया है।
    • SSR के साथ मॉड्यूल-स्तरीय लोकेल स्थिति। क्रॉस-रिक्वेस्ट लीक जो कभी भी स्थानीय रूप से प्रकट नहीं होता है।
    • देव सर्वर की बेंचमार्किंग। अनबंडल किए गए मॉड्यूल आपको बंडल के बारे में कुछ नहीं बताते हैं।

    आगे पढ़ें

    टिप्पणियाँ

    अभी तक कोई टिप्पणी नहीं। अपने विचार साझा करने वाले पहले व्यक्ति बनें।

    संबंधित पोस्ट

    नवीनतम पोस्ट