These are chat archives for ractivejs/ractive

6th
Jul 2018
Joseph
@fskreuz
Jul 06 2018 12:17
@shakeelosmani If it helps, I used to work on monorepo-ing Ractive a few months back. https://github.com/fskreuz/ractive-monorepo/tree/dev/packages/node_modules/%40ractivejs
Should contain some (a bunch of) examples. TL;DR:
  • I write in ES. Export the plugin(s) from the module.
  • I let Rollup handle creating the transpiled ES and UMD (AMD/CJS/globals) versions.
  • Each plugin is an src/index.js accompanied by an src/rollup.config.js. Same goes for tests.
You can ignore the monorepo setup and look at the individual plugin structure. I think the simplest one (and was the reference for the rest) is the port of adaptor-promise
Joseph
@fskreuz
Jul 06 2018 12:51
I forgot a few more points. The build and publish portions are like:
  • Build the module into a dist directory, pre-bundled, pre-transpiled (keeping third-party deps external)
  • Point the package.json main to the built UMD, and module to the built ES.
  • Publish to npm
  • ???
  • Profit :tada:
Shakeel Osmani
@shakeelosmani
Jul 06 2018 12:53
@fskreuz thanks :smile:
Joseph
@fskreuz
Jul 06 2018 12:54
If you want to practice publishing without ever sending anything to npm, use tools like this one https://github.com/verdaccio/verdaccio
It creates a local instance of an npm-like server. You publish to it instead of npm.
Cerem Cem ASLAN
@ceremcem
Jul 06 2018 15:32
@fskreuz I remember you told about language selection mechanism
do you think this is somewhat close what you mentioned: Playground
another question: (how) can we define a "curried-like" function which will observe some ractive variables and update its output on change?
// instead of writing this:
myFunc("some string", @global.lang);

// I want to write this: 
myFunc("some string");  // and still want the output to be updated when "@global.lang" is changed
Joseph
@fskreuz
Jul 06 2018 15:50
It's more like this. Language sets (JSON files) loaded on the fly and set somewhere visible to all like @shared.
Cerem Cem ASLAN
@ceremcem
Jul 06 2018 15:54
now I remember
Joseph
@fskreuz
Jul 06 2018 16:03
For curry, probably something like data functions or computed props. But you'd need to construct a function for each item, which isn't very... convenient. :grin:
I like the @shared way better because all you do is drop in a blob of JSON and everything just re-renders on switch. Plus you can cache the data too if you want. :smile:
Cerem Cem ASLAN
@ceremcem
Jul 06 2018 16:10
my most important design consideration was that the current code should be able to update incrementally and partially
which means, if we have a button displaying a string like <button>Hello world!</button> should be able to upgrade to a multi-language button when we surround the string with {{i18n(" and ")}}, even without defining a proper translation (as the original input is the fallback option)
Cerem Cem ASLAN
@ceremcem
Jul 06 2018 16:16
so upgrading a component to a multi-language component would be less work to do
Joseph
@fskreuz
Jul 06 2018 16:20
Yeah, the approach I took was to force the existence of translations :grin:
The problem I have with having fallbacks is that developers become too lax doing translations. What ends up happening is that finding things that are not translated becomes a pain, and translation files (the JSON) become structurally different, become very "holey" (some keys missing, not sorted, you can't just diff the files for missing things).
And having fallback text on the template is one more thing to take care of. :grimacing:
Cerem Cem ASLAN
@ceremcem
Jul 06 2018 16:25
...and that was a feature, not bug :))
Sometimes being too flexible is just asking for trouble.
Cerem Cem ASLAN
@ceremcem
Jul 06 2018 16:27
the natural result of "fallback translation" is that developer may only write the message by surrounding {{lang("...")}} and let the normal users (visitors?) add the translations with a GUI
Joseph
@fskreuz
Jul 06 2018 16:29
Well, nothing really prevents you from deep merging the default and the selected sets, i.e. const resultingStuff = deepMerge(lang.default, lang.fr). Anything missing in the fr JSON would just let the default one shine through.
Cerem Cem ASLAN
@ceremcem
Jul 06 2018 16:30
that's correct
Joseph
@fskreuz
Jul 06 2018 16:30
And on the template, it would be the same old {{@shared.i18n.thatText}} - you'll never have to touch this ever again once set. :tada:
But yeah, there's a beeellion ways to implement translations in JS :grin: I used to use decorators for this stuff (also inspired by angular-translate) and that had its own share of problems.
Cerem Cem ASLAN
@ceremcem
Jul 06 2018 16:33
does angular use translator components? or did I misunderstand that?
Joseph
@fskreuz
Jul 06 2018 16:36
Angular defines components/custom elements and directives/decorators the same way, so I guess that's a yes. :smile:
Cerem Cem ASLAN
@ceremcem
Jul 06 2018 16:37
there are 2 distinct problems with these 2 distinct approaches and let me ask your opinion:
  1. If we choose {{@shared.i18n.MyVeryLongErrorOrSuccesMessageThatExplainsBlahBlah}} makes the work twice: 1. developer has to write the MyVeryLong... part and navigate to the dictionary and add the string there.
(or should it be error codes? like ECONNRESET, ERR_CRYPTO_TIMING_SAFE_EQUAL_LENGTH?)
Joseph
@fskreuz
Jul 06 2018 16:40
Yep, interpolator on template and the key in the JSON somewhere else. I just write in regular camelCase, short but verbose.
In the long run, you'll only ever do textual changes. You'll only ever visit the JSON post-dev.
Cerem Cem ASLAN
@ceremcem
Jul 06 2018 16:41
this "write the message code, navigate to dictionary, add the translation, navigate back to the code" pattern may make the developer disrupted
Joseph
@fskreuz
Jul 06 2018 16:41
Unless you open the JSON and the code side-by-side :grin:
Cerem Cem ASLAN
@ceremcem
Jul 06 2018 16:41
:)
actually both approaches are topologically the same
let me explain
{{@shared.i18n.MyErrorCode}}
{{@shared.i18n.MyDefinitiveErrorCode}}
{{@shared.i18n["My definitive error code"]}}
{{@shared.i18n["My actual error message"]}}
here "My actual error message" should be treated as "MyErrorCode" and any typo fixes must be made in the dictionary
Cerem Cem ASLAN
@ceremcem
Jul 06 2018 16:50
which means "you won't have to touch your error messages again" :)
kouts
@kouts
Jul 06 2018 17:54
I use a global _t object for translations
simple stuff though just plain ol'strings