aurelia / i18n

A plugin that provides i18n support.
MIT License
93 stars 70 forks source link

Using aurelia-i18n with webpack + typescript + aurelia's own loader #268

Open alankila opened 6 years ago

alankila commented 6 years ago

I'm submitting a bug report Note: this is really a request for clarification of documentation.

Please tell us about your environment:

Current behavior: I was having a hard time figuring out how to bundle localization files with webpack using aurelia's own loader. The instructions on Aurelia I18N page do not really cover how tell webpack to bundle my translation files into the application bundle. If they are not bundled, then i18next of course fails resolving them at runtime.

Basically, no matter what I did, I could not require/import the .json files from either TS or template files, and I had no idea what to write to webpack config to make it bundle these files either. I was, however, able to determine that aurelia-i18n itself was working fine. Therefore, I designed a workaround.

Firstly, I converted the localization files from .json to .ts files, so that I could import them as regular modules. Basically, I just prepended "export default" in front of the JSON and changed the file suffix.

Then, I wrote a custom backend for i18next that does exactly this:

import fi from './fi';
import sv from './sv';
import en from './en';

export class LocaleBackend {
  type = "backend";

  init() {
  }

  read(language: string, namespace: string, callback: (error: string | undefined, data: {}) => void) {
    if (language == "fi") {
      callback(undefined, fi);
      return;
    }
    if (language == "sv") {
      callback(undefined, sv);
      return;
    }
    callback(undefined, en);
  }
}

This class was used as backend for i18next in place of the Backend.with(aurelia.loader) that I had before:

    instance.i18next.use(new LocaleBackend());
zewa666 commented 6 years ago

Thanks for looking into this. Sadly I cant really help with this one as Im trying to avoid using webpack wherever I can so my knowledge is too limited. Raising this issue over at Gitter or our Discourse forum should help bringing people with a better expertise.

doktordirk commented 6 years ago

@alankila maybe see https://discourse.aurelia.io/t/solved-how-to-use-i18n-with-backend-in-au-cli-webpack-projects/542/7

doktordirk commented 6 years ago

@alankila @zewa666 previous didn't work for me in the end.

but i did get https://github.com/atroo/i18next-resource-store-loader to work and have the translation.jsons bundled in the app bundle. no webpack.config edits needed (as a json loader is usually included already)

sample file structure:

main.js
config\locale\en\tanslation.json
config\locale\de\tanslation.json
config\locale\index.js //<-- just an empty file as root pointer for the resource store loader

in main.js

import resBundle from "i18next-resource-store-loader!./config/locale/index.js" //<--root pointer relative to main

export function configure(aurelia) {
  aurelia.use
//...
    /* @see https://github.com/aurelia/i18n */
    .plugin(PLATFORM.moduleName('aurelia-i18n'), instance => {
      // adapt options to your needs (see http://i18next.com/pages/doc_init.html)

      let language = localStorage.getItem('language');

      return instance.setup({
        resources: resBundle,
        lng        : language || appConfig.defaultLocale.language,
        attributes : ['t'],
        fallbackLng: language || appConfig.defaultLocale.language,
        debug      : false,
      });
    })

edit: type: ‘javascript/autoalso works. see https://discourse.aurelia.io/t/solved-aurelia-i18n-webpack-4-help-needed/

Mohsen-Bazmi commented 2 years ago

I ended up referencing a javascript file. Is there anything wrong with that? It seems more explicit and easier to reason about.

Configuration:

    import translarionResource from "./locales/translation"
...
   aurelia.use.plugin(PLATFORM.moduleName('aurelia-i18n'), (instance: I18N) => {
    let aliases = ['t', 'i18n'];

    TCustomAttribute.configureAliases(aliases);

    return instance.setup({
      debug: false,
      resources:  translarionResource,
      lng: 'en',
      fallbackLng: 'en',
      defaultNS: 'global',
      attributes: aliases,
    });
  });

./locales/translation.js:

export default {
  en: {
    global: {
      "userName": "User Name",
     ...
    }
}
zewa666 commented 2 years ago

totally fine. the only downside could be if you load multiple translations that all are eagerly loaded and increase bandwidth