Механизм расширения Globalize (JavaScript library) строится вокруг идеи модульной локализации, где базовое ядро отвечает за работу с CLDR-данными, а дополнительные возможности подключаются через плагины. Плагины позволяют изолировать функциональность форматирования, парсинга и преобразования данных, не перегружая основной пакет и сохраняя предсказуемую архитектуру.
В основе системы лежит единый объект Globalize, который
инкапсулирует доступ к локализованным операциям. Плагины подключаются
как расширения этого объекта, добавляя новые методы или модифицируя
поведение существующих через композицию.
Ключевые принципы:
Такая модель делает систему предсказуемой при масштабировании и позволяет формировать минимальные сборки под конкретные задачи.
Плагин в контексте Globalize представляет собой функцию, принимающую
экземпляр Globalize и добавляющую к нему новый
функционал.
function currencyPlugin(Globalize) {
Globalize.prototype.formatCurrencyDetailed = function(value, currency) {
return this.currencyFormatter(currency)(value);
};
}
Регистрация выполняется вручную:
import Globalize from "globalize";
currencyPlugin(Globalize);
После подключения методы становятся частью прототипа и доступны через любой экземпляр:
const globalize = new Globalize("en");
globalize.formatCurrencyDetailed(1000, "USD");
Плагин обычно состоит из трёх частей:
Пример расширенного шаблона:
function numberParserPlugin(Globalize) {
if (!Globalize || !Globalize.formatNumber) {
throw new Error("Globalize core or number module is missing");
}
function parseNumber(str) {
return this.numberParser()(str);
}
Globalize.prototype.parseNumber = parseNumber;
}
Такая структура позволяет контролировать совместимость и предотвращать некорректное подключение.
Наиболее распространённый тип расширений связан с форматированием данных. Globalize предоставляет базовые методы, но плагины позволяют объединять несколько операций или вводить новые форматы.
function dateTimePlugin(Globalize) {
Globalize.prototype.formatDateTimeLong = function(date) {
return this.formatDate(date, {
datetime: "long"
});
};
}
Добавленный метод объединяет стандартную функциональность в более высокоуровневую операцию, что уменьшает дублирование кода в приложениях.
Парсинг часто требует более сложной логики, чем форматирование, особенно при работе с пользовательским вводом.
function strictParsePlugin(Globalize) {
Globalize.prototype.strictParseNumber = function(value) {
const parsed = this.parseNumber(value);
if (isNaN(parsed)) {
throw new Error("Invalid number format");
}
return parsed;
};
}
Подобные плагины усиливают контроль над данными, особенно в формах и интерфейсах ввода.
Некоторые расширения объединяют несколько типов операций, создавая более высокоуровневые абстракции.
function accountingPlugin(Globalize) {
Globalize.prototype.formatAccounting = function(value, currency) {
const formattedNumber = this.formatNumber(value, {
minimumFractionDigits: 2
});
const formattedCurrency = this.currencyFormatter(currency)(value);
return `${formattedCurrency} (${formattedNumber})`;
};
}
Такие плагины формируют доменно-ориентированные инструменты поверх базовой интернационализации.
При увеличении числа расширений возникает необходимость контроля порядка подключения.
function pluginA(Globalize) {
Globalize.prototype.methodA = function() {};
}
function pluginB(Globalize) {
if (!Globalize.prototype.methodA) {
throw new Error("pluginA must be loaded before pluginB");
}
Globalize.prototype.methodB = function() {
this.methodA();
};
}
Зависимости между плагинами обычно не автоматизируются, что требует явного документирования порядка подключения.
При использовании сборщиков (Webpack, Rollup, Vite) плагины часто оформляются как отдельные модули:
// plugins/number-utils.js
export default function numberUtilsPlugin(Globalize) {
Globalize.prototype.roundLocalized = function(value) {
return Math.round(this.parseNumber(value));
};
}
Импорт в приложении:
import Globalize from "globalize";
import numberUtilsPlugin from "./plugins/number-utils";
numberUtilsPlugin(Globalize);
Такой подход позволяет формировать библиотеку расширений как независимый слой над международной логикой.
Ключевым аспектом является отсутствие модификации исходного ядра. Плагины:
При необходимости переопределения используется аккуратное сохранение оригинальной реализации:
function overrideFormatNumber(Globalize) {
const original = Globalize.prototype.formatNumber;
Globalize.prototype.formatNumber = function(value) {
const result = original.call(this, value);
return `[${result}]`;
};
}
В крупных проектах плагины группируются по функциональности:
Каждая группа может иметь собственный входной модуль:
import currencyPlugins from "./plugins/currency/index.js";
import datePlugins from "./plugins/date/index.js";
currencyPlugins(Globalize);
datePlugins(Globalize);
Такая структура позволяет масштабировать локализацию без увеличения сложности основного кода.