bem-site / bem-forum-content-ru

Content BEM forum for Russian speak users
MIT License
56 stars 6 forks source link

Пните, пожалуйста, куда смотреть для увеличения скорости сборки проекта. #1185

Open karalkou opened 7 years ago

karalkou commented 7 years ago

Проект на базе project-stub. Используются:

  1. bem-core v 3.0.1
  2. bem-components v 3.0.1
  3. enb

Около 100 страниц накопилось. Сборка идет около 30..70 с (30 000..70 000 мс) Можно ли что-то подкрутить для увеличения скорости?

tadatuta commented 7 years ago

Если действительно необходимо собирать одновременно 100 принципиально разных бандлов, то сильно вряд ли удастся сэкономить.

Возможно, между страницами есть много общего и количество бандлов можно сильно сократить, собирая только принципиально отличающиеся части? Или, наоборот, если страницы не пересекаются, то можно собирать точечно только то, что сейчас поменялось, а остальное не трогать.

В общем, чтобы мочь что-то подсказать, нужны подробности, а в идеале — посмотреть на код.

karalkou commented 7 years ago

@tadatuta Прошу прощения за долгий ответ.

Полный проект гораздо больше, но саму структуру, чтобы знать о чем говорим можно взять из моего предыдущего вопроса - репозиторий

Сейчас 111 страниц, в результате сборки в директорию merged собираются стили и скрипты всех страниц. Когда работаешь над одной страницей (css, js) и обновляешь страницу для применения написанного идет долгая сборка всего и вся.

Было бы вполне правильно разделять как-то сборку (например, по умолчанию собирать лишь одну страницу, с которой сейчас работаю, а всю стопку отдельной командой).

Нахожусь в некой растерянности, куда и как двигаться.

tadatuta commented 7 years ago

Если структура осталась прежней, то да, достаточно всего лишь в dev-режиме подключать стили и скрипты текущего бандла вместо merged (а для production возвращать merged, если это осмысленно). Пересборка ускорится в те самые 111 раз :)

karalkou commented 7 years ago

Да, осмысленно) На проде нужны смерженные файлы, но при разработке уж очень долго пересборка merged-bundle идёт. Т.е. получается

  1. меняю конфиг на такой:

    
    var fs = require('fs'),
    path = require('path'),
    techs = {
        // essential
        fileProvider: require('enb/techs/file-provider'),
        fileMerge: require('enb/techs/file-merge'),
    
        // optimization
        borschik: require('enb-borschik/techs/borschik'),
    
        // css
        stylus: require('enb-stylus/techs/stylus'),
    
        // js
        browserJs: require('enb-js/techs/browser-js'),
    
        // bemtree
        // bemtree: require('enb-bemxjst/techs/bemtree'),
    
        // bemhtml
        bemhtml: require('enb-bemxjst/techs/bemhtml'),
        bemjsonToHtml: require('enb-bemxjst/techs/bemjson-to-html')
    
    },
    enbBemTechs = require('enb-bem-techs'),
    merged = require('./techs/merged'),
    levels = [
        { path: 'libs/bem-core/common.blocks', check: false },
        { path: 'libs/bem-core/desktop.blocks', check: false },
        'common.blocks',
        'desktop.blocks',
        'form.blocks',
        'template.blocks'
    ];

module.exports = function(config) { var isProd = process.env.YENV === 'production', mergedBundleName = 'merged', pathToMargedBundle = path.join('desktop.bundles', mergedBundleName);

fs.existsSync(pathToMargedBundle) || fs.mkdirSync(pathToMargedBundle);

// тут условие-1 if( isProd ){ merged(config, pathToMargedBundle); }

config.nodes('*.bundles/*', function(nodeConfig) {
    var isMergedNode = path.basename(nodeConfig.getPath()) === mergedBundleName;

    isMergedNode || nodeConfig.addTechs([
        [techs.fileProvider, { target: '?.bemjson.js' }],
        [enbBemTechs.bemjsonToBemdecl]
    ]);

    nodeConfig.addTechs([
        // essential
        [enbBemTechs.levels, { levels: levels }],
        [enbBemTechs.deps],
        [enbBemTechs.files],

        // css
        [techs.stylus, {
            target: '?.css',
            sourcemap: false,
            autoprefixer: {
                browsers: ['last 20 versions', 'IE > 8', 'Opera > 11', 'Firefox >= 5', 'Chrome > 10']
            }
        }],
        // bemtree
        // [techs.bemtree, { sourceSuffixes: ['bemtree.js', 'bemtree'] }],

        // bemhtml
        [techs.bemhtml, { sourceSuffixes: ['bemhtml.js', 'bemhtml'] }],
        [techs.bemjsonToHtml],

        // client bemhtml
        [enbBemTechs.depsByTechToBemdecl, {
            target: '?.bemhtml.bemdecl.js',
            sourceTech: 'js',
            destTech: 'bemhtml'
        }],
        [enbBemTechs.deps, {
            target: '?.bemhtml.deps.js',
            bemdeclFile: '?.bemhtml.bemdecl.js'
        }],
        [enbBemTechs.files, {
            depsFile: '?.bemhtml.deps.js',
            filesTarget: '?.bemhtml.files',
            dirsTarget: '?.bemhtml.dirs'
        }],
        [techs.bemhtml, {
            target: '?.browser.bemhtml.js',
            filesTarget: '?.bemhtml.files',
            sourceSuffixes: ['bemhtml.js', 'bemhtml']
        }],

        // js
        [techs.browserJs, { includeYM: true }],
        [techs.fileMerge, {
            target: '?.js',
            sources: ['?.browser.js', '?.browser.bemhtml.js']
        }],

        // borschik
        [techs.borschik, { sourceTarget: '?.js', destTarget: '_?.js' }],
        [techs.borschik, { sourceTarget: '?.css', destTarget: '_?.css', tech: 'cleancss' }],
    ]);

// тут условие-2 if( isProd ){ nodeConfig.addTargets(isMergedNode ? ['?.css', '?.js'] : ['?.html']); } else { if( !isMergedNode ){ nodeConfig.addTargets(['?.css', '?.js', '?.html']); } }

});

};


2. прописываю в npm скриптах
"makeProd": "YENV=production node_modules/.bin/enb make",
"serverProd": "YENV=production node_modules/.bin/enb server"
3. Ну и в bemjson меняю пути до файлов (merged или для данного бандла) в зависимости от того, в каком режиме я сейчас работаю

Правильно ли описан процесс?
По идее не должно же быть ситуации, когда в дев-режиме не будут собираться какие-то необходимые данной странице (бандлу) js, css ?
tadatuta commented 7 years ago

Чтобы все быстро работало в режиме enb server достаточно только пункта 3 — если в BEMJSON в dev-режиме не будут запрашиваться merged-файлы, то они и пересобираться не будут.

По идее не должно же быть ситуации, когда в дев-режиме не будут собираться какие-то необходимые данной странице (бандлу) js, css ?

Такая ситуация может возникнуть только в случае, если полениться писать правильные deps-файлы. Например, зная, что на странице page1 есть зависимость от блока block1 и не добавить явно эту зависимость на page2, ожидая, что за счет merged-сборки она все равно окажется в итоговом бандле. Но это изначально неправильный подход.

karalkou commented 7 years ago

Да, если не будут запрашиваться, то и пересобираться не должны. Но в конфиге, чтобы ускорить сборку merged-бандла результирующие ?.css, ?.js отдельных страниц не собираются

nodeConfig.addTargets(isMergedNode ? ['_?.css', '_?.js'] : ['?.html']);

Потому и дошёл до условий и переменных окружения. Похоже, загнался уже)