Blocks are bricks, and bundles are buildings
A couple of days ago I was asked about some basic things of using BEM project stub from someone who is enjoying the full BEM stack (BEM-CSS, i-bem.js and BEMHTML templates) for their projects. Answering the questions I promised to turn the information into text as we always skip many important things mistakenly considering them being primitive.
The quesion was about .bem/make.js
configuration file which is needed if you
use bem tools to build your pages. The
12th and 13th
lines
describe regular expressions to match blocks
and bundles
. And the meaning of
these terms turned out to be unclear.
First of all, the expressions are to detect folders on the project file system.
Those which end with .blocks
store blocks, and those which end with .bundles
store bundles. The desktop.blocks
and desktop.bundles
folders of the project
stub demonstrate this.
The purpose of desktop.blocks
folder should be clear. As BEM is a modular
development pattern there has to be a place to store modules, the so-called
blocks
. Each block has its own directory to keep all the files needed for this
particular interface module. E.g. one project block
set.
The desktop.bundles
folder needs some comments. It stores pages, which are the
result of blocks applied. Every page has its own folder and inside you can find
different files needed for a page to function. Examine the example
project
again.
The difference is that block files are coded by a developer, as bundle files are built with the tools. Block files are our dear CSS, JavaScript and sometimes templates.
├── desktop.blocks/
│ ├── goods/
│ │ ├── goods.bemhtml
│ │ ├── goods.css
│ │ ├── goods.deps.js
│ │ └── goods.ie.css
Real world analogy of a BEM block (and actually any module of any modular pattern) can be a buiding brick.
Bundle files are also what a browser can read: CSS, JavaScript, HTML. None of them was written by a person, they are built with BEM tools. Have a look inside to be sure that this is robot's code.
├── desktop.bundles/
│ ├── index/
│ │ ├── _index.css
│ │ ├── _index.js
│ │ ├── index.bemjson.js
│ │ └── index.html
Think about bem tools as about building crane to pick up the bricks and make a house with them.
Besides _.js, _.css and *.html files there is the only one here written by a
developer. This is
index.bemjson.js,
the JSON decription of what are the blocks on a page and what it their nested
structure. Sounds logical, as only we human can know what we would like to see
on a page. Everything else is produced by the bem tools
. Once given
informaiton about which blocks to use for a page, they pick them up from
desktop.blocks
set of blocks and do their job.
Extending the building-a-house example I can say that page.bemjson.js
file
here is a draft.
But why do bem tools
need the regular expessions?
This is quite easy. The folders bem tools
operate with are levels
. It can
help if you think about a level as about a set
, a set of entities. There can be
a set of blocks wraped with desktop.blocks
folder, and a set of result pages
wraped with desktop.bundles
folder. In the
.bem/levels/
cofiguration folder there are some instructions from which bem tools understand
what to do with those different types of levels.
Dividing your project entities into blocks and bundles makes it possible to have different sets of blocks and different bundles built with those sets. For example, you can store blocks to a desktop and touch versions of your web site into the same repository as well as the pages built with them.
├── desktop.blocks/
├── desktop.bundles/
├── touch.blocks/
└── touch.bundles/
Comming back to the real world, not only bricks are the modules but lego blocks as well.
They also are to build a house. A pretty different house though.
Going futher you can detach code common for all the platforms and store it separately.
├── common.blocks/
├── desktop.blocks/
├── desktop.bundles/
├── touch.blocks/
└── touch.bundles/
With that structure desktop version of a web site gets source code from both
common.blocks
and desktop.blocks
levels as touch version gets it from
common.blocks
and touch.blocks
.
And before I wrap up, I cannot stop being delighted by the idea of BEM project stub. I use it a lot myself when starting projects. The Full stack quick start tutorial which you may remember demostrates how exactly. So does a friend who asked me about the basics. I never realized before that the project stub makes is possible to start a BEM project with no knowledge above. :-)
Having this written I see that describing the BEM basics is pretty easy and not very time-consuming to me being (I hope!) useful for the others. If so, please ask what you need to know.