Есть ли какой-нибудь плагин gulp, который позволяет ему выполнять функцию статического генератора сайта?

Я использовал кучу статических генераторов сайтов, но gulp - лучший подход, потому что он настолько модульный. Мне интересно, есть ли плагин, который выполняет некоторые функции генератора статического сайта. На мой взгляд, все, что отсутствует, это то, что превратит файлы в каталог в структуру данных json для использования в меню на сайте.

Ответы

Ответ 1

Если вы хотите создать структуру .json и добавить ее в файл с помощью Gulp, вы можете сделать это одним из нескольких способов. Первые два используют чистые методы Gulp:

  • Вы можете написать плагин потока с помощью through или through2, который в основном должен будет создать структуру данных по одному файлу за раз, а затем во второй операции создаст (т.е. push() или queue()) файл в конце

  • Вы можете использовать конвейер Highland для .reduce() файлов в структуре данных, затем .map() результат в файл, возможно делая .merge() с исходным потоком

В обоих случаях вам понадобится ваш сгенерированный новый vinyl файл, чтобы иметь соответствующие .base и .path, которые ваш плагин на самом деле не знает, из-за того, что файл, который вы создаете, еще не существует, Таким образом, ваш код должен будет составить фальшивый абсолютный путь, чтобы gulp.dest() поставил его в нужное место.

Третий способ - написать плагин Metalsmith, который будет выглядеть примерно так:

function generate_json(files, smith, done) {
    var menu = {};
    Object.keys(files).forEach(function(path) {
        var file = files[path];
        if (path.slice(-5)===".html") {
            menu[path] = ... // whatever you want to store about `file`
        }
    });
    files["path/to/menu.json"] = { contents: new Buffer(JSON.stringify(menu)) };
    done();
}

Хотя он не намного короче кода, необходимого для других методов, вам нужно будет понять намного меньше, чтобы сделать это правильно. Просто убедитесь, что если у вас есть ошибка, вы вызываете done(err), чтобы передать ошибку.

Если вы хотите объединить этот плагин с конвейером Gulp, вы можете его обернуть, используя Gulpsmith:

gulp.src(...)
.pipe( things() )
.pipe( gulpsmith().use(generate_json) )
.pipe( other_stuff() )
.pipe( gulp.dest(...);

Верно, что Gulp имеет определенные преимущества перед Металсмитом. К сожалению, простота написания плагинов не одна из них. Создание новых файлов из плагина Gulp сложнее, чем должно быть, а также правильная обработка ошибок. Также существует сильное несоответствие импеданса между потоковым подходом и характер статических сайтов, требующих операций с несколькими файлами.

Например, если вы хотите встраивать свое меню на каждую страницу .html после его создания, вам понадобится более сложный плагин Gulp, потому что к тому моменту, когда ваш плагин "просмотрел" все файлы, они будут иметь "ушел вниз по течению", иначе вам придется держаться за них, а затем выпустить их снова после того, как вы закончите. В плагине Metalsmith вы просто добавите второй цикл после создания меню, чтобы снова вернуться к файлам, чтобы вставить данные на место. Вам не нужно ничего делать, чтобы передавать файлы, которые вы ничего не делаете.

Для этих задач API-интерфейс плагина Metalsmith недвусмысленно превосходит Gulp. Но для задач, которые могут работать только с потоковыми файлами, используйте существующие плагины Gulp для выигрыша.

В принципе, Metalsmith действительно является Gulp статических генераторов сайтов, а Gulp - Gulp потоковых систем сборки. И вы можете комбинировать сильные стороны обоих, используя Gulpsmith.

(Кстати, в зависимости от вашей реальной задачи вы можете найти некоторые существующие плагины Metalsmith, которые выполняют все или часть этого. Например, плагин metalsmith-collections создает индексы для файлов, соответствующих определенным шаблонам, там metalsmith-title, который извлекает HTML-заголовок для свойства title и т.д.)

Ответ 2

Да, вы можете создавать статические генераторы в gulp.

Вам, вероятно, потребуется меньше плагинов, чем вы думаете. Счет может, возможно, округлить до нуля.

Подумайте, что вы можете сделать с gulp и без плагинов:

var gulp = require('gulp'),
    browserify = require('browserify');

gulp.task('browserify', function(callback) {
    browserify('app.js').bundle()
        .pipe(fs.createWriteStream('dist/app.js')
        .on('close', callback); // why? read on...
});

Слишком много плагинов gulp не требуется. Они адаптируют некоторый оригинальный модуль к потокам виниловых объектов, используемых между gulp.src и gulp.dest, но потоки виниловых объектов не являются обязательными.

Вам нужен модуль X, чтобы сделать для вас часть своего статического поколения? Возьмите callback как аргумент вашей функции задачи и передайте его X вместе с вашими аргументами. Достаточно часто, это один лайнер: require -в плагин просто сделает ваш код длиннее.

Даже для тех частей вашего рабочего процесса, которые лучше всего описываются как "читать все, обрабатывать их в памяти и писать один раз", вы можете использовать through2.obj, чтобы преобразовать виниловые объекты или gulp-filter, чтобы выбить их. gulp плагины (или, что еще хуже, metalsmith плагины через gulpsmith) являются последним средством.

var gulp = require('gulp'),
    filter = require('gulp-filter'),
    through2 = require('through2');

gulp.task('generate-assets', function() {
    return gulp.src('path/to/your/content/and/templates/**')
               .pipe(filter(shouldFileSurvive))
               .pipe(through2.obj(makeFileDifferent))
               .pipe(gulp.dest('dist/'));
});

Примечание: если вы не перезвоняете, вы должны вернуть результат окончательного pipe. В противном случае gulp будет считать вашу задачу синхронной и не дожидаться, прежде чем запускать зависимые задачи.

Если последний канал возвращает нормальный поток, а не gulp.dest, сделайте обратный вызов (см. первый пример) до тех пор, пока b59182c7 не приземлится.

Ответ 3

Я пишу такой плагин, здесь gulp-static-site. Глядя на два других ответа, я бы сказал, что его функциональность подходит где-то между ванилом gulp и gulpsmith.

Gulp-filetree

Основная функциональность - это вычисление древовидной структуры данных, которая выполняется Gulp-filetree. Он постепенно наращивает дерево до тех пор, пока поток не закончится. Затем каждый файл (виниловый объект) повторно используется с свойством .tree.

Посмотрите tree.js, чтобы получить дополнительную информацию об этой структуре данных.

gulp-static-site

Эти плагины берут поток файлов HTML, отправляют их через Gulp-filetree и в шаблон нефрита, который добавляет базовый макет с помощью меню дерева каталогов и содержимого файла.

Lookie lookie здесь для основного трубопровода. https://github.com/0x01/gulp-static-site/blob/master/index.js#L146 (Как вы можете видеть, это не самое красивое, но ОК. Преобразование Markdown должно быть удалено, как это можно сделать в gulp вне плагина. Вероятно, тот же аргумент относится и к другим материалам...)

Q: Как это относится к gulpsmith?

Gulpsmith определенно кажется мощным и полным, я бы, вероятно, использовал его, если бы знал об этом в то время, когда я изначально кодировал это.

Это сказано; этот плагин прост, легковес и имеет небольшую кодовую базу. Я думаю, что легко понять, что он делает и изменить по своему вкусу, тянуть запросы, конечно же, приветствовать: -)

Если что-то еще неясно, сообщите нам об этом или сообщите мне, спасибо