
Security News
The Changelog Podcast: Practical Steps to Stay Safe on npm
Learn the essential steps every developer should take to stay secure on npm and reduce exposure to supply chain attacks.
@bem/sdk.deps
Advanced tools
The tool to work with dependencies in BEM.
Dependencies are defined as JavaScript objects in files with the .deps.js extension and look like this:
/* DEPS entity */
({
block: 'block-name',
elem: 'elem-name',
mod: 'modName',
val: 'modValue',
tech: 'techName',
shouldDeps: [ /* BEM entity */ ],
mustDeps: [ /* BEM entity */ ],
noDeps: [ /* BEM entity */ ]
})
Read more in the BEM technologies documentation.
Note. If you don't have any BEM projects available to try out the
@bem/sdk.declpackage, the quickest way to create one is to use bem-express.
An example is available in the RunKit editor.
To install the @bem/sdk.deps package, run the following command:
npm install --save @bem/sdk.deps
Attention. To use
@bem/sdk.deps, you must install Node.js 8.0+.
Use the following steps after installing the package.
To run the @bem/sdk.deps package:
To work with dependencies you need to define them in files with the .deps.js extension. If you don't have such files in your project, prepare them.
In this quick start we will create simplified file structure of the bem-express project:
app
βββ .bemrc
βββ app.js
βββ common.blocks
βΒ Β βββ header
βΒ Β βΒ Β βββ header.deps.js
βΒ Β βββ page
βΒ Β βΒ Β βββ page.deps.js
βββ development.blocks
Β Β βββ page
Β Β βββ page.deps.js
Define the dependencies in the files with .deps.js extension:
common.blocks/page/page.deps.js:
({
shouldDeps: [
{
mods: { view: ['404'] }
},
'header',
'body',
'footer'
]
})
common.blocks/header/header.deps.js:
({
shouldDeps: ['logo']
})
development.blocks/page/page.deps.js:
({
shouldDeps: 'livereload'
});
Create the project's configuration file. In this file you should specify levels with paths to search BEM entities and *.deps.js files inside.
Also you should specify level's sets. Each set is a list of level's layers. By default this tool will load dependencies for the desktop set.
.bemrc:
module.exports = {
root: true,
levels: [
{ naming: 'legacy', layer: 'common', path: 'common.blocks' },
{ naming: 'legacy', layer: 'development', path: 'development.blocks' }
],
sets: {
'desktop': 'common',
'development': 'common development'
}
}
Read more about working with the configurations in the @bem/sdk.config package.
Create a JavaScript file with any name (for example, app.js) and insert the following:
const deps = require('@bem/sdk.deps');
(async () => {
const dependencies = await deps.load({});
dependencies.map(e => console.log(e.vertex.id + ' => ' + e.dependOn.id));
})().catch(e => console.error(e.stack));
// header => logo
// page => page_view
// page => page_view_404
// page => header
// page => body
// page => footer
This code will load the project's dependencies with default settings (for the desktop set) and print it to console in a readable format.
Let's try to search *.deps.js files with dependencies in the common.blocks and development.blocks directories. To do it we will use the development set, which includes both common and development sets. Pass the set's name in the platform field.
app.js:
const deps = require('@bem/sdk.deps');
(async () => {
const platform = 'development';
const dependencies = await deps.load({ platform });
dependencies.map(e => console.log(e.vertex.id + ' => ' + e.dependOn.id));
})().catch(e => console.error(e.stack));
// header => logo
// page => page_view
// page => page_view_404
// page => header
// page => body
// page => footer
// page => livereload
In this time one more dependency was load (page => livereload).
When we load dependencies from files we can create a graph from them and get an ordered dependencies list for specified blocks, for example the header block.
To create a graph use the buildGraph() method:
deps.buildGraph(dependencies);
To get an ordered dependencies list for specified blocks use the dependciesOf() method for the created graph.
const graph = deps.buildGraph(dependencies);
console.log(graph.dependenciesOf({ block: 'header'}));
Add this code into your app.js file and run it:
const deps = require('@bem/sdk.deps');
(async () => {
const platform = 'development';
const dependencies = await deps.load({ platform });
dependencies.map(e => console.log(e.vertex.id + ' => ' + e.dependOn.id));
const graph = deps.buildGraph(dependencies);
console.log(graph.dependenciesOf({ block: 'header'}));
})().catch(e => console.error(e.stack));
// => [
// { 'entity': { 'block': 'header'}},
// { 'entity': { 'block': 'logo'}}
// ]
Loads data from the deps.js files in the project and returns an array of dependencies.
This method sequentially gathers the deps.js files, then reads them and then parses the data from them.
/**
* @typedef {Object} DepsLink
* @property {BemCell} vertex β An entity, that depends on the entity from the `dependOn` field.
* @property {BemCell} dependOn β An entity from which the `vertex` entity depends on.
* @property {boolean} [ordered] - `mustDeps` dependency if `true`.
* @property {string} [path] - Path to deps.js file if exists.
*/
/**
* @param {Object} config β An object with options to configure.
* @param {BemConfig} [config.config] β Project's configuration. Read more in the `@bem/sdk.config` package.
* If not specified the project's configuration
* file will be used (`.bemrc`, `.bemrc.js` or `.bemrc.json`).
* @param {Object} [format] β An object which contains functions to create `reader` and `parser`.
* If format not specified the files in `formats/deps.js/` module's directory will be used.
* @param {Function} format.reader β A function to create reader for the `deps.js` files.
* @param {Function} format.parser β A function to create parser for the `deps.js` files.
* @returns {Promise<Array<DepsLink>>}
*/
load(config, format)
Gathering deps.js files in the project. This method uses @bem/sdk.walk and @bem/sdk.config packages to get project's dependencies.
/**
* @param {Object} opts β An object with options to configure.
* @param {BemConfig} [opts.config] β Project's configuration.
* If not specified the project's configuration
* file will be used (`.bemrc`, `.bemrc.js` or `.bemrc.json`).
* @param {BemConfig} [opts.platform='desktop'] β The name of the level set to gather `deps.js` files for.
* @param {Object} [options.defaults={}] β Use this object as fallback for found configs.
* @returns {Promise<Array<BemFile>>}
*/
gather(opts)
Creates a generic serial reader for BemFile objects. If reader not specified the formats/deps.js/reader.js file will be used.
This method returns a function that reads and evaluates BemFile objects with data from files.
/**
* @param {function(f: BemFile): Promise<{file: BemFile, data: *, scope: BemEntityName}>} [reader] β A generic serial reader for `BemFile` objects.
* @returns {Function}
*/
read(reader)
Creates a parser to read data from BemFile objects returned by the read() function and returns an array of dependencies.
With returned array of dependencies you can create a graph using the buildGraph() function.
/**
* @typedef {Object} DepsData
* @property {BemCell} [scope] - BEM cell object to use as a scope.
* @property {BemEntityName} [entity] - Entity to use if no scope was passed.
* @property {Array<DepsChunk>} data - Dependencies data.
*/
/**
* @typedef {(string|Object)} DepsChunk
* @property {string} [block] β Block name
* @property {(DepsChunk|Array<DepsChunk>)} [elem] β Element name.
* @property {string} [mod] β Modifier name.
* @property {string} [val] β Modifier value.
* @property {string} [tech] β Technology (for example, 'css').
* @property {(DepsChunk|Array<DepsChunk>)} [elems] β Syntacic sugar that means `shouldDeps` dependency
* from the specified elements.
* @property {Array|Object} [mods] β Syntacic sugar that means `shouldDeps` dependency from the specified modifiers.
* @property {(DepsChunk|Array<DepsChunk>)} [mustDeps] β An ordered dependency.
* @property {(DepsChunk|Array<DepsChunk>)} [shouldDeps] β An unordered dependency.
*/
/**
* @typedef {Object} DepsLink
* @property {BemCell} vertex β An entity, that depends on the entity from the `dependOn` field.
* @property {BemCell} dependOn β An entity from which the `vertex` entity depends on.
* @property {boolean} [ordered] - `mustDeps` dependency if `true`.
* @property {string} [path] - Path to deps.js file if exists.
*/
/**
* @param {function} parser - Parses and evaluates BemFiles.
* @returns {function(deps: (Array<DepsData>|DepsData)): Array<DepsLink>} }
*/
parse(parser)
Creates a graph from the dependencies list. Read more about graphs and their methods.
/**
* @typedef {Object} DepsLink
* @property {BemCell} vertex β An entity, that depends on the entity from the `dependOn` field.
* @property {BemCell} dependOn β An entity from which the `vertex` entity depends on.
* @property {boolean} [ordered] - `mustDeps` dependency if `true`.
* @property {string} [path] - Path to deps.js file if exists.
*/
/**
* @param {Array<DepsLink>} deps - List of dependencies.
* @param {Object} options β An options used to create a graph.
* @param {Boolean} denaturalized β If `true` the created graph won't be naturalized.
* @returns {BemGraph} β Graph of dependencies.
*/
buildGraph(deps, options)
Β© 2019 Yandex. Code released under Mozilla Public License 2.0.
FAQs
Manage BEM dependencies
The npm package @bem/sdk.deps receives a total of 6 weekly downloads. As such, @bem/sdk.deps popularity was classified as not popular.
We found that @bem/sdk.deps demonstrated a not healthy version release cadence and project activity because the last version was released a year ago.Β It has 6 open source maintainers collaborating on the project.
Did you know?

Socket for GitHub automatically highlights issues in each pull request and monitors the health of all your open source dependencies. Discover the contents of your packages and block harmful activity before you install or update your dependencies.

Security News
Learn the essential steps every developer should take to stay secure on npm and reduce exposure to supply chain attacks.

Security News
Experts push back on new claims about AI-driven ransomware, warning that hype and sponsored research are distorting how the threat is understood.

Security News
Ruby's creator Matz assumes control of RubyGems and Bundler repositories while former maintainers agree to step back and transfer all rights to end the dispute.