This commit is contained in:
David Štaleker
2025-07-18 05:33:16 +02:00
parent 401a367e5d
commit db0cc8d3de
14776 changed files with 9251484 additions and 0 deletions

View File

@@ -0,0 +1,3 @@
dist/
node_modules
.tmp-globalize-webpack

View File

@@ -0,0 +1,74 @@
# Globalize App example using webpack
This example demonstrates how to integrate Globalize with Webpack in your
Application. If you already have an existing Application using Webpack stack,
this example should as well provide you guidance on how to integrate Globalize.
It focuses on the [Globalize Webpack Plugin][], which automates data loading
(CLDR and app messages) during development and automates Globalize compilation
and the usage of Globalize runtime modules for production. It assumes knowledge
of Globalize, npm, and Webpack usage basics.
## Requirements
**1. Install app development dependencies**
This example uses `npm` to download the app development dependencies (i.e.,
Globalize, CLDR data, Cldrjs, Webpack, [Globalize Webpack Plugin][], and
others).
```
npm install
```
## Running the example
### Development mode
```
npm start
```
1. Start a server by running `npm start`, which uses webpack's live reload HMR
(Hot Module Replacement). See `package.json` to understand the actual shell
command that is used.
1. Point your browser at `http://localhost:8080`. Note that your browser will
automatically reload on any changes made to the application code (`app/*.js`
files). Also note that for faster page reload, formatters are created
dynamically and automatically by the [Globalize Webpack Plugin][].
1. Note you can specify the development locale of your choice by setting the
`developmentLocale` property of the Globalize Webpack Plugin on the Webpack
config file.
1. Note that CLDR data and your messages data are automatically loaded by the
[Globalize Webpack Plugin][].
1. Understand the demo by reading the source code. We have comments there for
you.
### Production mode
```
npm run build
```
1. Generate the compiled bundles by running `npm run build`, which will be
created at `./dist`. Note the production bundles are split into three chunks:
(a) vendor, which holds third-party libraries, which in this case means
Globalize Runtime modules, (b) i18n precompiled data, which means the minimum
yet sufficient set of precompiled i18n data that your application needs (one
file for each supported locale), and (c) app, which means your application code.
Also note that all the production code is already minified using UglifyJS. See
`package.json` to understand the actual shell command that is used.
1. Note that your formatters are already precompiled. This is
obvious, but worth emphasizing. It means your formatters are prebuilt, so no client
CPU clock is wasted to generate them and no CLDR or messages data needs to be
dynamically loaded. It means fast to load code (small code) and fast to run
code.
1. Point your browser at `./dist/index.html` to run the application using the
generated production files. Edit this file to display the application using a
different locale (source code has instructions).
1. Understand the demo by reading the source code. We have comments there for
you.
For more information about the plugin, see the [Globalize Webpack Plugin][]
documentation.
[Globalize Webpack Plugin]: https://github.com/rxaviers/globalize-webpack-plugin

View File

