Giter Site home page Giter Site logo

bem-tools's Introduction

BEM Tools Build Status

Toolkit to work with files based on BEM methodology.

Installation

You need NodeJS 0.10+ or later and npm 2.x+.

Run npm install bem to install bem-tools locally.

Usage

Get the list of commands with bem --help. To read about commands and subcommands use bem COMMAND --help or bem COMMAND SUBCOMMAND --help.

Shell completion

bash

To make completions for bem-tools available in your bash, run following command (ensure that you have bash-completion installed, first). Run this

bem completion > /path/to/etc/bash_completion.d/bem

and restart bash.

If you aren't using bash-completion, you can add bem completion to your .bashrc and reload:

bem completion >> ~/.bashrc
source ~/.bashrc

zsh

If you use zsh, you can add bem completion to your .zshrc and reload:

bem completion >> ~/.zshrc
source ~/.zshrc

Commands

bem create

You can create following entities using bem create:

  • levels of defenition
  • blocks
  • elements
  • modifiers
Level of defenition

Level of defenition is a directory that holds blocks and an utility directiry .bem.

A .bem directory holds configuration of a current level:

  • naming convention
  • links to the technologies

An example of technologies' links (this is blocks-desktop level of bem-bl block library):

https://github.com/bem/bem-bl/blob/master/blocks-common/.bem/level.js
Create new level of defenition named blocks under current directory:
bem create level blocks
Create a level for pages

In bem-tools terms pages are blocks as well and a directory which holds pages is a level of defenition itself. To create such a directory run this:

bem create level pages
Create a level based on an existing one

bem create level allows to use an existing level as a prototype for a level it creates.

bem create level --level bem-bl/blocks-desktop blocks
Block

Block is a bunch of files in different technologies that hold block's implementation.

Create a new block
bem create block b-my-block

By default, a block has several techs: (bemhtml, css, js).

Create a new block using concrete tech

Flags -t (-T) are to create files of technologies you need:

bem create block -t deps.js b-my-block
    // Creates a block implementation in deps.js technology, ecxept of default techs.

bem create block -T css b-my-block
    // Creates only CSS technology for a block

bem create block -T bem-bl/blocks-desktop/i-bem/bem/techs/bemhtml.js b-my-block
    // -T flag is useful when you need to add a new tech to the block existed

The value of this flag may be either tech's name (e.g css) or a path to tech module.

Tech names may be listed in .bem/level.js file of a level. E.g., https://github.com/bem/bem-bl/blob/master/blocks-common/.bem/level.js

You can find the examples of tech modules in the repo:

https://github.com/bem/bem-tools/tree/master/lib/techs
Create element

Create element named elem for block b-my-block

bem create elem -b b-my-block elem
Create modifier of block or element

Create modifier named mod for block b-my-block

bem create mod -b b-my-block mod

Create modifier named mod having value val for block b-my-block

bem create mod -b b-my-block mod -v val

Create modifier named mod for element elem of block b-my-block

bem create mod -b b-my-block -e elem mod

Create modifier named mod having value val for element elem of block b-my-block

bem create mod -b b-my-block -e elem mod -v val
Create any BEM entity using bem create command only

You can create any BEM entities or bunches of them using bem create command.

Create blocks named b-block1 and b-block2

bem create -b b-block1 -b b-block2

Create elements named elem1 and elem2 for block b-block

bem create -b b-block -e elem1 -e elem2

Create modifier names mod of block b-block

bem create -b b-block -m mod

Create modifier named mod of block b-block having values val1 and val2

bem create -b b-block -m mod -v val1 -v val2

Create modifier named mod for element elem of block b-block

bem create -b b-block -e elem -m mod

Create modifier named mod having values val1 and val2 for element elem of block b-block

bem create -b b-block -e elem -m mod -v val1 -v val2

bem build

bem build command builds page files in different techs, according to a page declaration.

Create bemdecl.js file from page's bemjson
bem build \
    -l bem-bl/blocks-common -l bem-bl/blocks-desktop \
    -l blocks -l pages/index/blocks \
    -d pages/index/index.bemjson.js -t bemdecl.js \
    -o pages/index -n index

You can use either tech's name or a path to its module as a value of -t flag. This module says how to build a final file from a declaration.

E.g., this is a module for deps.js: https://github.com/bem/bem-tools/blob/master/lib/techs/deps.js.js

Create deps.js file from bemdecl.js
bem build \
    -l bem-bl/blocks-common -l bem-bl/blocks-desktop \
    -l blocks -l pages/index/blocks \
    -d pages/index/index.bemdecl.js -t deps.js \
    -o pages/index -n index
Create js and css files for a page from deps.js
bem build \
    -l bem-bl/blocks-common -l bem-bl/blocks-desktop \
    -l blocks -l pages/index/blocks \
    -d pages/index/index.deps.js -t css \
    -o pages/index -n index

bem build \
    -l bem-bl/blocks-common -l bem-bl/blocks-desktop \
    -l blocks -l pages/index/blocks \
    -d pages/index/index.deps.js -t js \
    -o pages/index -n index
Create bemhtml.js template for a page from deps.js
bem build \
    -l bem-bl/blocks-common -l bem-bl/blocks-desktop \
    -l blocks -l pages/index/blocks \
    -d pages/index/index.bemhtml.js \
    -t bem-bl/blocks-desktop/i-bem/bem/techs/bemhtml.js \
    -o pages/index -n index

There is an example how pages are built using bem build in our test project that uses bem-bl block library: https://github.com/toivonen/bem-bl-test/blob/master/GNUmakefile

bem decl

bem decl is to work with declaration files. Thus,

  • to merge two or more decls into one
  • «subtract» decls

All subcommands of bem decl can take either bemdecl.js or deps.js as input declaration formats. as input declaration (via -d flag).

Ouput data (-o flag) is always in deps.js format.

bem decl merge

bem decl merge is to merge two or more decls into one. It is useful if you need, for example, to build one file for several pages.

Create a decl for all the pages
bem decl merge \
    -d pages/index/index.deps.js \
    -d pages/about/about.deps.js \
    -d pages/search/search.deps.js \
    -o pages/common/common.deps.js
bem decl subtract

bem decl subtract is to «subtract» all next decls from the first one. You may use it to create a bundle that you request by application.

Create a decl for a "heavy" block requested by application
bem decl subtract \
    -d bundles/heavy-block/heavy-block.deps.js \
    -d pages/common/common.deps.js \
    -o bundles/heavy-block/heavy-block.bundle.js
bem make

make command implements the build process of the BEM projects. You don't have to write your own scripts or makefiles (for GNU make or other build system) to build your BEM project.

Since 0.10.0 bem make also supports enb make under the hood which is recomended way to build your projects.

