bem-site / bem-forum-content-ru

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

Сборка верстки для передачи на back-end. #1286

Closed satanicman closed 7 years ago

satanicman commented 7 years ago

Всем привет. Посмотрел я вебинар 2х годичной давности https://www.youtube.com/watch?v=1GWoMnYldYc про БЭМ. Сильно заинтересовался я этой методологией. Решил сделать тестовый проект на полном бем стеке. Склонировал себе project-stub и начал делать, все замечательно не без подводных камней конечно но закончил я верстку. И пришло время собирать все в production, и вот тут то и засада. В том вебинаре был специальный таск для enb который собирал все основные файлы в отдельную папку, собирал туда все картинки и что самое главное переписывал все пути к картинкам относительно их нового расположения и нового имени. Я создал конфиг файл для борьщика, он мне все картинки собрал то, попробовал скопировать таск с этого вебинара и вставить к себе, но понятное дело это просто так не работает. Вот сам таск:

var fse = require('fs-extra'),
    path = require('path'),
    glob = require('glob'),

    rootDir = path.join(__dirname, '..');
config.task('dist', function (task) {

        // build targets and copy it to 'dist' folder
        function copyTargets(buildInfo) {
            buildInfo.builtTargets.forEach(function (target) {
                    var src = path.join(rootDir, target),
                        dst = path.join(rootDir, 'dist', path.basename(target));

                    fse.copySync(src, dst);
                });
        }

        return task.buildTargets(glob.sync('*.bundles/*'))
            .then(function (buildInfo) {
                copyTargets(buildInfo);
                task.log('Dist was created.');
            });
    });

В package.json добавил строку в скрипты

"dist": "YENV=production enb make dist -n"
но если из консоли запускать
npm run dist
то выдает ошибку
"Exit status 1 Failed at the bem-project-stub@2.0.0 dist script 'YENV=production enb make dist -n'."
. Если запустить так
./node_modules/.bin/enb make dist
То выдает такую вот ошибку
Target not found: desktop.bundles/index
Хотя эта папка есть. Я решил что оно ищет эту папку, как не странно, в корне диска. Дописал вот так
'./' + glob.sync('.bundles/')
Начало выдавать такую вот ошибку
targets.forEach is not a function
Как я понял, просто функция buildTargets ожидает на вход параметр object а я его преобразовываю в string. Но тогда нужно вернуться на предыдущий шаг и понять почему выдает что "desktop.bundles/index" не существует.

Вообще вопрос заключается в том, как вы передаете ту же верстку по БЭМ с использование project-stub в production. Повторюсь, самая большая проблема как по мне, это пути к картинкам, фиг с ним, файлы то можно и руками собрать, их там все по 3 на каждую страницу, но вот как быть с путями для меня вопрос. Может кто поможет настроить сборщик корректно?

tadatuta commented 7 years ago

Начну с истории про копирование в нужную структуру. Тут вариантов много и они все простые:

  1. Можно написать скрипт хоть на bash, который будет копировать нужные файлы
  2. Можно воспользоваться каким-то таск-раннером, вроде gulp и сделать таску, которая будет запускать enb make в продакшен-режиме (для этого сборку нужно запускать с переменной окружения YENV=production). При использовании через JS API запуск enb make возвращает промисс, на успешное выполнение которого можно копировать полученные файлы.
  3. Сконфигурировать конфиг ENB, чтобы он сам занимался копированием файлов. Пример можно посмотреть здесь (все ссылки ведут на тот же файл, но на разные строки): https://github.com/bem/bem-express/blob/master/.enb/make.js#L4 https://github.com/bem/bem-express/blob/master/.enb/make.js#L95-L96 https://github.com/bem/bem-express/blob/master/.enb/make.js#L99

Что касается рерайта путей к картинкам, то правильного конфига borschik будет достаточно. Примеры:

  1. Инлайним все картинки, ничего копировать не придется: https://github.com/bem/bem-express/blob/master/.borschik
  2. Картинки инлайним, шрифты копируем в папку static, но в CSS рерайтим так, как будто папка static раздается из корня сайта:

    {
    "paths": {
        "./static/": "/"
    },
    "freeze_paths": {
        "./node_modules/bem-font-awesome/fonts/*": "./static/fonts/",
    
        "./libs/**/*.woff": "./static/fonts/",
        "./libs/**/*.ttf": "./static/fonts/",
    
        "libs/**/*.svg": ":encodeURIComponent:",
        "libs/**": ":base64:",
    
        "./node_modules/**/*.svg": ":encodeURIComponent:",
        "./node_modules/**": ":base64:",
    
        "*.blocks/**/*.svg": ":encodeURIComponent:",
        "*.blocks/**": ":base64:"
    }
    }

