globalizejs / globalize

A JavaScript library for internationalization and localization that leverages the official Unicode CLDR JSON data
https://globalizejs.com
MIT License
4.8k stars 605 forks source link

Compile hundreds of plain text messages #652

Open PavelPZ opened 7 years ago

PavelPZ commented 7 years ago

For my web site I want to take advantage of compiling my formatters and messages. My web site contains:

Sorry for this stupid question: What is the strategy for design time compilation of such app?

Every compiled plain text messages produced complicated JS code, e.g. Globalize.b1130668030 = messageFormatterFn((function( ) { return function (d) { return "My plain text message 1"; }})(), Globalize("en").pluralGenerator({}));

Plain text message compilation cancels positive effect of 6 formatters and 10 messages compilation.

rxaviers commented 7 years ago

Please, can you define "cancels positive effect"? Are you talking about size and speed?

PavelPZ commented 7 years ago

Exactly (and sorry for my bad English). I like design time compilation but cannot find feasible solution for my case. Large web sites could contain thousands of messages, only few of them needs compilation (due to plural etc.)

rxaviers commented 7 years ago

Ok, I got your point: basically, the compiled output has unnecessary complexity for the plain text messages.

I agree and perhaps a better optimization could be done there, but keep in mind it doesn't affect size as it looks like because of gzip. It will take care of "getting rid of" the identical duplicate "boilerplate" around the plain text messages.

rxaviers commented 7 years ago

Ideas are welcome.

PS: Please, just let me know if you have any additional comments.

PavelPZ commented 7 years ago

Hi rxaviers,

what do you thing about following? Globalize.messageFormatter could return or string (for plain message) or formatter (for complex message).

plain message:

    en: { plain: 'My plain text message' }

compiled output:

    Globalize.a356165611 = "My plain text message";

using in the web page:

    let formatter = new Globalize('en').messageFormatter('plain');
    let translatedMessage = typeof formatter == 'string' ? formatter : formatter();

Hint: is hash for messages necessary? There could occurs collision for large site with huge amount of locales. Compiled output without hash:

    Globalize["en/plain"] = "My plain text message";
PavelPZ commented 7 years ago

... or another approach:

messages:

    let enMessages = { en: { 
      plain1: 'My plain text message 1',
      plain2: 'My plain text message 2',
      complex: 'Hello, {0}'
    }};

code to compile all messages:

    globalize.loadMessages(enMessages);
    // messageFormatter without key means "compile all messages"
    compiler.compile([new Globalize('en').messageFormatter()]) 

compiled output:

    Globalize.en.plainMessages = { 
      plain1: 'My plain text message 1',
      plain2: 'My plain text message 2'
    };
    Globalize.b1130668030 = ... //compiled 'complex' message

using in the web page:

    let plains = new Globalize('en').plainMessages;
    let translatedMessage = plains ? plains([plain]) : null;
    if (!translatedMessage) translatedMessage = new Globalize('en').messageFormatter('plain')();
necolas commented 7 years ago

Would love to see simpler compiled output, especially if it speeds up compile time and runtime performance

rxaviers commented 7 years ago

@PavelPZ, I believe the approach of using Globalize.a356165611 = "My plain text message" is viable and simpler than using the dictionary of translations. In that case, the change is: Instead of returning the cached function directly (code), (i) check whether the cached function is actually a function or string, (ii) if it's a function, return it, (iii) if it's a string, return a function that returns it. Feel free to submit a PR or let me know if you have any questions. Also consider updating/adding tests.

@necolas, thanks for your input. Do you have anything specific in mind please?