During the build bem make

  • fetches the block libraries
  • builds the levels content
  • builds the bundles
  • generates the templates (bemhtml)
  • generates html from bemjson.js
  • generates the static content files (js, css)
  • expands the @import derectives in css files (borschik)
  • expands the borschik:link:include directives in js files (borschik)
  • optimizes css files using csso
  • optimizes js files using uglifyjs
bem server

bem server command runs a development server. It makes the project files being accessible via the http protocol. This includes the files which are generated during the build process. So the server can be useful when you develop the static pages using the bem method. You just edit the files, refresh the browser and get updated page. All the files which are affected by your changes will be rebuilt automatically. In the case your project has no static pages you can configure your backend server and production environment to retrieve the stylesheets and scripts from the bem server. bem server accepts connections via normal TCP socket and via UNIX domain socket.

By default the current directory is considered as the project root. You can change it using the --project (-r) option.

Default TCP port is 8080. You can change it using the --port (-p) option.

When requested URL is mapped to a directory, the server will check if there is an index.html file or it's possible to build it. In the case one of these is true the content of the file will be returned to browser. The directory content listing will be returned otherwise.

Since 0.10.0 bem server also supports enb server under the hood which is recomended way to build your projects.

Build configuration

Since 0.10.0 bem make and bem server also supports ENB under the hood which is recomended way to build your projects. So for build configuration please refer ENB documentation.

The info about configuration bellow is deprecated and will be removed in the next version.

There is a default build behavior programmed in the build system. The configuration files allow to adjust it a little or change it completely. To make bem make work you should have .bem/level.js file within your levels. It should contain the getTechs() function, which returns object with the tech definitions used on the level. And it should have function getConfig():

var extend = require('bem/lib/util').extend;

exports.getTechs = function() {
    return {
        'bemjson.js': '',
        'js': 'js-i',
        'bemhtml.js': '../../bem-bl/blocks-common/i-bem/bem/techs/bemhtml.js',
        'priv.js': '../../.bem/techs/priv.js',
        'html': '../../bem-bl/blocks-common/i-bem/bem/techs/html'
    };
};

exports.getConfig = function() {

    return extend({}, this.__base() || {}, {

        bundleBuildLevels: this.resolvePaths([
            '../../bem-bl/blocks-common',
            '../../bem-bl/blocks-desktop',
            '../../blocks'
        ])

    });

};

getTechs() returns an object with used techs. Object properties (for example 'bemjson.js', 'js', 'bemhtml.js') define the tech names, object values specify the paths to the appropriate tech files ('', 'js-i', '../../bem-bl/blocks-common/i-bem/bem/techs/bemhtml.js'). A path can be relative or absolute, it can be empty, or it can specify just a file name. When the latter case is used the tech will be considered being standard (bundled with bem-tools) and the file will be looked up in the [bem]/lib/techs folder.

getConfig() function returns an object with the bundleBuildLevels property, containing the array of the used block levels.

Another (optional) configuration file is .bem/make.js located in the project root. Core of the build system is a graph of nodes, each of which executes own part of the whole build process. make.js allows you to adjust nodes behavior and change build graph. There are several standard node types:

  • Node - base node, implements basic functionality. All other nodes are inherited from this one
  • LibraryNode - retrieves external libraries
  • LevelNode - inspects the contents of a level and constructs graph branch accordingly to build the level
  • BundlesLevelNode - inherits from LevelNode and builds the bundles levels
  • BundleNode - constructs graph branch for a bundle
  • MergedBundleNode - builds merged bundle (aka common bundle)
  • BorschikNode - processes files with the borschik utility, csso and uglifyjs
  • Arch - builds initial graph, which by default consists of LibraryNode, BundlesLevelNode and LevelNode nodes

To alter build system behavior for your project you need to alter behavior of the nodes. This can be achieved by adding MAKE.decl() calls in the .bem/make file. MAKE.decl() is a helper function which accepts two arguments. First one is the node name which we want to change, second - an object with overriding methods.

MAKE.decl('BundleNode', {

});

Node classes have some fundamental methods, which take care about the build process:

  • isValid() - validates the node - indicates is there a need to rebuild it or not. If node artifacts were built during previous build and dependency nodes were not rebuilt after that, the node is considered being valid. In other words if you changed a file after first build then only the nodes which depend on this file will be rebuilt during the consequent build.
  • make() - implements the build logic for the node.
  • run() - node entry point. In the default implementation it executes isValid method and in case it returns false the make method will be executed next.
  • clean() - removes the build artifacts for the node.
Sample configuration files for some typical tasks
Build of static html, css, js, bemhtml templates on the level pages. Bemjson file is used as a source file. Also using blocks level blocks, and also blocks-common and blocks-desktop from bem-bl.

pages/.bem/level.js

var extend = require('bem/lib/util').extend;

exports.getTechs = function() {

    return {
        'bemjson.js': '',
        'bemdecl.js': 'bemdecl.js',
        'deps.js': 'deps.js',
        'js': 'js-i',
        'css': 'css',
        'bemhtml.js': '../../bem-bl/blocks-common/i-bem/bem/techs/bemhtml.js',
        'html': '../../bem-bl/blocks-common/i-bem/bem/techs/html.js'
    };

};

exports.getConfig = function() {

    return extend({}, this.__base() || {}, {

        bundleBuildLevels: this.resolvePaths([
            '../../bem-bl/blocks-common',
            '../../bem-bl/blocks-desktop',
            '../../blocks'
        ])

    });

};

.bem/make.js

MAKE.decl('Arch', {

    getLibraries: function() {

        return {
            'bem-bl': {
                type: 'git',
                url: 'git://github.com/bem/bem-bl.git'
            }
        };

    }

});

MAKE.decl('BundleNode', {

    getTechs: function() {

        return [
            'bemjson.js',
            'bemdecl.js',
            'deps.js',
            'bemhtml.js',
            'css',
            'js',
            'html'
        ];
    }

});
Build of css, js, bemhtml tamples on the level pages. bemdecl declaration file is used as a source file. Also using blocks level blocks, and also blocks-common and blocks-desktop from bem-bl.

pages/.bem/level.js

var extend = require('bem/lib/util').extend;

exports.getTechs = function() {

    return {
        'bemdecl.js': 'bemdecl.js',
        'deps.js': 'deps.js',
        'js': 'js-i',
        'css': 'css',
        'bemhtml.js': '../../bem-bl/blocks-common/i-bem/bem/techs/bemhtml.js'
    };

};

exports.getConfig = function() {

    return extend({}, this.__base() || {}, {

        bundleBuildLevels: this.resolvePaths([
            '../../bem-bl/blocks-common',
            '../../bem-bl/blocks-desktop',
            '../../blocks'
        ])

    });

};

.bem/make.js

MAKE.decl('Arch', {

    getLibraries: function() {

        return {
            'bem-bl': {
                type: 'git',
                url: 'git://github.com/bem/bem-bl.git'
            }
        };

    }

});

