WASM Globalization Icu
March 6, 2024 ยท View on GitHub
In WASM applications when globalization invariant mode is switched off, internalization data file is loaded. There are four basic types of these files:
icudt.dat- full dataicudt_EFIGS.dat- data for locales: "en-*", "fr-FR", "es-ES", "it-IT", and "de-DE".icudt_CJK.dat- for locales: "en" "ja", "ko", and "zh".icudt_no_CJK.dat- all locales fromicudt.dat, excluding "ja", "ko", and "zh".
Wasm Console, Wasm Browser
We can specify the file we want to load, e.g. icudt_no_CJK.dat by adding to .csproj:
<WasmIcuDataFileName>icudt_no_CJK.dat</WasmIcuDataFileName>
Only one value for WasmIcuDataFileName can be set. It can also be a custom file, created by the developer. To create a custom ICU file, see Custom ICU section below. If no WasmIcuDataFileName was specified, the application's culture will be checked and the corresponding file will be loaded, e.g. for en-US file icudt_EFIGS.dat, and for zh-CN - icudt_CJK.dat.
Custom ICU
The easiest way to build ICU is to open https://github.com/dotnet/icu/ it in Codespaces. See files in https://github.com/dotnet/icu/tree/dotnet/main/icu-filters, and read https://unicode-org.github.io/icu/userguide/icu_data/buildtool.html#locale-slicing. Build your own filter or edit the existing file.
We advise to edit the filters only by adding/removing locales from the localeFilter/includelist to avoid removing important data. We recommend not to remove "en-US" locale from the localeFilter/includelist because it is used as a fallback. Removing it for when
<PredefinedCulturesOnly>true</PredefinedCulturesOnly>: results inEncountered infinite recursion while looking for resource in System.Private.Corelib.exception- when predefined cultures only is not set: results in resolving data from ICU's
root.txtfiles, e.g.CultureInfo.DateTimeFormat.GetDayName(DateTime.Today.DayOfWeek)will return an abbreviated form:Moninstead ofMonday. Removing specific feature data might result in an exception that starts with[CultureData.IcuGetLocaleInfo(LocaleStringData)] Failed. It means you removed data necessary to extract basic information about the locale.
In the file eng/icu.mk, you can choose what filters to build. Choose the platform:
Building for Browser:
- For prerequisites run
.devcontainer/postCreateCommand.sh(it is run automatically on creation if using Codespaces) - Building:
Output is located in./build.sh /p:TargetOS=Browser /p:TargetArchitecture=wasmartifacts/bin/icu-browser-wasm.
Building for Mobiles:
- For prerequisites run:
export ANDROID_NDK_ROOT=$PWD/artifacts/ndk/ mkdir $ANDROID_NDK_ROOT wget https://dl.google.com/android/repository/android-ndk-r25b-linux.zip unzip android-ndk-r25b-linux.zip -d $ANDROID_NDK_ROOT rm android-ndk-r25b-linux.zip mv $ANDROID_NDK_ROOT/*/* $ANDROID_NDK_ROOT rmdir $ANDROID_NDK_ROOT/android-ndk-r25b - Building:
./build.sh /p:TargetOS=Android /p:TargetArchitecture=x64
Output from both builds will be located in subdirectories of artifacts/bin. Copy the generated .dat files to your project location and provide the path to it in the .csproj, e.g.:
<!-- relative path -->
<WasmIcuDataFileName>icudt_custom.dat</WasmIcuDataFileName>
<!-- OR absolute -->
<WasmIcuDataFileName>$(MSBuildThisFileDirectory)icudt_custom.dat</WasmIcuDataFileName>
Blazor
In Blazor we are loading the file based on the applications's culture.
To force the full data to be loaded, add this to your .csproj:
<BlazorWebAssemblyLoadAllGlobalizationData>true</BlazorWebAssemblyLoadAllGlobalizationData>
Custom files loading for Blazor is supported only for files with names starting with icudt, e.g. icudt_custom.dat. To load the file use BlazorIcuDataFileName property with either a path relative to your project or a full path, like for WasmIcuDataFileName.