Страницы

Поиск по вопросам

воскресенье, 7 июля 2019 г.

Сборка с помощью gulp данных из разных директорий

У меня есть подобная структура проекта
./source/ ./source/shop/ ./source/site/
./build/ ./build/shop/ ./build/site/
В source лежат исходники, которые должны после некоторых модфикаций выплевываться в build. За модификации отвечает gulp. Количество подпапок в source (и в build) соотстветвенно может меняться и каждый раз не хочется переписывать конфиг вручную. Поэтому я при помощи nodejs проверяю какие у меня есть папки в ./source/ и формирую примерно вот такой кофиг
config = { source: { shop: { templates: 'path', ... }, site: { templates: 'path', ... } }, build { shop: { templates: 'path', ... }, site: { templates: 'path', ... } } }
У меня задача правильно все это собирать в зависимости от того, что я хочу. И в связи с этим я сталкиваюсь с двумя задачами, к которым не знаю как подойти.
Во-первых, я хочу запускать сборку подобным образом:
# Собирает всё npm run build
# Собирает только необходимый мне модуль npm run build shop
Но я не знаю можно ли так вообще сделать, а если можно, то нужно будет передавать последнюю часть в gulp, а как это делать непонятно.
Во-вторых, не хочется плодить под каждый модуль задачу потому что все это может меняться. Ну то есть вот так не очень:
gulp.task('templates:shop', function() { return gulp.src(config.source.shop) .gulp.dist(config.build.shop) });
Плохо это потому что если я добавлю в source еще один модуль, например blog, то приется лезть в gulpfile.js и package.json и дописывать какой-то код, чтобы новый модуль поддерживался, а этого бы не хотелось. Возможно есть какое-то готовое решение для подобных задач, но я так ничего не смог найти.


Ответ

Я нашел решение, не знаю насколько это хорошо, но это работает. Я приведу примерный код, чтобы можно было понять суть, у меня в проекте все сложнее несколько.
gulpfile.js
// Для работы с файловой системой import fs from 'fs';
// Тут понятно ;-) import gulp from 'gulp';
// Чтобы получать аргументы import { argv } from 'yargs';
// Получаем список модулей const modules = fs.readdirSync('./source').filter(file => { return fs.statSync('./source' + file).isDirectory(); });
// Проверяем есть ли такой модуль и выводим ошибку, если запустили с несуществующим if(argv.module && !~apps.indexOf(argv.module)) { throw new TypeError('Ошибка при билде несуществующего приложения ' + argv.module); }
gulp.task('default', () => { // Пробегаемся по всем модулям modules.forEach(module => { // Если мы билдим не все, а только один модуль и сейчас в массиве пробегаемся не по этому модулю, то выходим, чтобы не сработала команда if( !(argv.module && argv.module === module || !argv.module) ) return;
// Собираем пути, у меня это делает отдельная функция, но идея такая же const srcPath = './source/' + module; const destPath = './build/' + module;
// Запускаем обработчик gulp.src(srcPath) .pipe(gulp.dest(destPath)); }); });
package.json
"scripts": { "build": "babel-node ./node_modules/gulp/bin/gulp.js" }
У меня тут Babel, чтобы работал ES6, но можно и без него в принципе.
Ну и запускается вот так:
# Собирает всё npm run build
# Собирает только необходимый мне модуль npm run build -- --module=site
Команда запуска билда конкретного модуля выглядит не так красиво, как я хотел изначально, но такой вариант меня тоже устроил.

Комментариев нет:

Отправить комментарий