MAKE.decl('BundleNode', {

    getTechs: function() {

        return [
            'bemdecl.js',
            'deps.js',
            'bemhtml.js',
            'css',
            'js'
        ];
    }

});
The block libraries

The block libraries are not used by default. To use a library add the following code to .bem/make.js:

MAKE.decl('Arch', {
    getLibraries: function() {

        return {
            'bem-bl': {
                type: 'git',
                url: 'git://github.com/bem/bem-bl.git'
            }
        };
    }
});

Where:

  • 'Arch' - node class name which we want to override. Arch builds initial build graph.
  • getLibraries - a method of the Arch class, which returns the associative array of the used block libraries.
  • 'bem-bl' — the name of the library and the folder where it will be copied to.
  • type - the type of the library source. We use git in the example, so the library will be checked out of a git repository. Possible values are: 'git', 'svn', 'symlink'. svn works the same as git, but with svn repositories. symlink - creates a symbolic link in the project folder to the library folder. The library path is specified by the relative property.
  • url - URL to the svn/git repository

Also you can use shorter code:

MAKE.decl('Arch', {
    libraries: {
        'bem-bl': {
            type: 'git',
            url: 'git://github.com/bem/bem-bl.git'
        }
    }
});
Block levels

The folders in the project root matching the blocks* mask are considered being the blocks level. You can change this using the following code:

MAKE.decl('Arch', {
    blocksLevelsRegexp:  /regular expression/,
});

The regular expression will be used to match the folders in the project root. A folder which does match will be used as the blocks level.

If you need some logic for the levels selection you can achieve that by overriding the createBlocksLevelsNodes() method:

MAKE.decl('Arch', {
    createBlocksLevelsNodes: function(parent, children) {
        // Create the LevelNode instance
        var node1 = new LevelNode(...);
        // Add it into the graph
        this.arch.setNode(node1, parent, children);

        var node2 = new LevelNode(...);
        this.arch.setNode(node2, parent, children);

        // return an array with the Ids of the created nodes
        return [node1.getId(), node2.getId()];
    }
});
The bundles and the pages

The folders in the project root matching the pages* abd bundles* masks are considered being bundle level. You can change this using the following code:

MAKE.decl('Arch', {
    bundlesLevelsRegexp: /regular expression/,
});

And for more precise control:

MAKE.decl('Arch', {

    getBundlesLevels: function() {
        return [
            'pages-desktop',
            'pages-touch',
            'bundles/common'
        ];
    }

});

For every bundle the following target files are built by default:

  • .bemhtml.js
  • .html
  • .css
  • .ie.css
  • .js
  • _*.css
  • _*.ie.css
  • _*.js

and the intermediate:

  • .bemdecl.js
  • .deps.js
  • .deps.js.deps.js
  • .bemhtml.js.meta.js
  • .js.meta.js
  • .css.meta.js
  • .ie.css.meta.js

.bemjson.js file is considered as a source file. If it does not exist, .bemdecl.js is used then. If .bemdecl.js does not exist too, .deps.js will be used. For the cases when .bemjson.js does not exist static html will not be built.

To change the list of the file techs to use, add the following code into .bem/make.js:

MAKE.decl('BundleNode', {

    getTechs: function() {
        return [
            'bemdecl.js',
            'deps.js',
            'bemhtml.js',
            'css',
            'js',
            'priv.js'
        ];
    }
});

IMPORTANT: Techs in the list should be in the order of dependency on each other. Tech B, which depends on A, should go bellow A. The source file tech should also be in the list, for example bemjson.js.

The merged bundles

The merged bundle — a bundle which includes the declarations of all bundles on the level. So for example css in a merged bundle will contain the styles from all of the bundles.

The following code will enable the build of the merged bundles for all levels:

MAKE.decl('BundlesLevelNode', {
    buildMergedBundle: function() {
        return true;
    }
});

If you need a merged bundle for the selected levels only (for pages-desktop level in the example):

var PATH = require('path');

MAKE.decl('BundlesLevelNode', {
    buildMergedBundle: function() {
        if (this.getLevelPath() === 'pages-desktop') return true;

        return false;
    }
});

The getLevelPath() method returns the relative path for the level. We can use it to decide should we enable some special logic for current level or not.

To change the merged bundle name use the code:

MAKE.decl('BundlesLevelNode', {

    mergedBundleName: function() {
        return 'mymergedbundle';
    }

});
Production and Development builds

By changing the YENV environment variable value, you can switch between the production and development builds. In production mode static files are processed with the borschik utility. It expands the include directives and puts the result content in the file with the _ prefix. For example, index.css has the directives to include blocks/block1.css and blocks/block2.css. _index.css will be created with the content of both block1.css and block2.css. Also the css files are optimized with the csso utility, the js files are optimized with uglifyjs. In development mode borschik is used only, no optimizations take the place.

The default mode is development. To use the production mode set YENV to production.

Environment variables can be set in .bem/make.js, for example

process.env.YENV = 'production';

Configuration files

Level (.bem/level.js)

A level should have .bem/level.js configuration file which contains the meta information about the level:

  • the mapping rules between the BEM entities and the file system
  • the thech modules defined on the level
  • the meta information for the build system

