Forum

Methodology

Toolbox

Platform

Community

BEM project building methodology

Any project developed using the BEM methodology has a multi-level file structure. Such a structure results from the component-based approach. In BEM, blocks can be implemented in one or more technologies. Each technology is stored in a separate file. Consequently, a build process is required in order to obtain general project files from individual files. You can use any of the available build tools.

Here is an example of a file structure organization of a BEM project:

blocks/               # Project level
  input/              # input block directory
    input.css         # input block implementation in CSS technology
    input.js          # input block implementation in JavaScript technology
  icon/
    icon.css
library/              # Library level
  input/
    input.js          # input block basic implementation in JavaScript technology
  button/

To find out more about the reasons for dividing a block implementation into separate files, read File system organizaation of a BEM project.

The build process takes care of the following:

Main stages of the build process

In order to obtain a finished project part (build result), such as a web page, from individual files, we need to:

Build results

We can get different final sets of files as the outcome of the build:

In the BEM methodology, such file sets resulting from the build process are commonly called bundles.

Note that in this document the build process is illustrated on the example of a page, which is an instance of a bundle.

In the file system, build results for individual files are placed in a default directory carrying the page name (e.g., hello):

blocks/       # Directory containing the blocks
bundles/      # Directory containing all build results (optional)
  hello/      # Directory for the hello page (created manually)

An example of a pre-build file structure of a BEM project:

blocks/           # Directory containing the blocks
bundles/          # Directory containing all build results
  hello/          # Directory for the hello page
  hello.decl.js   # List of BEM entities required for the hello page

An example of a post-build file structure of a BEM project:

blocks/           # Directory containing the blocks
bundles/          # Directory containing all build results
  hello/          # Directory for the hello page
  hello.decl.js   # List of BEM entities required for the hello page
  hello.css       # Built CSS file for the hello page
  hello.js        # Built JavaScript file for thehello page

Either of the following can be included in the project during the build process:

Building a project with only the relevant BEM entities makes use of the following (all are optional):

Determining a list of blocks, elements, and modifiers for creating a page

To start the build process for a page, the build tool must know all of its components.

Declaration

The first step in the build process is making a list of the necessary BEM entities. The following example explains the purpose of such a list and how it is created.

Let's say there is a library linked to your project, and some of the blocks from that library are used on the page. There is no need to include the entire library in the build. You can use the page description to make a list of the specific items required. This can be done either automatically or manually. Only the listed blocks will end up in the build. In the BEM methodology, such a list is called a declaration.

The main purpose of the declaration is to define what and in what order should be included in the build.

Find out more about different ways of building a declaration.

Identifying dependencies

In the BEM methodology, blocks are often built on the basis of other blocks. For instance, the search form block (search-form) is built using the input and button blocks. There is no need to implement a block again if it is already stored in the library. You can build the new block on the basis of the existing one.

To create a block based on another block that already exists, you need to specify dependencies between the two. For instance, the above-mentioned search-form block is dependent on input and button.

The build tool receives the dependency data and adds all the entities and technologies necessary for implementing the block during the build process. The order of including entities is also specified in the dependencies.

Dependencies can be specified in a number of ways:

Determining the order of including BEM entities in the build

The order of including BEM entities in the build depends upon:

The diagram illustrates the principle of applying redefinition levels to the build: components common to all platforms are linked to the common level, while platform-specific components are linked from the desktop and touch levels.

Redefinition levels

To find out more about using redefinition levels, read these examples:

Build tools

The choice of a particular build tool depends on the complexity of your BEM project, on whether it has redefinition levels and whether it uses dependencies.

The BEM methodology does not limit your choice of tools — you can use any build tool (e.g., Gulp, Grunt, Brunch, Broccoli) that meets the requirements of your project.

An example of building a BEM project using Gulp — Declarative JavaScript with BEM.

The BEM platform uses ENB, which is a tool suitable for building BEM projects of any level of complexity.

An example of building a BEM project using ENBStarting your own BEM project.

If you notice a mistake or want something to supplement the article, you can always write to us at GitHub, or correct an article using prose.io.