Библиотека Globalize опирается на данные CLDR (Unicode Common Locale Data Repository), что делает её мощным инструментом интернационализации, но одновременно создаёт специфические требования к сборке. В отличие от лёгких i18n-решений, Globalize не работает без явной загрузки данных локалей, поэтому конфигурация Webpack становится частью архитектуры интернационализации приложения.
Ключевая особенность заключается в том, что Globalize не поставляет готовых локализованных пакетов «из коробки». Все данные (числа, даты, валюты, правила pluralization) подключаются вручную, что требует контроля над зависимостями на этапе сборки.
Globalize построен модульно. Базовая библиотека не содержит локализованных данных и работает только как слой API.
Основные группы зависимостей:
globalize,
cldrjsWebpack должен учитывать, что ни один из модулей не является самодостаточным без данных CLDR.
Типичная структура зависимостей:
npm install globalize cldrjs
Дополнительно часто требуются пакеты с данными CLDR:
npm install cldr-data
При этом важно понимать, что cldr-data — это не
runtime-библиотека, а источник JSON-файлов для сборки.
Webpack не обрабатывает CLDR автоматически. Данные должны быть явно импортированы.
Типичная структура импорта:
import Globalize from "globalize";
import Cldr from "cldrjs";
// supplemental data
import likelySubtags from "cldr-data/supplemental/likelySubtags";
import numberingSystems from "cldr-data/supplemental/numberingSystems";
import currencyData from "cldr-data/supplemental/currencyData";
import timeData from "cldr-data/supplemental/timeData";
// locale data
import numbers from "cldr-data/main/ru/numbers";
import currencies from "cldr-data/main/ru/currencies";
import caGregorian from "cldr-data/main/ru/ca-gregorian";
import dateFields from "cldr-data/main/ru/dateFields";
После импорта данные необходимо загрузить в CLDR:
Cldr.load(
likelySubtags,
numberingSystems,
currencyData,
timeData,
numbers,
currencies,
caGregorian,
dateFields
);
Globalize.loadTimeZone();
Globalize.locale("ru");
Webpack в этом случае выступает лишь как транспилятор и бандлер, не вмешиваясь в структуру данных.
Минимальная конфигурация Webpack учитывает необходимость корректной обработки JSON и ES-модулей.
const path = require("path");
module.exports = {
mode: "production",
entry: "./src/index.js",
output: {
filename: "bundle.js",
path: path.resolve(__dirname, "dist")
},
module: {
rules: [
{
test: /\.js$/,
exclude: /node_modules/,
use: {
loader: "babel-loader"
}
}
]
},
resolve: {
extensions: [".js"]
}
};
Дополнительная конфигурация обычно не требуется, так как CLDR поставляется в виде готовых JSON-модулей.
Критическая проблема производительности возникает при включении всех локалей одновременно. CLDR содержит большой объём данных, и их бездумное подключение приводит к увеличению bundle size.
Практика разделения:
Webpack позволяет реализовать это через dynamic imports:
async function loadLocale(locale) {
switch (locale) {
case "ru":
await import("cldr-data/main/ru/numbers");
await import("cldr-data/main/ru/currencies");
await import("cldr-data/main/ru/ca-gregorian");
break;
case "en":
await import("cldr-data/main/en/numbers");
await import("cldr-data/main/en/currencies");
await import("cldr-data/main/en/ca-gregorian");
break;
}
}
Такой подход позволяет Webpack автоматически создавать отдельные чанки для каждой локали.
Code splitting является основным механизмом оптимизации Globalize-интеграции.
Пример динамической загрузки:
import Globalize from "globalize";
import Cldr from "cldrjs";
async function initLocale(locale) {
const [
likelySubtags,
numbers,
currencies,
gregorian
] = await Promise.all([
import("cldr-data/supplemental/likelySubtags"),
import(`cldr-data/main/${locale}/numbers`),
import(`cldr-data/main/${locale}/currencies`),
import(`cldr-data/main/${locale}/ca-gregorian`)
]);
Cldr.load(likelySubtags.default, numbers.default, currencies.default, gregorian.default);
Globalize.locale(locale);
}
Webpack интерпретирует такие конструкции как точки разбиения бандла.
Globalize может значительно увеличивать итоговый размер сборки, если не контролировать импорт модулей.
Основные техники оптимизации:
1. Импорт только необходимых модулей Globalize
import number from "globalize/number";
import date from "globalize/date";
Вместо:
import Globalize from "globalize";
2. Tree shaking
Webpack 4+ способен удалять неиспользуемые части, но только при ESM-импортах:
optimization: {
usedExports: true,
sideEffects: false
}
3. Разделение vendor chunk
optimization: {
splitChunks: {
cacheGroups: {
vendor: {
test: /node_modules/,
name: "vendors",
chunks: "all"
}
}
}
}
CLDR данные — это JSON-файлы, и Webpack обрабатывает их через встроенный JSON loader.
В некоторых конфигурациях требуется явное указание:
module: {
rules: [
{
test: /\.json$/,
type: "json"
}
]
}
Webpack позволяет задавать глобальные параметры локали на этапе сборки:
const webpack = require("webpack");
module.exports = {
plugins: [
new webpack.DefinePlugin({
DEFAULT_LOCALE: JSON.stringify("ru")
})
]
};
Дальнейшая инициализация:
Globalize.locale(DEFAULT_LOCALE);
Поддержка нескольких языков требует изоляции данных CLDR.
Структура загрузки:
const locales = {
ru: () => import("cldr-data/main/ru/ca-gregorian"),
en: () => import("cldr-data/main/en/ca-gregorian"),
de: () => import("cldr-data/main/de/ca-gregorian")
};
Каждая локаль становится независимым чанком, что уменьшает стартовый вес приложения.
Основные факторы производительности:
Webpack не оптимизирует CLDR автоматически, поэтому архитектура загрузки определяет итоговую скорость приложения.
Типовые проблемы при интеграции:
Cldr.load() в разных модуляхКаждая из этих ошибок приводит к увеличению bundle size и замедлению инициализации интернационализации.
Типичная структура:
src/
i18n/
cldr.js
locales/
ru.js
en.js
core/
globalize.js
index.js
Файл инициализации CLDR:
// i18n/cldr.js
import Cldr from "cldrjs";
export function setupCldr(data) {
Cldr.load(...data);
}
Production-сборка требует минимизации и строгого контроля зависимостей:
module.exports = {
mode: "production",
devtool: false,
optimization: {
minimize: true,
usedExports: true,
sideEffects: true,
splitChunks: {
chunks: "all"
}
}
};
Особое внимание уделяется тому, чтобы CLDR данные не попадали в несколько чанков одновременно.
С точки зрения Webpack Globalize формирует трёхслойную модель:
Webpack выступает связующим слоем, обеспечивая разделение, ленивую загрузку и оптимизацию доставки локализационных данных без изменения логики самой библиотеки