Подробнее про конфигурацию borschik см. https://github.com/bem-site/bem-method/blob/bem-info-data/articles/borschik/borschik.ru.md#Минимизация-css-и-js

satanicman commented 7 years ago

@tadatuta Дак вот по поводу копирования в нужную структуру собственно и вопрос.

var fse = require('fs-extra'),
    path = require('path'),
    glob = require('glob'),

    rootDir = path.join(__dirname, '..');
config.task('dist', function (task) {

        // build targets and copy it to 'dist' folder
        function copyTargets(buildInfo) {
            buildInfo.builtTargets.forEach(function (target) {
                    var src = path.join(rootDir, target),
                        dst = path.join(rootDir, 'dist', path.basename(target));

                    fse.copySync(src, dst);
                });
        }

        return task.buildTargets(glob.sync('*.bundles/*'))
            .then(function (buildInfo) {
                copyTargets(buildInfo);
                task.log('Dist was created.');
            });
    });

Насколько я понимаю суть этого таска не замысловата, он просто запускает билд проекта и после его выполнения проходится по всем папкам и собирает с них файлы в папку 'dist' Только вопрос, почему он выдает ошибку

Target not found: desktop.bundles/index
Если на самом деле данный каталог существует? А по поводу борьщика я обязательно почитаю. И сразу по нему вопрос, с чем может быть связан тот факт что когда я в конфиге борьщика указываю папку назначения ту которая не существует то он выдает мне ошибку типа
rror: ENOENT: no such file or directory, open ...
. И вопрос номер 2, если фиг с ним создать руками папку назначения для борьщика и запустить enb make то почему то в корне появляется папка с полным путем относительно корня диска. Т.е. что я имею ввиду, допустим я меня проект лежит по такому пути "d:/Projects/project/bem/", то после сборки у меня в корне проекта появится папка "Projects/project/bem/build/img/" и вот эта папка "buld/img/" - это та папка которую я указываю в борьщике?

tadatuta commented 7 years ago

Насколько я понимаю суть этого таска не замысловата, он просто запускает билд проекта и после его выполнения проходится по всем папкам и собирает с них файлы в папку 'dist' Только вопрос, почему он выдает ошибку

Сделал буквально сделующее:

  1. Взял чистый project-stub
  2. Вставил в .enb/make.js приведенный код с таской
  3. enb make dist
    20:04:15.425 - build started
    20:04:15.446 - [rebuild] [desktop.bundles/index/index.bemjson.js] file-provider
    20:04:15.564 - [rebuild] [desktop.bundles/index/index.levels] levels
    20:04:15.565 - [rebuild] [desktop.bundles/index/index.bemdecl.js] bemjson-to-bemdecl
    20:04:15.623 - [rebuild] [desktop.bundles/index/index.deps.js] deps
    20:04:15.638 - [rebuild] [desktop.bundles/index/index.files] files
    20:04:15.638 - [rebuild] [desktop.bundles/index/index.dirs] files
    20:04:16.108 - [rebuild] [desktop.bundles/index/index.bemhtml.bemdecl.js] deps-by-tech-to-bemdecl
    20:04:16.125 - [rebuild] [desktop.bundles/index/index.browser.js] browser-js
    20:04:16.193 - [rebuild] [desktop.bundles/index/index.bemhtml.js] bemhtml
    20:04:16.241 - [rebuild] [desktop.bundles/index/index.html] bemjson-to-html
    20:04:16.504 - [rebuild] [desktop.bundles/index/index.css] enb-postcss
    20:04:16.513 - [rebuild] [desktop.bundles/index/index.bemhtml.deps.js] deps
    20:04:16.517 - [rebuild] [desktop.bundles/index/index.bemhtml.files] files
    20:04:16.517 - [rebuild] [desktop.bundles/index/index.bemhtml.dirs] files
    20:04:16.702 - [rebuild] [desktop.bundles/index/index.browser.bemhtml.js] bemhtml
    20:04:16.708 - [rebuild] [desktop.bundles/index/index.js] file-merge
    20:04:16.840 - [rebuild] [desktop.bundles/index/index.min.css] borschik
    20:04:16.985 - [rebuild] [desktop.bundles/index/index.min.js] borschik
    20:04:16.989 - [dist] Dist was created.
    20:04:16.991 - build finished - 2879ms
    /Users/tadatuta/projects/bem/project-stub ls dist/
    index.html  index.min.css   index.min.js

По borschik нужно искать проблему в конфиге. Не должно быть ни полных путей, ни ошибок при отсутствии необходимой папки.

Если не получится разобраться, можно опубликовать здесь ссылку на репозиторий, я попробую помочь.

