bem-core
bem-core copied to clipboard
Use ES2015
We can autogenerate Modules-Wrapper from ES2015 syntax.
For simple cases (i.e. dom.js
):
modules.define('dom', ['jquery'], function(provide, $) {
provide({ /* ... */ });
});
import $ from 'bem:jquery'
export default { /* ... */ }
Same for elements.
For modifiers (i.e. button_type_link.js
):
modules.define('button', function(provide, Button) {
provide(Button.decl({ modName : 'type', modVal : 'link' }, { /* ... */ }));
});
import Button from 'bem:button'
export default Button.declMod({ modName : 'type', modVal : 'link' }, { /* ... */ })
Same for modifiers of elements.
For async provides (i.e. jquery.js
)
modules.define(
'jquery',
['loader__js', 'jquery__config'],
function(provide, loader, cfg) {
function doProvide(preserveGlobal) {
provide(preserveGlobal? jQuery : jQuery.noConflict(true));
}
typeof jQuery !== 'undefined'?
doProvide(true) :
loader(cfg.url, doProvide);
});
import provide from 'ym:provide'
import loader from 'bem:loader__js'
import cfg from 'bem:jquery__config'
doProvide = preserveGlobal => {
provide(preserveGlobal? jQuery : jQuery.noConflict(true));
}
typeof jQuery !== 'undefined'?
doProvide(true) :
loader(cfg.url, doProvide);
Rollback
- [ ]
i-bem-dom__events_type_dom
andi-bem-dom__events_type_bem
<-i-bem-events
,i-bem-events__dom
andi-bem-events__bem
- [ ]
ua__dom
<-page
- [ ]
jquery
,loader_type_js
cc @narqo @dfilatov @aristov
Just to be mentioned: we still need to think about this button_type_link
vs loader_type_js
case, as I'm not sure if loader_type_js
is the only strange case we have.
And still I don't like this camelcased 'EXPORT'
;)
:+1:
:fire:
@veged does this issue introduce only syntactic sugar? Y-Modules will stay as a module system?
@s-panferov YModules suppose to stay as compile target for Babel modules, cause we still have fully async modules (such as jQuery) — but for most of end users there is no need to know about YModules since they are fulfilled with ES2015 modules
@veged will interop between the new modules and raw es6 modules be possible? E.g.:
npm install moment
import Button from 'button'
import moment from 'moment'
export Button.declMod({ modName : 'type', modVal : 'link' }, { /*
use moment here: var now = moment()
*/ })
@s-panferov short answer — no
npm install ...
it's not about "raw ES6" modules, it's about npm/node.js modules system — https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Statements/import "module-name: The name of the module to import. This is a file name." — so treating module names is depends on "runtime", since for us main abstraction is BEM our modules reference to BEM-entities
for use npm-modules in our *.node.js
files you still be able to use plain require('mymodule')
@s-panferov ...but nothing coded yet, so we can think about details and change it later soon ;-)
Don't see a single problem with using ES6 modules in *.node.js
, if babel can transpile it to CJS modules, why we couldn't?
@zxqfox there is a namespace problem — we have two different global spaces BEM and NPM, so you can't just use import mymodule from 'mymodule'
and need to specify somehow from what modules namespace it should be used
we discussed about it and start to tend for something like import mymodule from 'bem:mymodule'
for BEM modules and import mymodule from 'mymodule'
for NPM modules
@veged :+1: great!
Current plan:
- Write an ENB plugin to assemble JS files in a way test-webpack-bem implementation assumes
- Write another ENB plugin to use WebPack API + Babel Loader + babel-plugin-bem
The status:
- https://github.com/bem/babel-plugin-bem
- https://github.com/bem/enb-bem-babel
- example usage: functions.vanilla.js
https://github.com/bem/bem-core/blob/6b0e3496502475c88ec3b9ec111bcbed1d806b7e/common.blocks/functions/functions.vanilla.js#L21
why not () => {}
?
@Guria i've already fixed that in 6cb6b5674ac876edb52e8c3ac809ade06b9fd116, but the main goal the task is still in progress.
I've left some suggestions. Why not to start spec also? We risk to lose the logic with our evolutionary steps.
@zxqfox what do you mean?
@veged @zxqfox i beliave it's about issues in babel-plugin-bem repo.
I have a some considerations about it:
- Please, use
!
as the delimeter instead of:
, for exampleimport $ from 'bem!jquery'
. Most loaders from other world are using this convention, so it would be easy to combine with them. - Add at the file start some hint to help distinguish that this module has special behavior. Something like this:
/* @yModule */
.
@just-boris
- can you please provide examples about "most loaders"? maybe even some standardisation attempts?
- for which modules
/* @yModule */
needed? for every js file in{common,desktop,touch}.blocks/*/
? looks a bit excessively :-/
Well, /* @yModule */
declaration is redundant. Loader can hide all implementation details, and everything will be alright.
Also, regarding async provide
. Since you have a special loader, you can place an export everywhere you want.
import loader from 'bem!loader__js';
loader('some-file.js', function(result) {
export default result;
});
@just-boris What about size of runtime? Did you compared it?
There is a talk on russian about loader__js
. Please read it again. http://habrahabr.ru/post/213627/#comment_7352647
And, as an example of strange theoretical and even pseudoscientific comparisons: http://hackhat.com/p/110/module-loader-webpack-vs-requirejs-vs-browserify/ — Webpack won, so we should use it, right?
@zxqfox I don't get what size should be compared here.
I just proposed to use !
notation to be more similar to other tools. What's wrong with it?
Just read the answer is not enough, right?
require("!style!css!less!bootstrap/less/bootstrap.less");
// => the file "bootstrap.less" in the folder "less" in the "bootstrap"
// module (that is installed from github to "node_modules") is
// transformed by the "less-loader". The result is transformed by the
// "css-loader" and then by the "style-loader".
I'll be waiting for the day when webpack will cook me a borscht!
var borscht = require('!smetaner!spetsier!salter!sugarer|potatoer!beeter!meater!water.js');
You may not use long chain of loaders if you don't need it. Also here we are talking about other tools at all.
You can achieve the same hell as well with colon :
. But !
is widely treated as splitter between module name and its loader. Even Webstorm recognizes it and resolves filenames followed after !
.
@just-boris Sure. But there is a HUGE difference between LOADERS and NAMESPACES. The first ones are functions.
Yes, we won't overuse these !
, but users will. And then we should support these projects. You just don't know this progression and how it affect overall productivity.
I'm not against webpack
, but when I see in their official docs how to load and transpile styles into js, I'm asking myself: are they mentally healthy? Is this a module loader or what? And you know, I don't like that feel.
Colon-separated namespace reminds me about XSLT. Why you want mix it up with ES2015?
placing export
anywhere will be against ES2015 standard