componentjs / builder2.js

builder for component
50 stars 20 forks source link

register a require call doesn't work for dynamic strings #65

Closed timaschew closed 10 years ago

timaschew commented 10 years ago

require("./lang/" + k) doesnt work

from IRC:

hey guys, need some help again component manipulates the require path after build process require("./helper.js") — becomes —> require("./lib/my-component/helper.js") within a module but for the moment library this doesn’t work for the require call which handle the lang files https://github.com/moment/moment/blob/develop/moment.js#L902 this line is not modified correctly after component build instead of require('./lang/' + k); it should be: require('moment~moment@2.7.0/lang/' + k+'.js') is the reason because it contains a variable? yes, this is the problem! component cannot transform dynamic require calls but this should not be a problem, if it starts with a dot, its local, and need a prefix, in this case: moment~moment@2.7.0

you can repdoruce it when run component install timaschew/moment@develop and then run component build

jonathanong commented 10 years ago

Nope this won't work for es6 modules either so there's no point in supporting them

timaschew commented 10 years ago

so how can that be solved?

maybe generate a file languages.js:

var requireFactory = {
  'de': function() {return require('./lang/de')},
  'en': function() {return require('./lang/en')},
  ...
}
module.exports = function(key) {
  return requireFactory[key]();
}

and then instead of require('./lang/' + k) do a require('./languages')(k)

or do you have another idea?

jonathanong commented 10 years ago

not totally sure how to do translations. @Swatinem strugged with translations for a while and i'm not sure what he's doing now.

the easiest thing for me would be to just create each translation as a separate bundle, and just add a script tag for the relevant translation.

<script src="boot.js"></script>
<script src="lang/de.js"></script>
timaschew commented 10 years ago

But this way I cannot load or change the language dynamically at runtime - without manipulate the dom to add a <script> tag, right?

jonathanong commented 10 years ago

nope. i'm generally opposed to doing stuff in runtime :P again, i'm not the expert in this haha

timaschew commented 10 years ago

okay, thanks :) btw, have you a reference that es6 don't allow dynamic require / allow only static strings?

jonathanong commented 10 years ago

don't know of any references. i just know import is supposed to be static. you could still do System.import() stuff, but that's all async and no fun

jonathanong commented 10 years ago

i don't know what any of that means =P plus i think all the harmony docs are outdated

timaschew commented 10 years ago

http://people.mozilla.org/~jorendorff/es6-draft.html#sec-imports

Syntax:

ImportDeclaration : ModuleImport import ImportClause FromClause ; import ModuleSpecifier ;

ModuleSpecifier : StringLiteral


StringLiteral means a string, no variable

Swatinem commented 10 years ago

The import syntax is completely static.

What I used to do: Include all the language files as json in component.json. And then:

var _ = require('t');
['de', 'en'].forEach(function (lang) {
_.merge(lang, require('../locale/' + lang));
});
_.lang('en');

btw, that is Swatinem/t which has a little more utilities.

Disadvantage: All locale files are baked in. Advantage: You can switch the language and re-render your templates, all dynamically.