@@ -0,0 +1,89 @@
var Globalize = require( "globalize" );
var startTime = new Date();
// Standalone table.
var numberFormatter = Globalize.numberFormatter({ maximumFractionDigits: 2 });
document.getElementById( "number" ).textContent = numberFormatter( 12345.6789 );
var numberCompactFormatter = Globalize.numberFormatter({
compact: "short",
minimumSignificantDigits: 1,
maximumSignificantDigits: 3
});
document.getElementById( "number-compact" ).textContent = numberCompactFormatter( 12345.6789 );
var currencyFormatter = Globalize.currencyFormatter( "USD" );
document.getElementById( "currency" ).textContent = currencyFormatter( 69900 );
var dateFormatter = Globalize.dateFormatter({ datetime: "medium" });
document.getElementById( "date" ).textContent = dateFormatter( new Date() );
var dateWithTimeZoneFormatter = Globalize.dateFormatter({
datetime: "full",
timeZone: "America/Sao_Paulo"
});
document.getElementById( "date-time-zone" ).textContent = dateWithTimeZoneFormatter( new Date() );
var _dateToPartsFormatter = Globalize.dateToPartsFormatter({ datetime: "medium" });
var dateToPartsFormatter = function( value ) {
return _dateToPartsFormatter( value, {
datetime: "medium"
}).map(function( part ) {
switch(part.type) {
case "month": return "<strong>" + part.value + "</strong>";
default: return part.value;
}
}).reduce(function( memo, value ) {
return memo + value;
});
};
document.getElementById( "date-to-parts" ).innerHTML = dateToPartsFormatter( new Date() );
var relativeTimeFormatter = Globalize.relativeTimeFormatter( "second" );
document.getElementById( "relative-time" ).textContent = relativeTimeFormatter( 0 );
var unitFormatter = Globalize.unitFormatter( "mile/hour", { form: "short" } );
document.getElementById( "unit" ).textContent = unitFormatter( 60 );
// Messages.
document.getElementById( "intro-1" ).textContent = Globalize.formatMessage( "intro-1" );
document.getElementById( "number-label" ).textContent = Globalize.formatMessage( "number-label" );
document.getElementById( "number-compact-label" ).textContent = Globalize.formatMessage( "number-compact-label" );
document.getElementById( "currency-label" ).textContent = Globalize.formatMessage( "currency-label" );
document.getElementById( "date-label" ).textContent = Globalize.formatMessage( "date-label" );
document.getElementById( "date-time-zone-label" ).textContent = Globalize.formatMessage( "date-time-zone-label" );
document.getElementById( "date-to-parts-label" ).textContent = Globalize.formatMessage( "date-to-parts-label" );
document.getElementById( "relative-time-label" ).textContent = Globalize.formatMessage( "relative-time-label" );
document.getElementById( "unit-label" ).textContent = Globalize.formatMessage( "unit-label" );
document.getElementById( "message-1" ).textContent = Globalize.formatMessage( "message-1", {
currency: currencyFormatter( 69900 ),
date: dateFormatter( new Date() ),
number: numberFormatter( 12345.6789 ),
relativeTime: relativeTimeFormatter( 0 ),
unit: unitFormatter( 60 )
});
document.getElementById( "message-2" ).textContent = Globalize.formatMessage( "message-2", {
count: 3
});
// Display demo.
document.getElementById( "requirements" ).style.display = "none";
document.getElementById( "demo" ).style.display = "block";
// Refresh elapsed time
setInterval(function() {
var elapsedTime = +( ( startTime - new Date() ) / 1000 ).toFixed( 0 );
document.getElementById( "date" ).textContent = dateFormatter( new Date() );
document.getElementById( "date-time-zone" ).textContent = dateWithTimeZoneFormatter( new Date() );
document.getElementById( "date-to-parts" ).innerHTML = dateToPartsFormatter( new Date() );
document.getElementById( "relative-time" ).textContent = relativeTimeFormatter( elapsedTime );
document.getElementById( "message-1" ).textContent = Globalize.formatMessage( "message-1", {
currency: currencyFormatter( 69900 ),
date: dateFormatter( new Date() ),
number: numberFormatter( 12345.6789 ),
relativeTime: relativeTimeFormatter( elapsedTime ),
unit: unitFormatter( 60 )
});
}, 1000);

View File