satanicman commented 7 years ago

@tadatuta А можно узнать какой ОС вы пользуетесь. У меня стоит windows 10 и в ней выдает что Error: Target not found: desktop.bundles/index Даже на чистом project-stub. Я просто думаю что это может как-то с настройками ОС связанно или зависит от платформы. И еще на чтостом project-stub у меня почему то не подхватываются стили блоков и борьщик не собират изображения по указанному пути. Вот репозиторий https://github.com/satanicman/bem-test

tadatuta commented 7 years ago

По всей видимости дело действительно в ОС, т.к. в этом репо у меня тоже все в порядке:

git clone git@github.com:satanicman/bem-test.git
cd bem-test/
npm i
enb make dist

22:39:37.738 - build started
22:39:37.762 - [rebuild] [desktop.bundles/index/index.bemjson.js] file-provider
22:39:37.945 - [rebuild] [desktop.bundles/index/index.levels] levels
22:39:37.946 - [rebuild] [desktop.bundles/index/index.bemdecl.js] bemjson-to-bemdecl
22:39:37.972 - [rebuild] [desktop.bundles/index/index.deps.js] deps
22:39:37.975 - [rebuild] [desktop.bundles/index/index.files] files
22:39:37.975 - [rebuild] [desktop.bundles/index/index.dirs] files
22:39:38.235 - [rebuild] [desktop.bundles/index/index.bemhtml.bemdecl.js] deps-by-tech-to-bemdecl
22:39:38.369 - [rebuild] [desktop.bundles/index/index.bemhtml.deps.js] deps
22:39:38.370 - [rebuild] [desktop.bundles/index/index.browser.js] browser-js
22:39:38.370 - [rebuild] [desktop.bundles/index/index.bemhtml.files] files
22:39:38.370 - [rebuild] [desktop.bundles/index/index.bemhtml.dirs] files
22:39:38.403 - [rebuild] [desktop.bundles/index/index.browser.bemhtml.js] bemhtml

desktop.bundles/index/index.css
3:1 ⚠  /Users/tadatuta/projects/bem/bem-test/common.blocks/icon/_type/icon_type_meet.css:2:24: Missed semicolon [postcss-import]

22:39:38.547 - [rebuild] [desktop.bundles/index/index.css] enb-postcss
22:39:38.555 - [rebuild] [desktop.bundles/index/index.bemhtml.js] bemhtml
22:39:38.628 - [rebuild] [desktop.bundles/index/index.js] file-merge
22:39:38.761 - [rebuild] [desktop.bundles/index/index.html] bemjson-to-html
22:39:38.945 - [rebuild] [desktop.bundles/index/index.min.css] borschik
22:39:38.980 - [rebuild] [desktop.bundles/index/index.min.js] borschik
22:39:38.986 - [dist] Dist was created.
22:39:38.988 - build finished - 3204ms

и в результате выполнения в папке img появляется GD8S4K7cgL0W7ttsvzQxsO3YCb0.png.

Предлагаю попробовать поставить git bash и запускать сборку в нем, есть шанс, что поможет.

satanicman commented 7 years ago

@tadatuta Да я и так из баша все запускал. Пробовал и из cmd консоли, результат тот же. Завтра еще на работе попробую, правда там тоже винда, но мало ли.

satanicman commented 7 years ago

@tadatuta На работе та же фигня. Видимо все таки это именно то ОС зависит. Буду пробовать подымать виртуалку с Linux и там еще тестить.

tadatuta commented 7 years ago

Есть пара вот таких PR, связанных с windows, может быть они исправляются проблему? https://github.com/borschik/borschik/pull/130 https://github.com/borschik/borschik/pull/89

satanicman commented 7 years ago

@tadatuta Вся беда в ОС. На linux все собирается корректно.

satanicman commented 7 years ago

@tadatuta

borschik/borschik#130

Этот вариант помог с тем что борьщик не создавал папку.

config.task('dist', function (task) {
        var dirs = new Object();

        // build targets and copy it to 'dist' folder
        function copyTargets(buildInfo) {
            buildInfo.builtTargets.forEach(function (target) {
                var src = path.join(rootDir, target),
                    dst = path.join(rootDir, 'dist', path.basename(target));

                fse.copySync(src, dst);
            });
        }

        for (var line in glob.sync('*.bundles/*')) {
            dirs[line] = './' + glob.sync('*.bundles/*')[line]
        }
        return task.buildTargets(dirs)
            .then(function (buildInfo) {
                copyTargets(buildInfo);
                task.log('Dist was created.');
            });
    });

А вот этот КОСТЫЛИЩЕ помог с

Target not found: desktop.bundles/index

tadatuta commented 7 years ago

cc @blond