BEM. More than methodology, less than technology

Nowadays front-end developers know that BEM is a methodology used to construct CSS class names which are independent of each other. Its birthplace is Yandex which I am currently working for. Here at Yandex BEM is not only a methodology but also a whole infrastructure, server-side templating, build process, client-side framework, library of reusable UI components and much more. One can argue if is this useful approach or not. But what I wanted to show you is just one thing which can be useful in your projects.

Dependencies problem

Let’s say you have a bunch of UI components in your project and you want to use BEM class naming. Then you should probably organize your project filesystem to store all these components separately. Let’s say you decided to store all these components inside app/components directory.

Then you probably need to concat and build all your static files into one build.js or build.css etc. If you are using gulp all you need is a Gulpfile like this:

All right, this works. You can also notice that gulp build process respects order from gulp.src(…) and if you need to use some kind of per-project variables/mixins/globals file you can just put it to the top of gulp.src(…).

But what if you have UI component which CSS depends on another? This could be a block modifier, which sets color property and there’s also another block modifier which also sets color property, and since CSS selectors weight is the same the resulting color is used from the selector which stands closer to the end of built CSS file.

Another example is BEM mixin: you have UI component “sample” with its own behavior which needs to look like UI component “button”. So you have an HTML like this: <div class=”sample button”>…</div> but if both “sample” and “button” have CSS property color set, then order of built files matters.

You can also have a Javascript UI component which depends on another UI component which must be defined closer to the top. How can you handle this problem?

Managing dependencies with deps.js

BEM infrastructure introduces deps.js files for this. The whole idea is that you have a directory for your UI component (let’s say it is app/components/button) and you put files for component there (app/components/button/button.scss, app/components/button/button.js etc). And you can also store an app/components/button/button.deps.js file, where you set dependencies needed for this UI component. And if you put something into mustDeps the resulting file will contain your dependency closer to the start of the file.

Try deps.js now with gulp-order-bemdeps

There comes a question: can I try these deps.js files in a real project? The simple answer is “yes you can!”. If you’re using gulp, there’s a plugin for that which re-orders gulp.src(…) stream of files using your deps.js files contents. The code for this differs not so much from its original:

A deeper dive into BEM’s deps.js

Deps files are not only used for mustDeps. There’s a bunch of functionality: building different techs (like bemhtml), shouldDeps which declare that there UI components are really used in this project and bundler (like webpack) should grab only these files. All of this stuff is currently supported in ENB.