И называется она Разработка → Приятная сборка frontend проекта. Пару месяцев назад я ее уже просмотрел, но не оценил..., а вчера нашел снова и прочитал с удовольствием. Почему? Потому, что сейчас я решаю задачку о том, по каким папкам мне раскладывать мои новые проекты... К статье сделано более 100 комментарие. Так что, надеюсь выделить для себя подпроцессы фронтенда с наборами инструментов под каждый процесс. Например, я пытаюсь спрогнозировать поведение заказчиков, сделал я им сайт-визитку, а они захотят добавить к неу блог, а потом окажется, что им и контент для блога нужен... С точки зрения "фронтенда", у меня должны быть заготовки шаблонов и стилей... (и движков, но это уже бэкэнд ?)... и под "визитку" и под "блог" сразу. И это очевидно... Так что здесь продолаем осваивать инструменты, и между делом устанавливаем авторские заготовки для сборки проектов.
Разработка → Приятная сборка frontend проекта
Frontend-devilМою рабочую версию сборщика вы можете скачать на моем github.
Оказывается, у Gulp есть чёрный список плагинов
npmjs The npm registry hosts over a quarter million packages of reusable code — the largest code registry in the world.
Mincer - assets processor JavaScript port of Sprockets (v2.10.0). It features same declarative dependency management (with exactly same language) for CSS and JavaScript and preprocessor pipeline. Mincer allows you to write assets in the languages like: CoffeeScript, LESS, Stylus and others. Moreover mincer has advanced built-in features, not available in sprockets:
sourcemaps support
macros support (nice alternative to EJS)
Choose: Grunt, Gulp, or npm? npm as a build tool
Rule of three )(computer programming)
separation of concerns In computer science, separation of concerns (SoC) is a design principle for separating a computer program into distinct sections, such that each section addresses a separate concern. A concern is a set of information that affects the code of a computer program
Bower: зачем фронтенду нужен менеджер пакетов gulp-bower нужен для установки зависимостей. А для обработки зависимостей нужен main-bower-files
run-sequence Run a series of dependent gulp tasks in order
gulp documentation
Frontizer Недавно делал нечто подобное, но без bower (мне не нравится, что bower тянет за собой содержимое всего репозитория вместо одного js-файла) и с шаблонизатором Handlebars (ведь даже на фронте часто проще заполнять пространство в цикле, например, а не писать голый html). Так же livereload работает веселее — он не перегружает всю страницу, если изменены стили, а только перегружает сами стили. Ну и я использовал grunt, хотя можно попробовать и на gulp перейти.
Ну и вообще у меня как-то попроще получилось, хотя вроде все примерно то же самое)
Вот, если кому интересно
Gulp task with Less processingВдруг кому-то еще для быстрого старта и ознакомления пригодится мой конфиг Gulp-а с комментариями на русском для каждой задачи. В прошлом году познакомил с Gulp-ом коллег и некоторые уже активно используют, да и мне легче передавать проект. Gulp task with Less processing (autoprefixer), live reload (browser-sync), javascript (es6, babelify, react), error handling, images optimization, jade templates
bower-installerЕсли хотите устанавливать через bower только самые нужные файлы, можно использовать bower-installer: github.com/blittle/bower-installer
data URI scheme Спрайты устарели, нынче модно в dataURI всё кодировать в отдельный CSS. ...The data URI scheme is a uniform resource identifier (URI) scheme that provides a way to include data in-line in web pages as if they were external resources.
К статье есть frontend-devil.git, конечно, его надо установить¶
F:\stradorusite\GULP-projects\frontend-devil>git clone https://github.com/Insayt/frontend-devil.git
Cloning into 'frontend-devil'...
remote: Counting objects: 89, done.
remote: Total 89 (delta 0), reused 0 (delta 0), pack-reused 89
Unpacking objects: 100% (89/89), done.
Checking connectivity... done.
F:\stradorusite\GULP-projects\frontend-devil>
Установка прошла без проблем
F:\stradorusite\GULP-projects\frontend-devil\frontend-devil>npm install
...
npm WARN optional Skipping failed optional dependency /chokidar/fsevents:
npm WARN notsup Not compatible with your operating system or architecture: fsevents@1.0.12
npm WARN frontend-devil@1.0.1 No license field.
F:\stradorusite\GULP-projects\frontend-devil\frontend-devil>
####Вот что залилось
F:\stradorusite\GULP-projects\frontend-devil\frontend-devil>dir
Том в устройстве F имеет метку MYLINUXLIVE
Серийный номер тома: CE7F-8134
Содержимое папки F:\stradorusite\GULP-projects\frontend-devil\frontend-devil
27.05.2016 12:13 <DIR> .
27.05.2016 12:13 <DIR> ..
27.05.2016 12:13 37 .gitignore
27.05.2016 12:13 170 README.md
27.05.2016 12:13 375 bower.json
27.05.2016 12:13 3 503 gulpfile.js
27.05.2016 12:13 612 package.json
27.05.2016 12:13 <DIR> src
27.05.2016 12:17 <DIR> node_modules
5 файлов 4 697 байт
4 папок 1 904 582 656 байт свободно
F:\stradorusite\GULP-projects\frontend-devil\frontend-devil>
Теперь посмотрим, что в конфигурационных файлах¶
# %load F:\stradorusite\GULP-projects\frontend-devil\frontend-devil\package.json
{
"name": "frontend-devil",
"version": "1.0.1",
"description": "Devil boilerplate for html+js+css apps",
"repository": {
"type": "git",
"url": "https://github.com/Insayt/frontend-devil"
},
"dependencies": {
"browser-sync": "^2.2.3",
"gulp": "^3.8.11",
"gulp-autoprefixer": "^2.1.0",
"gulp-imagemin": "^2.2.1",
"gulp-minify-css": "^1.0.0",
"gulp-rigger": "^0.5.8",
"gulp-sass": "^1.3.3",
"gulp-sourcemaps": "^1.5.0",
"gulp-uglify": "^1.1.0",
"gulp-watch": "^4.1.1",
"imagemin-pngquant": "^4.0.0",
"rimraf": "^2.3.1"
}
}
# %load F:\stradorusite\GULP-projects\frontend-devil\frontend-devil\bower.json
{
"name": "frontend-devil",
"version": "1.0.0",
"homepage": "https://github.com/Insayt/frontend-devil",
"authors": [
"Alex Insayt <insait.rostov@ya.ru>"
],
"description": "Devil boilerplate for html+js+css apps",
"moduleType": [
"globals"
],
"license": "MIT",
"dependencies": {
"normalize.css": "*",
"jquery": "2.*"
}
}
В оригинале статьи можно посмотреть пояснения
# %load F:\stradorusite\GULP-projects\frontend-devil\frontend-devil\gulpfile.js
'use strict';
var gulp = require('gulp'),
watch = require('gulp-watch'),
prefixer = require('gulp-autoprefixer'),
uglify = require('gulp-uglify'),
sass = require('gulp-sass'),
sourcemaps = require('gulp-sourcemaps'),
rigger = require('gulp-rigger'),
cssmin = require('gulp-minify-css'),
imagemin = require('gulp-imagemin'),
pngquant = require('imagemin-pngquant'),
rimraf = require('rimraf'),
browserSync = require("browser-sync"),
reload = browserSync.reload;
var path = {
build: {
html: 'build/',
js: 'build/js/',
css: 'build/css/',
img: 'build/img/',
fonts: 'build/fonts/'
},
src: {
html: 'src/*.html',
js: 'src/js/main.js',
style: 'src/style/main.scss',
img: 'src/img/**/*.*',
fonts: 'src/fonts/**/*.*'
},
watch: {
html: 'src/**/*.html',
js: 'src/js/**/*.js',
style: 'src/style/**/*.scss',
img: 'src/img/**/*.*',
fonts: 'src/fonts/**/*.*'
},
clean: './build'
};
var config = {
server: {
baseDir: "./build"
},
tunnel: true,
host: 'localhost',
port: 9000,
logPrefix: "Frontend_Devil"
};
gulp.task('webserver', function () {
browserSync(config);
});
gulp.task('clean', function (cb) {
rimraf(path.clean, cb);
});
gulp.task('html:build', function () {
gulp.src(path.src.html)
.pipe(rigger())
.pipe(gulp.dest(path.build.html))
.pipe(reload({stream: true}));
});
gulp.task('js:build', function () {
gulp.src(path.src.js)
.pipe(rigger())
.pipe(sourcemaps.init())
.pipe(uglify())
.pipe(sourcemaps.write())
.pipe(gulp.dest(path.build.js))
.pipe(reload({stream: true}));
});
gulp.task('style:build', function () {
gulp.src(path.src.style)
.pipe(sourcemaps.init())
.pipe(sass({
includePaths: ['src/style/'],
outputStyle: 'compressed',
sourceMap: true,
errLogToConsole: true
}))
.pipe(prefixer())
.pipe(cssmin())
.pipe(sourcemaps.write())
.pipe(gulp.dest(path.build.css))
.pipe(reload({stream: true}));
});
gulp.task('image:build', function () {
gulp.src(path.src.img)
.pipe(imagemin({
progressive: true,
svgoPlugins: [{removeViewBox: false}],
use: [pngquant()],
interlaced: true
}))
.pipe(gulp.dest(path.build.img))
.pipe(reload({stream: true}));
});
gulp.task('fonts:build', function() {
gulp.src(path.src.fonts)
.pipe(gulp.dest(path.build.fonts))
});
gulp.task('build', [
'html:build',
'js:build',
'style:build',
'fonts:build',
'image:build'
]);
gulp.task('watch', function(){
watch([path.watch.html], function(event, cb) {
gulp.start('html:build');
});
watch([path.watch.style], function(event, cb) {
gulp.start('style:build');
});
watch([path.watch.js], function(event, cb) {
gulp.start('js:build');
});
watch([path.watch.img], function(event, cb) {
gulp.start('image:build');
});
watch([path.watch.fonts], function(event, cb) {
gulp.start('fonts:build');
});
});
gulp.task('default', ['build', 'webserver', 'watch']);
К статье более 100 комментариев, вот некоторые темы оттуда¶
Логично, да, но npm такой же специальный пакет, только нативный :) Насчет стримов — смотрите, если вам нужны программные стримы, такие, как в gulp — можно пойти путем gulp, создать файл для сборки build.js, где делать все, что угодно и как угодно, не ограничиваясь плагинами gulp, которые по сути обертки над пакетами npm. В том числе вы можете использовать и стримы, и gulp, и что угодно, без каких-либо ограничений.
Но на самом деле это все достаточно сложно для повседневных задач, и практически всегда можно обойтись тасками в "scripts" с нативными пайпами вместо стримов.
Чем это классно? У вас нет лишнего файла gulpfile.js в проекте; вы используете декларативную нотацию тасков, что весьма читабельно; новый пользователь может узнать все возможные операции для проекта прямо из package.json, в одном месте, что удобно; наконец, вы используете нативный инструмент, который гарантированно будет существовать долго и всегда включает все возможные пакеты, в отличие от систем сборки, где их может недоставать.
Собственно, управление зависимостями. Вы можете в bower.json указать конкретные версии библиотек от которых зависит ваше приложение. Можете даже указать конкретный коммит в GIT-репозитории (иногда бывает нужно и такое, когда, например, в какой-то из веток/пулл-реквестов есть фикс, но автор либы не спешит выпускать новую версию).
У вас нет сортировки зависимости, например, поставить jquery или angularjs первым. Вот накидал свой велосипед на эту тему: gist.github.com/dshster/2535b4317e495d070bcb
Провел эксперимент, с картинкой png Спрайты устарели, нынче модно в dataURI всё кодировать в отдельный CSS. ...Не заметил этой моды. В основном встречаю спрайты или svg
LibSass всем хорош, только больно уж отстаёт от основной ветки. В итоге часть самых вкусностей не работает.
Нашёл для себя в качестве альтернативы Stylus, который: а) нативный, б) довольно быстрый, в) более гибкий.
gulp-sourcemaps файл Обратил внимание, что генерируемый gulp-sourcemaps файл просто огромен (x10 от размера минифицированного файла). В опциях плагина ничего про сжатие карты не нашел, как победить такую ситуацию? И может быть, можно как-то ограничить пользователей от загрузки .map файла, он ведь им по факту не нужен?
Посты чуть ниже также могут вас заинтересовать
Комментариев нет:
Отправить комментарий