@@ -0,0 +1,71 @@
<!doctype html>
<html>
<head>
<meta charset="utf-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<title>Globalize App example using Webpack</title>
</head>
<body>
<h1>Globalize App example using Webpack</h1>
<div id="requirements">
<h2>Requirements</h2>
<ul>
<li>Read README.md for instructions on how to run the demo.
</li>
</ul>
</div>
<div id="demo" style="display: none">
<p id="intro-1">Use Globalize to internationalize your application.</p>
<table border="1" style="marginBottom: 1em;">
<tbody>
<tr>
<td><span id="number-label">Standalone Number</span></td>
<td>"<span id="number"></span>"</td>
</tr>
<tr>
<td><span id="number-compact-label">Standalone Number (compact form)</span></td>
<td>"<span id="number-compact"></span>"</td>
</tr>
<tr>
<td><span id="currency-label">Standalone Currency</span></td>
<td>"<span id="currency"></span>"</td>
</tr>
<tr>
<td><span id="date-label">Standalone Date</span></td>
<td>"<span id="date"></span>"</td>
</tr>
<tr>
<td><span id="date-time-zone-label">Standalone Date (in a specific IANA time zone, e.g., America/Sao_Paulo)</span></td>
<td>"<span id="date-time-zone"></span>"</td>
</tr>
<tr>
<td><span id="date-to-parts-label">Standalone Date (note the highlighted month, the markup was added using formatDateToParts)</span></td>
<td>"<span id="date-to-parts"></span>"</td>
</tr>
<tr>
<td><span id="relative-time-label">Standalone Relative Time</span></td>
<td>"<span id="relative-time"></span>"</td>
</tr>
<tr>
<td><span id="unit-label">Standalone Unit</span></td>
<td>"<span id="unit"></span>"</td>
</tr>
</tbody>
</table>
<p id="message-1">
An example of a message using mixed number "{number}", currency "{currency}", date "{date}", relative time "{relativeTime}", and unit "{unit}".
</p>
<p id="message-2">
An example of a message with pluralization support:
{count, plural,
one {You have one remaining task}
other {You have # remaining tasks}
}.
</p>
</div>
</body>
</html>

View File

@@ -0,0 +1,25 @@
{
"ar": {
"intro-1": "‫استخدم Globalize لتدويل تطبيقك.",
"number-label": "رقم",
"number-compact-label": "الرقم (شكل مدمج)",
"currency-label": "عملة",
"date-label": "تاريخ",
"date-time-zone-label": "التاريخ (في منطقة زمنية محددة ل إيانا، على سبيل المثال، America/Sao_Paulo)",
"date-to-parts-label": "التاريخ (لاحظ الشهر القوي، تمت إضافة الترميز باستخدام formatDateToParts)",
"relative-time-label": "الوقت النسبي",
"unit-label": "وحدة القياس",
"message-1": "مثال علي رسالة باستخدام رقم مختلط \"{number}\", عملة \"{currency}\", تاريخ \"{date}\", وقت نسبي \"{relativeTime}\", و وحدة قياس \"{unit}\" .",
"message-2": [
"مثال على رسالة بدعم صيغة الجمع:",
"{count, plural,",
" zero {لا يوجد لديك اي مهام متبقية}",
" one {لديك مهمة واحدة متبقية}",
" two {لديك اثنين من المهام المتبقية}",
" few {لديك # من المهام المتبقية}",
" many {لديك # من المهام المتبقية}",
" other {لديك # من المهام المتبقية}",
"}."
]
}
}

View File

@@ -0,0 +1,21 @@
{
"de": {
"intro-1": "Verwenden Sie Globalize um Ihre Anwendung zu internationalisieren.",
"number-label": "Zahl",
"number-compact-label": "Zahl (kompakte Form)",
"currency-label": "Währung",
"date-label": "Datum",
"date-time-zone-label": "Datum (in einer bestimmten IANA-Zeitzone, z. B. America/Sao_Paulo)",
"date-to-parts-label": "Datum (beachten Sie den hervorgehobenen Monat, das Markup wurde mit dateToPartsFormatter hinzugefügt)",
"relative-time-label": "Relative Zeit",
"unit-label": "Einheit",
"message-1": "Ein Beispiel mit Zahl \"{number}\", Währung \"{currency}\", Datum \"{date}\", relative Zeit \"{relativeTime}\", und Einheit \"{unit}\".",
"message-2": [
"Ein Beispieltext mit Unterstützung von Plural Formen: ",
"{count, plural,",
" one {Sie haben noch eine Aufgabe}",
" other {Sie haben noch # verbliebende Aufgaben}",
"}."
]
}
}

View File

@@ -0,0 +1,21 @@
{
"en": {
"intro-1": "Use Globalize to internationalize your application.",
"number-label": "Number",
"number-compact-label": "Number (compact form)",
"currency-label": "Currency",
"date-label": "Date",
"date-time-zone-label": "Date (in a specific IANA time zone, e.g., America/Sao_Paulo)",
"date-to-parts-label": "Date (note the highlighted month, the markup was added using formatDateToParts)",
"relative-time-label": "Relative Time",
"unit-label": "Unit",
"message-1": "An example of a message using mixed number \"{number}\", currency \"{currency}\", date \"{date}\", relative time \"{relativeTime}\", and unit \"{unit}\".",
"message-2": [
"An example of a message with pluralization support:",
"{count, plural,",
" one {You have one remaining task}",
" other {You have # remaining tasks}",
"}."
]
}
}

View File

@@ -0,0 +1,21 @@
{
"es": {
"intro-1": "Usa Globalize para internacionalizar tu aplicación.",
"number-label": "Número",
"number-compact-label": "Número (forma compacta)",
"currency-label": "Moneda",
"date-label": "Fecha",
"date-time-zone-label": "Fecha (en una zona horaria IANA específica, por ejemplo, America/Sao_Paulo)",
"date-to-parts-label": "Fecha (note el mes destacado en negro, el marcador de html se agregó utilizando dateToPartsFormatter)",
"relative-time-label": "Tiempo Relativo",
"unit-label": "Unidad",
"message-1": "Un ejemplo de mensaje usando números mixtos \"{number}\", monedas \"{currency}\", fechas \"{date}\", tiempo relativo \"{relativeTime}\", y unidades \"{unit}\".",
"message-2": [
"Un ejemplo de mensaje con soporte de pluralización:",
"{count, plural,",
" one {Tienes una tarea restante}",
" other {Tienes # tareas restantes}",
"}."
]
}
}

View File

@@ -0,0 +1,21 @@
{
"pt": {
"intro-1": "Use o Globalize para internacionalizar sua aplicação.",
"number-label": "Número",
"number-compact-label": "Número (forma compacta)",
"currency-label": "Moeda",
"date-label": "Data",
"date-time-zone-label": "Data (em um fuso horário IANA específico, por exemplo, America/Sao_Paulo)",
"date-to-parts-label": "Data (note o mês em negrito, a marcação HTML foi adicionada usando formatDateToParts)",
"relative-time-label": "Tempo relativo",
"unit-label": "Unit",
"message-1": "Um exemplo de mensagem com mistura de número \"{number}\", moeda \"{currency}\", data \"{date}\", tempo relativo \"{relativeTime}\", e unidade \"{unit}\".",
"message-2": [
"Um exemplo de message com suporte a pluralização:",
"{count, plural,",
" one {Você tem uma tarefa restante}",
" other {Você tem # tarefas restantes}",
"}."
]
}
}

View File

@@ -0,0 +1,23 @@
{
"ru": {
"intro-1": "Используйте Globalize для интернационализиции вашего приложения.",
"number-label": "Число",
"number-compact-label": "Число (компактная форма)",
"currency-label": "Валюта",
"date-label": "Дата",
"date-time-zone-label": "Дата (в определенном часовом поясе IANA, например, America/Sao_Paulo)",
"date-to-parts-label": "Дата (обратите внимание на сильный месяц, разметка была добавлена с помощью formatDateToParts)",
"relative-time-label": "Относительное время",
"unit-label": "Единица измерения",
"message-1": "Пример сообщения с числом \"{number}\", валютой \"{currency}\", датой \"{date}\", относительным временем \"{relativeTime}\" и единицей измерения \"{unit}\".",
"message-2": [
"Пример сообщения с поддержкой множественного числа:",
"{count, plural,",
" one {У вас осталась одна задача}",
" many {У вас осталось # задач}",
" few {У вас осталось # задачи}",
" other {У вас осталось # задачи}",
"}."
]
}
}

View File

@@ -0,0 +1,20 @@
{
"zh": {
"intro-1": "使用Globalize的国际化应用程序",
"number-label": "号码",
"number-compact-label": "编号(紧凑形式)",
"currency-label": "币",
"date-label": "迄今",
"date-time-zone-label": "日期在特定的IANA时区例如America / Sao_Paulo",
"date-to-parts-label": "日期注意强烈的月份使用formatDateToParts添加标记",
"relative-time-label": "相对时间",
"unit-label": "单元",
"message-1": "使用混合数\"{number}\",货币\"{currency}\",日期\"{date}\",相对时间\"{relativeTime}\"和单元\"{unit}\"的消息的例子。",
"message-2": [
"与多元化支持消息的例子:",
"{count, plural,",
" other {你有#剩下的任务}",
"}."
]
}
}

View File

@@ -0,0 +1,17 @@
{
"private": true,
"devDependencies": {
"cldr-data": ">=25",
"globalize": "^1.3.0",
"globalize-webpack-plugin": "^2.1.0",
"html-webpack-plugin": "^2.30.1",
"iana-tz-data": "^2017.1.0",
"webpack": "^3.11.0",
"webpack-dev-server": "^2.11.1"
},
"scripts": {
"start": "webpack-dev-server --config webpack-config.js --hot --progress --colors --inline",
"build": "NODE_ENV=production webpack --config webpack-config.js"
},
"cldr-data-urls-filter": "(core|dates|numbers|units)"
}

View File

@@ -0,0 +1,63 @@
var webpack = require( "webpack" );
var path = require("path");
var CommonsChunkPlugin = require( "webpack/lib/optimize/CommonsChunkPlugin" );
var HtmlWebpackPlugin = require( "html-webpack-plugin" );
var GlobalizePlugin = require( "globalize-webpack-plugin" );
var production = process.env.NODE_ENV === "production";
var globalizeCompiledDataRegex = new RegExp( /^(globalize\-compiled\-data)\-\S+$/ );
function subLocaleNames( name ) {
return name.replace( globalizeCompiledDataRegex, "$1" );
}
module.exports = {
entry: {
main: "./app/index.js",
},
output: {
path: path.join( __dirname, production ? "./dist" : "./tmp" ),
publicPath: production ? "" : "http://localhost:8080/",
chunkFilename: "[name].[chunkhash].js",
filename: production ? "[name].[chunkhash].js" : "app.js"
},
resolve: {
extensions: [ "*", ".js" ]
},
plugins: [
new HtmlWebpackPlugin({
template: "./index-template.html",
// filter to a single compiled globalize language
// change 'en' to language of choice or remove inject all languages
// NOTE: last language will be set language
chunks: [ "vendor", "globalize-compiled-data-en", "main" ],
chunksSortMode: function ( c1, c2 ) {
var orderedChunks = [ "vendor", "globalize-compiled-data", "main" ];
var o1 = orderedChunks.indexOf( subLocaleNames( c1.names[ 0 ]));
var o2 = orderedChunks.indexOf( subLocaleNames( c2.names[ 0 ]));
return o1 - o2;
},
}),
new GlobalizePlugin({
production: production,
developmentLocale: "en",
supportedLocales: [ "ar", "de", "en", "es", "pt", "ru", "zh" ],
messages: "messages/[locale].json",
output: "i18n/[locale].[chunkhash].js"
})
].concat( production ? [
new CommonsChunkPlugin({
name: "vendor",
minChunks: function(module) {
return (
module.context && module.context.indexOf("node_modules") !== -1
);
}
}),
new webpack.optimize.UglifyJsPlugin({
compress: {
warnings: false
}
})
] : [] )
};