Офлайн-режим в Globalize строится вокруг принципа полного отсутствия зависимости от сети во время выполнения приложения. Библиотека не выполняет запросов к CDN или внешним API для получения локализационных данных. Все необходимые ресурсы — CLDR-данные, форматы, сообщения — должны быть заранее включены в сборку или загружены локально.
Ключевой элемент модели — CLDR (Unicode Common Locale Data Repository). Globalize использует его как единственный источник локализационной информации: числовые форматы, правила плюрализации, календарные данные, валюты, единицы измерения.
Основной принцип офлайн-режима:
Все данные локализации должны быть доступны в момент инициализации приложения
Globalize не содержит встроённых локалей. Вместо этого используется внешняя поставка CLDR JSON-файлов.
Минимальный набор данных для офлайн-работы включает:
likelySubtagsnumberscurrenciescalendartimeZoneNamespluralRulesCLDR-файлы подключаются вручную:
import likelySubtags from "cldr-core/supplemental/likelySubtags.json";
import numberingSystems from "cldr-core/supplemental/numberingSystems.json";
import plurals from "cldr-core/supplemental/plurals.json";
import enNumbers from "cldr-numbers-full/main/en/numbers.json";
import enCurrencies from "cldr-numbers-full/main/en/currencies.json";
import enCaGregorian from "cldr-dates-full/main/en/ca-gregorian.json";
Далее данные передаются в Globalize:
import Globalize from "globalize";
Globalize.load(
likelySubtags,
numberingSystems,
plurals,
enNumbers,
enCurrencies,
enCaGregorian
);
После этого библиотека полностью работает без сетевых запросов.
Инициализация требует явного определения локали:
const globalize = new Globalize("en");
После привязки локали все операции используют только загруженные данные.
Офлайн-режим требует выбора стратегии упаковки локалей:
Используется в приложениях с множеством языков:
import * as en from "cldr-dates-full/main/en/ca-gregorian.json";
import * as ru from "cldr-dates-full/main/ru/ca-gregorian.json";
Недостаток — увеличение размера бандла.
Подключаются только используемые языки:
const locales = ["en", "ru", "de"];
locales.forEach(locale => {
require(`cldr-dates-full/main/${locale}/ca-gregorian.json`);
});
Такой подход оптимизирует размер и ускоряет загрузку.
Офлайн-режим требует статической поставки JSON:
module.exports = {
module: {
rules: [
{
test: /\.json$/,
type: "json"
}
]
}
};
Дополнительно используется ContextReplacementPlugin для
ограничения локалей:
new webpack.ContextReplacementPlugin(
/cldr-dates-full/,
/(en|ru|de)\.json/
);
Vite позволяет использовать динамические импорты:
const loadLocale = async (locale) => {
const data = await import(`cldr-dates-full/main/${locale}/ca-gregorian.json`);
Globalize.load(data);
};
В офлайн-сценарии динамические импорты должны быть предсобраны во время build step.
При работе в браузере офлайн-режим может дополняться кешированием через Service Worker.
self.addEventListener("install", (event) => {
event.waitUntil(
caches.open("globalize-cache").then((cache) => {
return cache.addAll([
"/locales/en.json",
"/locales/ru.json"
]);
})
);
});
При последующих загрузках данные берутся из кеша, исключая сеть.
После загрузки CLDR Globalize может форматировать числа без подключения к сети:
const formatNumber = new Globalize("en").numberFormatter();
formatNumber(12345.67);
// "12,345.67"
Все правила берутся из локально загруженного CLDR.
Для валют требуется дополнительный CLDR-модуль:
const formatCurrency = new Globalize("en").currencyFormatter("USD");
formatCurrency(1999.99);
// "$1,999.99"
При отсутствии currencies.json форматирование становится
невозможным, что делает его обязательным элементом офлайн-сборки.
CLDR календарные данные обеспечивают корректную локализацию дат:
const formatDate = new Globalize("ru").dateFormatter({
datetime: "medium"
});
formatDate(new Date());
// "28 мая 2026 г., 12:34:56"
Зависимые данные:
ca-gregorian.jsontimeZoneNames.jsondateFields.jsonОфлайн-архитектура часто требует разделения сборки:
locale-en.jslocale-ru.jslocale-de.jsПример загрузки:
import Globalize from "globalize";
async function init(locale) {
const data = await import(`./locales/${locale}.js`);
Globalize.load(data);
return new Globalize(locale);
}
CLDR имеет большой объём данных, поэтому офлайн-режим требует оптимизации:
numbers
без timeZoneNames)CLDR может занимать десятки мегабайт при полной локализации множества языков.
Несоответствие версий CLDR и Globalize приводит к ошибкам форматирования.
Без webpack/Vite корректная сборка офлайн-пакета становится нетривиальной задачей.
const locales = {};
async function getLocale(locale) {
if (!locales[locale]) {
const data = await import(`./cldr/${locale}.json`);
Globalize.load(data);
locales[locale] = new Globalize(locale);
}
return locales[locale];
}
const criticalLocales = ["en", "ru"];
Promise.all(
criticalLocales.map(l => import(`./cldr/${l}.json`))
).then(modules => {
modules.forEach(m => Globalize.load(m));
});
Создание отдельного слоя данных:
class LocaleStore {
constructor() {
this.cache = new Map();
}
async load(locale) {
if (!this.cache.has(locale)) {
const data = await import(`./cldr/${locale}.json`);
Globalize.load(data);
this.cache.set(locale, new Globalize(locale));
}
return this.cache.get(locale);
}
}
Перед запуском приложения выполняется валидация:
numberscurrenciescalendarПример простого чекера:
function validateCLDR(data) {
return (
data.numbers &&
data.numbers.defaultNumberingSystem &&
data.currencies &&
data["ca-gregorian"]
);
}
В прогрессивных веб-приложениях офлайн-режим Globalize становится частью сервисной архитектуры:
В Node.js офлайн-режим проще:
const Globalize = require("globalize");
const cldrData = require("./cldr/ru.json");
Globalize.load(cldrData);
const g = new Globalize("ru");
В браузере требуется упаковка через сборщик, но логика остаётся идентичной.
Ключевые факторы производительности:
Пример кеширования форматтера:
const cache = new Map();
function getFormatter(locale) {
if (!cache.has(locale)) {
cache.set(locale, new Globalize(locale).numberFormatter());
}
return cache.get(locale);
}