When the bem create level command is used to create a level the empty .bem/level.js file will be also created. Which means that this level is «standard» one. The logic for standard level is defined in the Level class within (lib/level.js)[https://github.com/bem/bem-tools/blob/master/lib/level.js].

As the .bem/level.js file is a CommonJS module it's easy to override the level's behavior. bem-tools creates a new class inherited from the standard Level class using export of this module as a class extention (under the hood the inherit module is used).

In the example bellow the getTechs() method is overriden.

exports.getTechs = function() {

    return {
        'bemjson.js': ''
        'css': 'path/to/my/css-tech-module.js'
    }

};
The levels inheritance

To avoid the copy and paste of the same code among several levels you can put the common parts into the independant modules and inherit them. This way you can build up the levels hierarchy.

To specify the base level you should export it in the baseLevelPath property. For example

exports.baseLevelPath = require.resolve('path/to/base/level.js');

It's also possible to create the inherited levels using the command

bem create level <your-level-name> --level path/to/base/level.js
The mapping rules between BEM entities and the file system

By default the following mapping scheme is used (this example is about the css tech):

level/
    block/
        __elem/
            _mod/
                block__elem_mod_val.css
            block__elem.css
        _mod/
            block_mod_val.css
        block.css

If you want to use a custom scheme override the appropriate match*() and get*() methods in the .bem/level.js file.

Tech modules defined on the level

To define a list of the tech modules used on the level export the getTechs() function. It should return an object the keys of which contain the tech names and the values contain on of the following:

  • the absolute tech path;
  • a short tech name — a tech module with such name bundled with bem-tools will be used;
  • an empty string — the default tech implementation will be used.

By deault there is no any techs defined explicitly on a level. In the case some techs are used within such a level by a short name (for example css, js, etc) then the appropriate tech modules bundled with bem-tools are loaded. If such do exist of course. The full list of such techs can be found there lib/techs.

If you try to use a tech which was not defined explicitly and which is not bundled with bem-tools - the default tech will be used (see lib/tech/v1.js).

The techs defined on the level are used:

  • by the bem create command
  • by the bem build command
  • by the file system introspection (see the getLevelByIntrospection() of the Level class)
  • during the project build with the bem make and bem build commands

It's recommended to define explicitly the used techs.

The build system meta information

To let the build system know which levels should be used to build one bundle or another set the bundleBuildLevels property within an object returned by the getConfig() function to an array of these levels.

exports.getConfig = function() {

    return extend({}, this.__base() || {}, {

        bundleBuildLevels: this.resolvePaths([
            // your levels here
        ])

    });

};

Tech modules

API

Look for the documentation in the source code lib/tech/v1.js.

Creating tech module

There are many ways to write a tech module.

Whatever manner you choose you can refer to the tech object from methods using this. Any base method is available using this.__base(...) call. Tech class can be referenced using this.__class. Thanks to inherit module that helps us to organize inheritance here.

Trivial way

You only need to declare regular CommonJS module and export some of its functions to redefine them. By default your tech will derive from base Tech class defined in module lib/tech/v1.js.

exports.getCreateResult = function(...) {
    // your code goes here
};

You can also group all methods in techMixin object. This is a recommended way.

exports.techMixin = {

    getCreateResult: function(...) {
        // your code goes here
    }

};
Simple way

Besides function, you can also export baseTechPath variable to define an absolute path to a tech module you are extending. Or you can

var BEM = require('bem');

exports.baseTechPath = BEM.require.resolve('./techs/css');

You can also derive from tech module by its name using baseTechName variable. Base class will be chosen in the context of level where tech module will be used.

exports.baseTechName = 'css';

In this example new tech will derive from css tech declared on level in file .bem/level.js.

Hardcore way

If you need a total control, you can create a module that exports the whole Tech class.

var INHERIT = require('inherit'),
    BaseTech = require('bem/lib/tech').Tech;

exports.Tech = INHERIT(BaseTech, {

    create: function(prefix, vars, force) {
        // do some creation work
    },

    build: function(prefixes, outputDir, outputName) {
        // organize own build process
    }

});

If you need to base your tech on an existing one written in a simple way use getTechClass() function to get its class. We recommend to use getTechClass() function all the time to not depend on tech implementation.

var INHERIT = require('inherit'),
    BEM = require('bem'),
    BaseTech = BEM.getTechClass(require.resolve('path/to/tech/module'));

exports.Tech = INHERIT(BaseTech, {

    // your overrides go here

});
Examples of tech modules

API usage

Starting from 0.2.0 version it is possible to use bem-tools from API.

bem module exports the object of a command that has an api property. It is to use in this way:

var Q = require('q'),
    BEM = require('bem').api,

    techs = ['css', 'js'],
    blocks = ['b-block1', 'b-block2'];

Q.when(BEM.create.block({ forceTech: techs }, { names: blocks }), function() {
    console.log('Create blocks: %s', blocks.join(', '));
});

The example above shows that you can use all the commands (including subcommands).

A command accepts two args:

  • Object opts command options
  • Object args command arguments

It returns an object of Q.promise type.

BEM.create

Commands to create BEM entities.

BEM.create.level()

Creates a level of defenition.

Options
  • String outputDir a directory of output (current directory by default)
  • String level a «prototype» of the level
  • Boolean force key to force level's creating if it already exists
Arguments
  • Array names Namef of levels you are creating
Example
var PATH = require('path'),
    Q = require('q'),
    BEM = require('bem').api,

    outputDir = PATH.join(__dirname, 'levels'),
    levels = ['blocks-common', 'blocks-desktop'];

Q.when(BEM.create.level({ outputDir: outputDir }, { names: levels }), function() {
    console.log('Create levels %s at %s', levels.join(', '), outputDir);
});
BEM.create()

Creates BEM entities: blocks, elems, modifiers and their values.

Options
  • String level Level directory (current directory by default)
  • Array block Block name (required)
  • Array elem Element name
  • Array mod Modifier name
  • Array val Modifier value
  • Array addTech Add the techs listed
  • Array forceTech Use only the techs listed
  • Array noTech Exclude the techs listed
  • Boolean force Force creating BEM entities files (rewrite)
Example
var Q = require('q'),
    BEM = require('bem').api,

    forceTechs = ['css'],
    block = 'b-header',
    elem = 'logo',
    mods = ['lang'],
    vals = ['ru', 'en'];

Q.when(BEM.create({ forceTechs: forceTechs, block: block, mod: mods, val: vals }), function() {
    console.log('Create mod %s of block %s with vals %s', mods.join(', '), block, vals.join(', '));
});

Q.when(BEM.create({ forceTechs: forceTechs, block: block, elem: elem, mod: mods, val: vals }), function() {
    console.log('Create mod %s of elem %s of block %s with vals %s', mods.join(', '), elem, block, vals.join(', '));
});
BEM.create.block()

Creates a block.

Options
  • String level A directory of block's level. (Current directory by default)
  • Array addTech Add the techs listed
  • Array forceTech Use these techs only
  • Array noTech Exclude these techs
  • Boolean force Force files creating
Arguments
  • Array names List of block names
Example
var Q = require('q'),
    BEM = require('bem').api,

    addTechs = ['bemhtml'],
    blocks = ['b-header'];

Q.when(BEM.create.block({ addTech: addTechs }, { names: blocks }), function() {
    console.log('Create blocks: %s', blocks.join(', '));
});
BEM.create.elem()

Creating an element.

Options
  • String level A directory of level. (Current directory by default)
  • String blockName A name of element's block (required)
  • Array addTech Add the techs listed
  • Array forceTech Use only the techs listed
  • Array noTech Exclude the techs listed
  • Boolean force Force creating element's files (to rewrite them)
Arguments
  • Array names List of element names
Example
var Q = require('q'),
    BEM = require('bem').api,

    addTechs = ['bemhtml', 'title.txt'],
    block = 'b-header',
    elems = ['logo'];

Q.when(BEM.create.elem({ addTech: addTechs, blockName: block }, { names: elems }), function() {
    console.log('Create elems %s of block %s', elems.join(', '), block);
});
BEM.create.mod()

Creating a modifier for a block or an element.

Options
  • String level Level directory (current directory by default)
  • String blockName Block name of this modifier (required)
  • String elemName Element name
  • Array modVal Modifier value
  • Array addTech Add the techs listed
  • Array forceTech Use only the techs listed
  • Array noTech Exclude the techs listed
  • Boolean force Force creating modifier files (rewrite)
Arguments
  • Array names List of modifier
Example
var Q = require('q'),
    BEM = require('bem').api,

    forceTechs = ['css'],
    block = 'b-header',
    elem = 'logo',
    mods = ['lang'],
    vals = ['ru', 'en'];

Q.when(BEM.create.mod({ forceTechs: forceTechs, blockName: block, modVal: vals }, { names: mods }), function() {
    console.log('Create mod %s of block %s with vals %s', mods.join(', '), block, vals.join(', '));
});

Q.when(BEM.create.mod({ forceTechs: forceTechs, blockName: block, elemName: elem, modVal: vals }, { names: mods }), function() {
    console.log('Create mod %s of elem %s of block %s with vals %s', mods.join(', '), elem, block, vals.join(', '));
});

BEM.build()

Build files from blocks.

Options
  • String outputDir An output directory (current directory by default)
  • String outputName A filename (its prefix) for output
  • Level outputLevel Output level for BEM entity to create
  • String block Block name
  • String elem Element name
  • String mod Modifier name
  • String val Modifier name
  • String declaration A filename of input declaration (required)
  • Array level List of levels to use
  • Array tech List of techs to build

You should use one of the following to specify output prefix:

  • outputName to specify full path-prefix
  • outputDir plus outputName to specify directory path and file prefix (they will be joined for you)
  • outputLevel plus properties describing BEM entity: block, elem, mod and val (path-prefix will be constructed for you using level file mapping scheme)
Example
var Q = require('q'),
    B = require('bem'),
    BEM = B.api,

    decl = 'page.deps.js',
    outputDir = 'build',
    outputName = 'page',
    levels = ['blocks-common', 'blocks-desktop'],
    techs = ['css', 'js'];

// use outputDir and outputName options
Q.when(
    BEM.build({
        outputDir: outputDir,
        outputName: outputName,
        declaration: decl,
        level: levels,
        tech: techs
    }),
    function() {
        console.log('Finished build of techs %s for levels %s. Result in %s/%s.* files.',
            techs.join(', '), levels.join(', '), outputDir, outputName);
    }
);

// use outputLevel option
var level = B.createLevel('path/to/level'),
    block = 'page';
Q.when(
    BEM.build({
        outputLevel: level,
        block: block
    }),
    function() {
        console.log('Finished build of techs %s for levels %s. Result in %s.* files.',
            techs.join(', '), levels.join(', '), level.getRelByObj({ block: block }));
    }
);

BEM.decl

Commands to work with declarations.

BEM.decl.merge()

Merging two or more declarations into one.

Options
  • String output A file for output result. By default output is in STDOUT
  • Array declaration List of filenames for declarations (required)
BEM.decl.subtract()

Subtracting the next declarations from the first one.

Options
  • String output A file for output result. By default output is in STDOUT
  • Array declaration List of filenames for declarations (required)

Contribute to development

Executing autotests

To verify that your changes do not break existing functionality we recommend to run autotests and check that all of them pass. You can do that by executing the following command in the root of the project:

mocha 

Running autotests with test coverage report

You can check the level of the code coverage by tests using the command:

make test-cover

Then open coverage.html file in a browser. Code lines which have not been executed during the tests run will be marked red.

bem-tools's People

Contributors

afelix avatar arikon avatar avakarev avatar banzalik avatar burgua avatar chayn1k avatar dab avatar dfilatov avatar diunko avatar egavr avatar eprev avatar fliptheweb avatar ilyar avatar indutny avatar j0tunn avatar mishanga avatar narqo avatar readmecritic avatar scf2k avatar tadatuta avatar tolkera avatar veged avatar vithar avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

bem-tools's Issues

Implement arch invalidation mechanism in the bem server

Arch should be built on the first request. The requests coming shortly after the first one should be completed using the existing arch. An invalidation timeout should be defined which sets the time during which the arch is considered being valid. Requests coming during the timout will use existing arch, every such request resets the timeout. When timeout is completed the arch becomes invalid and next server request will lead to the arch being rebuilt.

No manual entry for bem

Не хватает мана для bem-tools, в котором было бы описано всё по использованию. Описание сущностей и как с ними работать.

Проблема с bem build

Беру тестовый проект отсюда - https://github.com/bem/bem-bl-test
Во время сборки вылетает ошибка:

/Users/vizo/Sites/test make
bem create block -l pages -T bemdecl.js client
bem build -l bem-bl/blocks-common/ -l bem-bl/blocks-desktop/ -l blocks/ -l pages/client/blocks/ -d pages/client/client.bemdecl.js -t deps.js -o pages/client -n client
bem build -l bem-bl/blocks-common/ -l bem-bl/blocks-desktop/ -l blocks/ -l pages/client/blocks/ -d pages/client/client.deps.js -t bem-bl/blocks-common/i-bem/bem/techs/bemhtml.js -o pages/client -n client
Error: Cannot find module 'bem/lib/path'
at Function._resolveFilename (module.js:317:11)
at Function._load (module.js:262:25)
at require (module.js:346:19)
at Object. (/Users/vizo/Sites/test/bem-bl/blocks-common/i-bem/bem/techs/bemhtml.js:1:76)
at Module._compile (module.js:402:26)
at Object..js (module.js:408:10)
at Module.load (module.js:334:31)
at Function._load (module.js:293:12)
at require (module.js:346:19)
at /usr/lib/node_modules/bem/lib/tech.js:13:20
make: *** [pages/client/client.bemhtml.js] Error 1
rm pages/client/client.deps.js pages/client/client.bemdecl.js

node -v v0.4.11

npm -v 1.0.104

bem -v 0.1.2

пути GNUMakefile для windows

в файле utils.js есть функция:

exports.isPath = function(str) {
return str.indexOf(PATH.dirSep) !== -1;
};

Она определяет является ли путём строка. Так вот в windows окружении PATH.dirSep == '' , а GNUMakefile все пути заданы с косой чертой '/' и при сборке выскакивают ошибки о не найденых файлах и т.п.

Принимая в качестве разделителя косую черту nodejs нормально её интерпретирует и в винде, поэтому может имеет смысл как-то форсировать именно её при возможности - так скрипты сборки будут кроссплатформеней писаться?

ps чтобы было понятнее вопрос относится к GNUMakefile из bem-method - но детали реализации тут, поэтому и сюда запостил.

Оповещение браузера об изменениях на файловой системе

Если использовать WebSocket (и его аналоги для старых браузеров), то при поднятии bem serverа, можно инклудить на страницу легкий js, который будет подключаться к серверу и ждать от него сообщений о том, что файл технологии обновился и то, что следует обновить страницу или этот файл.
Тогда получится обратный процесс, когда мы меняем что-то на файловой системе, а bem server производит автоматическую сборку всего, что требуется и по окончании обновляет страницу на клиенте.

Под Windows 7 x64 и XP x86 не работает bem-tools

C:\usr\nodejs>bem
C:\usr\nodejs>bem create block b-my-block
C:\usr\nodejs>dir

Directory of C:\usr\nodejs

29.12.2011 13:58

.
29.12.2011 13:58 ..
29.12.2011 13:58 199 bem.cmd
29.12.2011 13:55 5 030 248 node.exe
29.12.2011 13:56 15 698 944 node.pdb
29.12.2011 13:58 node_modules
16.12.2011 18:00 213 npm-g.cmd
16.12.2011 18:00 213 npm.cmd
16.12.2011 18:00 213 npm_g.cmd
6 File(s) 20 730 030 bytes
3 Dir(s) 8 230 465 536 bytes free

C:\usr\nodejs>bem --help

После ввода команды что-то происходит, но результата нет, как нет никаких сообщений.
Под Debian собрал, всё работает, всё ок.

Проблема в node.exe или bem-tools?

После make -B в bem-bl-test пустые файлы

Играюсь с БЭМ, сегодня сделал в проекте make -B и что-то пошло не так.
Раньше лечилось обновлением всего связанного с БЭМ. В этот раз не полечилось.

Удалил все что было, поставил обратно. Все равно не полечилось.
После 1-й установки оно поругалось
error: TypeError: Object # has no method 'parse'
После npm update оно перестало ругаться, но результирующие файлы пустые.

Куда копать?
Ниже лог.

dmage@nibbler ~ $ sudo npm-g install bem xjst ometajs
npm WARN [email protected] package.json: bugs['web'] should probably be bugs['url']
/usr/bin/ometajs2js -> /usr/lib/node_modules/ometajs/bin/ometajs2js
/usr/bin/xjst -> /usr/lib/node_modules/xjst/bin/xjst
npm WARN [email protected] package.json: bugs['web'] should probably be bugs['url']
npm WARN [email protected] package.json: bugs['web'] should probably be bugs['url']
/usr/bin/bem -> /usr/lib/node_modules/bem/bin/bem
[email protected] /usr/lib/node_modules/ometajs
[email protected] /usr/lib/node_modules/xjst
[email protected] /usr/lib/node_modules/bem
├── [email protected]
├── [email protected]
└── [email protected]
dmage@nibbler ~ $ git clone https://github.com/bem/bem-bl-test.git
Cloning into bem-bl-test...
cd bem remote: Counting objects: 121, done.
remote: Compressing objects: 100% (79/79), done.
remote: Total 121 (delta 35), reused 106 (delta 20)
Receiving objects: 100% (121/121), 11.91 KiB, done.
Resolving deltas: 100% (35/35), done.
dmage@nibbler ~ $ cd bem-bl-test/
dmage@nibbler ~/bem-bl-test $ make
-- git git://github.com/bem/bem-bl.git bem-bl
Cloning into bem-bl...
remote: Counting objects: 3834, done.
remote: Compressing objects: 100% (1527/1527), done.
remote: Total 3834 (delta 2122), reused 3724 (delta 2012)
Receiving objects: 100% (3834/3834), 758.43 KiB | 307 KiB/s, done.
Resolving deltas: 100% (2122/2122), done.
bem create block -l pages -t bemdecl.js client
bem build -l bem-bl/blocks-common/ -l bem-bl/blocks-desktop/ -l blocks/ -l pages/client/blocks/ -d pages/client/client.bemdecl.js -t deps.js -o pages/client -n client
bem build -l bem-bl/blocks-common/ -l bem-bl/blocks-desktop/ -l blocks/ -l pages/client/blocks/ -d pages/client/client.deps.js -t bem-bl/blocks-common/i-bem/bem/techs/bemhtml.js -o pages/client -n client
error: TypeError: Object # has no method 'parse'
TypeError: Object # has no method 'parse'
at [object Object].bemBuild (/home/dmage/bem-bl-test/bem-bl/blocks-common/i-bem/bem/techs/bemhtml.js:43:29)
at [object Object].build (/usr/lib64/node_modules/bem/lib/tech.js:420:26)
at /usr/lib64/node_modules/bem/lib/commands/build.js:119:22
at Array.forEach (native)
at Cmd. (/usr/lib64/node_modules/bem/lib/commands/build.js:44:32)
at /usr/lib64/node_modules/bem/node_modules/coa/lib/cmd.js:384:22
at _fulfilled (/usr/lib64/node_modules/bem/node_modules/q/q.js:498:32)
at Promise.promiseSend (/usr/lib64/node_modules/bem/node_modules/q/q.js:242:37)
at /usr/lib64/node_modules/bem/node_modules/q/q.js:519:18
at Promise.promiseSend (/usr/lib64/node_modules/bem/node_modules/q/q.js:242:37)
make: *** [pages/client/client.bemhtml.js] Ошибка 1
rm pages/client/client.deps.js pages/client/client.bemdecl.js
dmage@nibbler ~/bem-bl-test $ sudo npm-g update
npm WARN [email protected] package.json: bugs['web'] should probably be bugs['url']
npm WARN [email protected] package.json: bugs['web'] should probably be bugs['url']
npm WARN [email protected] package.json: bugs['web'] should probably be bugs['url']
npm WARN [email protected] package.json: bugs['web'] should probably be bugs['url']
/usr/bin/xjst -> /usr/lib/node_modules/xjst/bin/xjst
[email protected] /usr/lib/node_modules/xjst
├── [email protected]
├── [email protected]
└── [email protected]
dmage@nibbler ~/bem-bl-test $ make -B
-- git git://github.com/bem/bem-bl.git bem-bl
From git://github.com/bem/bem-bl

  • branch master -> FETCH_HEAD
    Already up-to-date.
    bem create block -l pages -t bemdecl.js client
    bem build -l bem-bl/blocks-common/ -l bem-bl/blocks-desktop/ -l blocks/ -l pages/client/blocks/ -d pages/client/client.bemdecl.js -t deps.js -o pages/client -n client
    bem build -l bem-bl/blocks-common/ -l bem-bl/blocks-desktop/ -l blocks/ -l pages/client/blocks/ -d pages/client/client.deps.js -t bem-bl/blocks-common/i-bem/bem/techs/bemhtml.js -o pages/client -n client
    bem build -l bem-bl/blocks-common/ -l bem-bl/blocks-desktop/ -l blocks/ -l pages/client/blocks/ -d pages/client/client.deps.js -t css -o pages/client -n client
    bem build -l bem-bl/blocks-common/ -l bem-bl/blocks-desktop/ -l blocks/ -l pages/client/blocks/ -d pages/client/client.deps.js -t js -o pages/client -n client
    bem build -l bem-bl/blocks-common/ -l bem-bl/blocks-desktop/ -l blocks/ -l pages/client/blocks/ -d pages/client/client.deps.js -t ie.css -o pages/client -n client
    bem create block -l pages -t bem-bl/blocks-common/i-bem/bem/techs/html.js client
    bem create block -l pages -t bemdecl.js example
    bem build -l bem-bl/blocks-common/ -l bem-bl/blocks-desktop/ -l blocks/ -l pages/example/blocks/ -d pages/example/example.bemdecl.js -t deps.js -o pages/example -n example
    bem build -l bem-bl/blocks-common/ -l bem-bl/blocks-desktop/ -l blocks/ -l pages/example/blocks/ -d pages/example/example.deps.js -t bem-bl/blocks-common/i-bem/bem/techs/bemhtml.js -o pages/example -n example
    bem build -l bem-bl/blocks-common/ -l bem-bl/blocks-desktop/ -l blocks/ -l pages/example/blocks/ -d pages/example/example.deps.js -t css -o pages/example -n example
    bem build -l bem-bl/blocks-common/ -l bem-bl/blocks-desktop/ -l blocks/ -l pages/example/blocks/ -d pages/example/example.deps.js -t js -o pages/example -n example
    bem build -l bem-bl/blocks-common/ -l bem-bl/blocks-desktop/ -l blocks/ -l pages/example/blocks/ -d pages/example/example.deps.js -t ie.css -o pages/example -n example
    bem create block -l pages -t bem-bl/blocks-common/i-bem/bem/techs/html.js example
    rm pages/example/example.bemdecl.js pages/client/client.deps.js pages/client/client.bemdecl.js pages/example/example.deps.js
    dmage@nibbler ~/bem-bl-test $ cat pages/example/example.html

dmage@nibbler ~/bem-bl-test $ ls -al pages/example/
итого 20
drwxr-xr-x 2 dmage dmage 4096 Ноя 20 00:55 .
drwxr-xr-x 4 dmage dmage 4096 Ноя 20 00:53 ..
-rw-r--r-- 1 dmage dmage 1259 Ноя 20 00:55 example.bemhtml.js
-rw-r--r-- 1 dmage dmage 563 Ноя 20 00:53 example.bemjson.js
-rw-r--r-- 1 dmage dmage 0 Ноя 20 00:55 example.css
-rw-r--r-- 1 dmage dmage 1 Ноя 20 00:55 example.html
-rw-r--r-- 1 dmage dmage 0 Ноя 20 00:55 example.ie.css
-rw-r--r-- 1 dmage dmage 0 Ноя 20 00:55 example.js
dmage@nibbler ~/bem-bl-test $ make pages/client/client.bemdecl.js
bem create block -l pages -t bemdecl.js client
dmage@nibbler ~/bem-bl-test $ cat pages/client/client.bemdecl.js
dmage@nibbler ~/bem-bl-test $

bem server: hangs during build

Поставить свежий bem server.
Поставить bem-bl-test.
Запустить bem server в bem-bl-test.
Вызвать в браузере сборку http://localhost:8080/pages/example/example.html
Сборка доходит до

[*] make 'pages/example/example.deps.js.meta.js' [6]
[=] Log of make 'pages/example/example.deps.js.meta.js' [6]

после чего виснет.

bem server: 404 error in case of "request to build absent node"

  1. Клонировать https://github.com/bem/bem-bl-test.
  2. Запустить bem server в корне.
  3. В браузере запросить http://localhost:8080/pages/example/example.html

Результат:

  1. В браузере HTTP error 404.
  2. В консоли сервера (реальные абсолютные пути заменил на fake):
trying to access /fake/bem-bl-test/pages/example/example.html
[*] make 'bem-bl' [1]
[=] Log of make 'bem-bl' [1]
git clone --progress git://github.com/bem/bem-bl.git /fake/bem-bl-test/bem-bl
Cloning into /fake/bem-bl-test/bem-bl...

remote: Counting objects: 8834, done.
remote: Compressing objects: 100% (2650/2650), done.
remote: Total 8834 (delta 5765), reused 8785 (delta 5721)
Receiving objects: 100% (8834/8834), 1.58 MiB | 360 KiB/s, done.
Resolving deltas: 100% (5765/5765), done.

cd /fake/bem-bl-test/bem-bl && git checkout master
Already on 'master'

[*] make 'pages*' [1]
[=] Log of make 'pages*' [1]
*** HTTP error: 404, undefined

Пустой runner приводит к падению bem

Похоже, последние коммиты bem / apw что-то крепко сломали. Поставленный начисто bem-tools/server падает.

  1. bem server падает по TypeError: Object #<Object> has no method 'findNode, at /../bem-tools/lib/server.js:76:23
  2. bem make падает по TypeError: Object #<Object> has no method 'findAndProcess, at /../bem-tools/lib/commands/make.js:56:22
    Везде гуляет пустой ({}) runner.

Ошибка в синтаксисе bem-tools /lib/level.js

в объявлении myPath внутри библиотеки bem-tools / lib / level.js
при объявлении переменных закаралась ошибка в виде точки с запятой вместо просто запятой

getBuildResults() для legacy-технологий

Нет возможности получить результат билда технологии написанной в legacy-стиле. Это бывает нужно, если новая технология содержит (доопределяет) контент старой технологии.

Update bem package with .ie.css tech

Sergey, could you please release new version of bem npm package with ie.css tech I have done right now. I will announce it in out Yarushka club with an example in bem-bl-test project which I have already done too.
Thank you!

bem server: silent errors in blocks

В нодах проглатываются ошибки, после чего сборка не работает, а в консоли (как make, так и server стектрейсов и вообще сообщений об ошибках нет). Один из примеров: в тело конструктора BundleNode добавить xxx.yyy; и запустить bem make pages/example/example.html на bem-bl-test.
Результат:

[*] make 'bem-bl' [1]
[=] Log of make 'bem-bl' [1]
cd /../bem-bl-test/bem-bl && git pull --progress origin server
Already up-to-date.

From git://github.com/bem/bem-bl
 * branch            server     -> FETCH_HEAD

cd /../bem-bl-test/bem-bl && git checkout server
Already on 'server'

[*] make 'pages*' [1]
** No rule to make target 'pages/example/example.html'

bem server: deal with require() caching of loaded modules

The problem is that require() caches loaded modules, so when we need to reload changes make.js or something we'll get a link to the obsolete cached copy of new and not a new version from disk.

There are some places in code that need to be fixed.

Incorrect handling of paths on windows

Добрый день, первый раз сталкиваюсь с nodejs поэтому могу что-то не правильно делать.

Поставил node.exe версии 0.6.6 на windows 7 x64, пользуюсь ryppi пакет менеджером. Тестовые проекты для nodejs работают.

Установил bem. Но при обращении к утилите - резальтатов никаких не даёт. Опытным путём (console.log) - выяснил что методы .act() не вызываются никогда.

к примеру в файле bem/lib/commands/create/level.js после строчки "module.exports = function() {" -- console.log(); выполняется, а далее по коду в методе act() -- нет. Запускал с командой bem create level blocks.

Так же не отвечают на запросы все другие команды - даже bem --help ничего не выводит.

bem create level -t css blocks: Cannot find module 'bem/lib/techs/default'

/Users/vitaly/sites/project# bem create level -t css blocks

node.js:134
throw e; // process.nextTick error, or 'error' event on first tick
^
Error: Cannot find module 'bem/lib/techs/default'
at Function._resolveFilename (module.js:320:11)
at Function._load (module.js:266:25)
at require (module.js:348:19)
at new (/usr/local/lib/node/.npm/bem/0.0.6/package/lib/tech.js:9:16)
at [object Object].createTech (/usr/local/lib/node/.npm/bem/0.0.6/package/lib/context.js:39:12)
at [object Object].getTech (/usr/local/lib/node/.npm/bem/0.0.6/package/lib/context.js:33:38)
at /usr/local/lib/node/.npm/bem/0.0.6/package/lib/commands/create/level.js:75:44
at Array.forEach (native)
at /usr/local/lib/node/.npm/bem/0.0.6/package/lib/commands/create/level.js:74:66
at Array.forEach (native)

/Users/vitaly/sites/project# bem -v
0.0.6

bem server: Initialize block library targets

Read block libraries config from .bem/lib.js, generate target for each library.

Config can be like this:

exports.getLibraries = function() {

    return {
        'bem-bl': {
            type: 'git',
            url: 'git://github.com/bem/bem-bl.git',
            treeish: 'master'
        }
    }

};

bem server: Initialize bundle level targets

Read config from .bem/<something>.js (.bem/levels.js?), look for function-getter or glob variable, generate target for each bundle level present.

Config could be like this:

// regexp?
exports.bundleLevelsRegexp = /bundles.*?/;

// glob pattern?
exports.bundleLevelsGlob = 'bundles* pages*';

// function-getter (overriding default implementation)
exports.getBundleLevels = function() {
    return ['pages', 'widgets'];
};

Ошибка при сборке deps файла.

Симптомы:

Блок А имеет элемент А.а.

Блок А подключен к блоку Б и блоку В.

Блок Б подключен к блоку Г, который подключен к блоку В.

После сборки деклорация об элемент A.а в deps-фале отсутствует, соответственно и в сборке.

Если отсоединить блок А от блока Б или блока В и оставить только в одном из них. То декларация элемента А.а появляется в deps-файле и в сборке.

Все колдовство происходило с js фалами. Других технологий там нет.

[bug] `bem create level` TypeError: Cannot call method 'shift' of undefined

Пытаюсь создать уровень переопределения с точкой в имени: bem create level level.blocks. Получаю

node.js:134
        throw e; // process.nextTick error, or 'error' event on first tick
        ^
TypeError: Cannot call method 'shift' of undefined
    at Cmd.parse (/usr/lib/node/.npm/bem/0.0.9/package/lib/optparse.js:163:37)
    at Cmd.parse (/usr/lib/node/.npm/bem/0.0.9/package/lib/optparse.js:156:21)
    at Cmd.parse (/usr/lib/node/.npm/bem/0.0.9/package/lib/optparse.js:156:21)
    at Object.main (/usr/lib/node/.npm/bem/0.0.9/package/lib/bem.js:23:10)
    at Object.<anonymous> (/usr/lib/node/.npm/bem/0.0.9/package/bin/bem:3:23)
    at Module._compile (module.js:402:26)
    at Object..js (module.js:408:10)
    at Module.load (module.js:334:31)
    at Function._load (module.js:293:12)
    at Array.<anonymous> (module.js:421:10)

Если передать ключ -C ./то уровень создается.

ie.css tech has to include non-ie file first

Example:

@import url(index.css);
@import url(../../blocks/i-global/i-global.ie.css);
@import url(../../blocks/i-global/_type/i-global_type_reset.ie.css);
@import url(../../blocks/i-global/_type/i-global_type_simple.ie.css);
@import url(../../blocks/b-head-tabs/b-head-tabs.ie.css);

instead of:

@import url(../../blocks/i-global/i-global.ie.css);
@import url(../../blocks/i-global/_type/i-global_type_reset.ie.css);
@import url(../../blocks/i-global/_type/i-global_type_simple.ie.css);
@import url(../../blocks/b-head-tabs/b-head-tabs.ie.css);

Форматирование результирующего HTML

Сейчас выводимый html файл не содержит форматирования.
Хочется иметь возможность получать "красивый" html.
Необходимо для удобного распиливая html на куски, и нормального diffa.

Комментирование html кода средствами bemjson.

Хочется иметь в bemjson встроенную поддержку комментирования блоков.
например

{
    block: 'b-test',
    info: true,
    content: 'hello'
}

будет развариваться в
<!-- start b-test -->
<div class='b-test'>
hello
</div>
<!-- end b-test -->

Implement arch actualization mechanizm in node classes

Ноды (LevelNode, BundlesLevelNode, BundleNode) должны актуализировать состояние arch во время своего выполнения. Сейчас эти ноды достраивают граф ровно один раз при первом выполнении.

В нодах должна быть реализована защита от частой перестройки графа (для начала, не чаще чем раз в 5 секунд).
В будущем механизм контроля будет отдан модулю, мониторящему изменения на файловой системе.

Пересмотр сборки ie.css технологии

Сейчас ie.css технология собирается так:

@import url(../../bem-bl/blocks-desktop/b-link/_pseudo/b-link_pseudo_yes.ie.css);

Есть мнение, что правильней собирать эту технологию в таком виде:

@import url(../../bem-bl/blocks-desktop/b-link/_pseudo/b-link_pseudo_yes.ie.css);
@import url(../../blocks/b-link/_pseudo/b-link_pseudo_yes.css);
@import url(../../blocks/b-link/_color/b-link_color_red.css);
@import url(../../blocks/b-link/_color/b-link_color_green.css);

ie.css файлы должны подключаются там, где объявлены, а не в конце документа, как это происходит сейчас

bem server: ability to configure and fine tune of build rules

We need an ability to configure (override some points and replace whole logic when needed) and fine tune of default build rules.

Proposed solution.

We add an ability for user to specify his own rules in .bem/make.js for the project (starting build arch) and its levels (blocks and bundles/pages) and in path/to/block-or-bundle/block-or-bundle.make.js for the block or bundle. The result of require() of this file then treated as a second argument to INHERIT(baseNodeClass, requiredObj) (require('inherit')) call. baseNodeClass is a class describing default build rules for particular builded object.

This solution doesn't cover overriding of generic nodes like FileNode, BemCreateNode and BemBuildNode.

Feature request: bem create --force param

%.html: %.bemhtml.js %.css %.js
$(call BEM_CREATE,bem-bl/blocks-desktop/i-bem/bem/techs/html.js)

bem create выдаёт ошибку "File already exists". Спасает "rm $@" в мейк-файле. Но удаление — плохая практика, т.к. новый файл может не собраться.
Хорошо бы иметь ключик --force (-f) для принудительного перезаписывания файла цели в случае успешной генерации.

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.