1
0
mirror of https://github.com/kremalicious/blog.git synced 2025-02-14 21:10:25 +01:00

Merge pull request #20 from kremalicious/gulpgulp

Gulp gulp
This commit is contained in:
Matthias Kretschmann 2015-06-07 21:12:56 +02:00
commit 6d4d7d2eb9
52 changed files with 325 additions and 372 deletions

View File

@ -1,338 +0,0 @@
module.exports = function(grunt){
'use strict';
// config
var gruntConfig = {
src: '_src',
site: '_site',
build: '_build',
cdnurl: 'https://d2jlreog722xe2.cloudfront.net',
assets: {
stylus: 'assets/styl',
css: 'assets/css',
js: 'assets/js',
img: 'assets/img',
fonts: 'assets/fonts'
}
};
// banner
grunt.log.writeln("");
grunt.log.writeln(" <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<>>>>>>>>>>>>>>>>>>>>>>>>>>>>");
grunt.log.writeln("");
grunt.log.writeln(" (o) Just what do you think you're doing, Matthias? ");
grunt.log.writeln("");
grunt.log.writeln(" <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<>>>>>>>>>>>>>>>>>>>>>>>>>>>>");
grunt.log.writeln("");
// Grunt config
grunt.initConfig({
pkg: grunt.file.readJSON('package.json'),
config: gruntConfig,
// clean everything
clean: {
site: [
'<%= config.site %>/*',
'<%= config.site %>/.htaccess',
'!<%= config.site %>/media'
],
build: [
'<%= config.build %>/*',
'<%= config.build %>/.htaccess'
]
},
// Jekyll
jekyll: {
options: {
src : '<%= config.src %>/',
config: './_config.yml'
},
production: {
options: {
lsi: true
}
},
development: {
options: {
drafts: true,
future: true,
//limit_posts: 5
}
}
},
// Stylus
stylus: {
compile: {
options: {
'include css': true,
compress: false
},
files: {
'<%= config.site %>/<%= config.assets.css %>/kremalicious3.min.css' : '<%= config.src %>/<%= config.assets.stylus %>/kremalicious3.styl',
'<%= config.site %>/<%= config.assets.css %>/poststyle-2300.min.css' : '<%= config.src %>/<%= config.assets.stylus %>/poststyle-2300.styl'
}
}
},
// Post process css
postcss: {
options: {
processors: [
// autoprefixer
require('autoprefixer-core')({browsers: 'last 2 versions'}),
// combine media queries
require('css-mqpacker'),
// css minification
require('csswring')
]
},
dist: {
src: '<%= config.site %>/<%= config.assets.css %>/*.css'
}
},
// Concatenate and minify js
uglify: {
options: {
report: 'min'
},
production: {
files: {
'<%= config.site %>/<%= config.assets.js %>/picturefill.min.js': [
'node_modules/picturefill/dist/picturefill.js'
],
'<%= config.site %>/<%= config.assets.js %>/CustomElements.min.js': [
'node_modules/webcomponents.js/CustomElements.js'
],
'<%= config.site %>/<%= config.assets.js %>/kremalicious3.min.js': [
'node_modules/jquery/dist/jquery.js',
'node_modules/masonry-layout/dist/masonry.pkgd.js',
'node_modules/imagesloaded/imagesloaded.js',
'bower_components/simple-jekyll-search/dest/jekyll-search.js',
'bower_components/time-elements/time-elements.js',
'<%= config.src %>/<%= config.assets.js %>/app.js'
]
}
}
},
// image optimization
imagemin: {
assets: {
files: [{
expand: true,
cwd: '<%= config.site %>/<%= config.assets.img %>/',
src: ['**/*.{png,jpg,jpeg,gif}'],
dest: '<%= config.site %>/<%= config.assets.img %>/'
}]
},
media: {
files: [{
expand: true,
cwd: '<%= config.site %>/media/',
src: ['**/*.{png,gif}'],
dest: '<%= config.site %>/media/'
}]
},
touchicons: {
files: [{
expand: true,
cwd: '<%= config.site %>/',
src: ['*.png'],
dest: '<%= config.site %>/'
}]
}
},
// dev server
connect: {
server: {
options: {
port: 1337,
hostname: '*',
base: '<%= config.site %>'
}
}
},
// watch
watch: {
options: {
livereload: true
},
stylus: {
files: ['<%= config.src %>/<%= config.assets.stylus %>/*.styl'],
tasks: ['stylus', 'postcss']
},
js: {
files: ['<%= config.src %>/<%= config.assets.js %>/*.js'],
tasks: ['uglify']
},
jekyll: {
files: [
'<%= config.src %>/**/*.html',
'<%= config.src %>/*.xml',
'<%= config.src %>/*.json',
'<%= config.src %>/.htaccess',
'<%= config.src %>/_includes/**',
'<%= config.src %>/_layouts/**',
'<%= config.src %>/_posts/**',
'<%= config.src %>/_drafts/**'
],
tasks: ['jekyll:development', 'stylus', 'postcss', 'uglify']
},
},
// assets versioning
rev: {
files: {
src: [
'<%= config.build %>/assets/{css,js,img,fonts}/*.*'
]
}
},
// updating assets paths in html/css
usemin: {
html: ['<%= config.build %>/**/*.html'],
css: ['<%= config.build %>/**/*.css'],
options: {
dirs: '<%= config.build %>',
basedir: '<%= config.build %>',
assetsDirs: ['<%= config.build %>', '<%= config.build %>/assets/{css,js,img,fonts}']
}
},
// insert CDN url by replacing text strings
replace: {
html: {
src: ['<%= config.build %>/**/*.html'],
overwrite: true,
replacements: [
{
from: '/assets/js/',
to: '<%= config.cdnurl %>/assets/js/'
},
{
from: '/assets/img/',
to: '<%= config.cdnurl %>/assets/img/'
},
{
from: '/media/',
to: '<%= config.cdnurl %>/media/'
},
{
from: 'https://kremalicious.com<%= config.cdnurl %>/media/',
to: 'https://kremalicious.com/media/'
}
]
},
css: {
src: ['<%= config.build %>/<%= config.assets.css %>/*.css'],
overwrite: true,
replacements: [
{
from: '../',
to: '<%= config.cdnurl %>/assets/'
}
]
}
},
// rsync stuff around
rsync: {
options: {
recursive: true
},
// copy media folder
copy_media: {
options: {
src: '<%= config.src %>/_media/',
dest: '<%= config.site %>/media',
exclude: ['**/gen'],
syncDestIgnoreExcl: true,
args: ['--update']
}
},
// copy build
copy_build: {
options: {
src: '<%= config.site %>/',
dest: '<%= config.build %>',
syncDest: true
}
},
// deployment
deploy: {
options: {
syncDest: true,
src: '<%= config.build %>/',
dest: 'domains/kremalicious.com/html',
host: 'kremalicious',
ssh: true,
compareMode: 'checksum',
args: ['--verbose']
}
}
}
});
// Load NPM Tasks, smart code stolen from @bluemaex <https://github.com/bluemaex>
require('fs').readdirSync('node_modules').filter(function (file) {
return file && file.indexOf('grunt-') > -1;
}).forEach(function (file) {
grunt.loadNpmTasks(file);
});
// Default Task, assets only
grunt.registerTask('default', [
'stylus',
'postcss',
'uglify',
'connect',
'watch'
]);
// Full Dev server
grunt.registerTask('server', [
'clean:site',
'jekyll:development',
'rsync:copy_media',
'stylus',
'postcss',
'uglify',
'connect',
'watch'
]);
// Production build
grunt.registerTask('build', [
'clean',
'jekyll:production',
'rsync:copy_media',
'stylus',
'postcss',
'uglify',
'imagemin:assets',
'imagemin:touchicons',
'rsync:copy_build',
'rev',
'usemin',
'replace'
]);
// Optimze media
grunt.registerTask('mediamin', [
'imagemin:media'
]);
// Deploy
grunt.registerTask('deploy', [
'rsync:deploy'
]);
};

View File

@ -31,13 +31,6 @@ Link | `rake link -- Title`
Get up and running
------------------
For various reasons the assets build process and Jekyll site generation is managed through Grunt instead of `jekyll` or `rake`.
Both, `grunt server` and `grunt build`, use [grunt-jekyll](https://github.com/dannygarcia/grunt-jekyll) to first generate the site into the `_site` folder and the following Grunt tasks output into that folder. The build task copies everything over into the `_build`folder.
The `media` folder holding the source post images is excluded from Jekyll site generation and rsynced around from `_src/_media` to `_site/media` before site generation starts.
Image size generation for post teaser images and photos is done with [jekyll-picture-tag](https://github.com/robwierzbowski/jekyll-picture-tag), putting resized images into `_site/media/gen`.
### Install dependencies
@ -49,20 +42,18 @@ npm install
### Development build
This generates the site and assets with some Jekyll development options and starts a local dev server combined with a livereloading watch task under `http://localhost:1337`.
**[jekyll-picture-tag](https://github.com/robwierzbowski/jekyll-picture-tag) makes site generation very slow at the moment.** During development, uncommenting [some lines](https://github.com/kremalicious/kremalicious3/blob/master/_src/_plugins/picture_tag.rb#L142-L144) in that plugin's file speeds up regeneration dramatically. Seriously, from like 10 min. to 10 sec. Downside: no teaser images or photos in the development build.
This generates the site and assets and starts a local dev server combined with a livereloading watch task under `http://localhost:1337`.
```bash
grunt server
gulp server
```
### Production build
Runs almost the same tasks as `grunt server` but puts everything into the `_build` directory, versions all assets and optimizes all image assets.
Runs almost the same tasks as `gulp server` but additionally versions all assets and optimizes all image assets.
```bash
grunt build
gulp build
```

View File

@ -45,7 +45,6 @@ redcarpet:
source: ./_src
destination: ./_site
exclude: ['assets/styl', 'app.js']
keep_files: ['media', 'gen']

View File

Before

Width:  |  Height:  |  Size: 25 KiB

After

Width:  |  Height:  |  Size: 25 KiB

View File

Before

Width:  |  Height:  |  Size: 14 KiB

After

Width:  |  Height:  |  Size: 14 KiB

View File

Before

Width:  |  Height:  |  Size: 5.5 KiB

After

Width:  |  Height:  |  Size: 5.5 KiB

View File

Before

Width:  |  Height:  |  Size: 708 B

After

Width:  |  Height:  |  Size: 708 B

View File

Before

Width:  |  Height:  |  Size: 1.6 KiB

After

Width:  |  Height:  |  Size: 1.6 KiB

View File

Before

Width:  |  Height:  |  Size: 65 KiB

After

Width:  |  Height:  |  Size: 65 KiB

View File

Before

Width:  |  Height:  |  Size: 11 KiB

After

Width:  |  Height:  |  Size: 11 KiB

View File

Before

Width:  |  Height:  |  Size: 26 KiB

After

Width:  |  Height:  |  Size: 26 KiB

View File

Before

Width:  |  Height:  |  Size: 44 KiB

After

Width:  |  Height:  |  Size: 44 KiB

View File

@ -33,7 +33,8 @@
</footer>
<script src="/assets/js/CustomElements.min.js"></script>
<script async src="/assets/js/kremalicious3.min.js"></script>
<script src="/assets/js/jquery.min.js"></script>
<script src="/assets/js/kremalicious3.min.js"></script>
<script>
(function(i,s,o,g,r,a,m){i['GoogleAnalyticsObject']=r;i[r]=i[r]||function(){

290
gulpfile.js Normal file
View File

@ -0,0 +1,290 @@
// load plugins
var $ = require('gulp-load-plugins')();
// manually require modules that won"t get picked up by gulp-load-plugins
var gulp = require('gulp'),
del = require('del'),
nib = require('nib'),
merge = require('merge-stream'),
pkg = require('./package.json');
// Temporary solution until gulp 4
// https://github.com/gulpjs/gulp/issues/355
var runSequence = require('run-sequence');
// ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
// Terminal Banner
// ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
console.log("");
console.log(" <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<>>>>>>>>>>>>>>>>>>>>>>>>>>>>");
console.log("");
console.log(" (o) Just what do you think you're doing, Matthias? ");
console.log("");
console.log(" <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<>>>>>>>>>>>>>>>>>>>>>>>>>>>>");
console.log("");
// ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
// Config
// ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
var src = '_src',
dist = '_site',
cdn = 'https://d2jlreog722xe2.cloudfront.net';
var banner = [
'/**',
' ** <%= pkg.name %> v<%= pkg.version %>',
' ** <%= pkg.description %>',
' ** <%= pkg.homepage %>\n' +
' **\n' +
' ** <%= pkg.repository.url %>',
' ** <%= pkg.author.name %> <<%= pkg.author.email %>>',
' **/',
''
].join('\n');
// ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
// Tasks
// ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
//
// Delete build artifacts
//
gulp.task('clean', function(cb) {
return del([
dist + '/**/*',
dist + '/.*', // delete all hidden files
'!' + dist + '/media/**'
], cb);
});
//
// Jekyll
//
gulp.task('jekyll', function (cb){
var spawn = require('child_process').spawn;
var jekyll = spawn('jekyll', ['build', '--drafts', '--future'], {stdio: 'inherit'});
jekyll.on('exit', function(code) {
cb(code === 0 ? null : 'ERROR: Jekyll process exited with code: '+code);
});
});
gulp.task('jekyll:production', function (cb){
var spawn = require('child_process').spawn;
var jekyll = spawn('jekyll', ['build', '--lsi'], {stdio: 'inherit'});
jekyll.on('exit', function(code) {
cb(code === 0 ? null : 'ERROR: Jekyll process exited with code: '+code);
});
});
//
// Styles
//
gulp.task('css', function() {
return gulp.src([
src + '/_assets/styl/kremalicious3.styl',
src + '/_assets/styl/poststyle-2300.styl'
])
.pipe($.stylus({ use: [nib()], 'include css': true }))
.pipe($.autoprefixer({ browsers: 'last 2 versions' }))
.pipe($.combineMq({ beautify: false }))
// .pipe($.uncss({
// html: [dist + '/**/*.html'],
// ignore: ['.in', '.collapsing']
// }))
.pipe($.cssmin())
.pipe($.rename({suffix: '.min'}))
.pipe($.header(banner, {pkg: pkg}))
.pipe(gulp.dest(dist + '/assets/css/'))
.pipe($.connect.reload());
});
//
// Scripts
//
// Libraries
gulp.task('js-libraries', function() {
var jquery = gulp.src('node_modules/jquery/dist/jquery.js'),
picturefill = gulp.src('node_modules/picturefill/dist/picturefill.js'),
CustomElements = gulp.src('node_modules/webcomponents.js/CustomElements.js')
return merge(jquery, picturefill, CustomElements)
.pipe($.uglify())
.pipe($.rename({suffix: '.min'}))
.pipe(gulp.dest(dist + '/assets/js/'))
});
// Project js
gulp.task('js-project', function() {
return gulp.src([
'node_modules/masonry-layout/dist/masonry.pkgd.js',
'node_modules/imagesloaded/imagesloaded.js',
'bower_components/simple-jekyll-search/dest/jekyll-search.js',
'bower_components/time-elements/time-elements.js',
src + '/_assets/js/*.js'
])
.pipe($.uglify())
.pipe($.concat('kremalicious3.min.js'))
.pipe($.header(banner, {pkg: pkg}))
.pipe(gulp.dest(dist + '/assets/js/'))
.pipe($.connect.reload());
});
// Collect all script tasks
gulp.task('js', ['js-libraries', 'js-project']);
//
// Copy images
//
gulp.task('images', function() {
return gulp.src(src + '/_assets/img/**/*')
.pipe(gulp.dest(dist + '/assets/img/'))
.pipe($.connect.reload());
});
//
// Copy fonts
//
gulp.task('fonts', function() {
return gulp.src(src + '/_assets/fonts/**/*')
.pipe(gulp.dest(dist + '/assets/fonts/'))
.pipe($.connect.reload());
});
//
// Copy media
//
gulp.task('media', function() {
return gulp.src(src + '/_media/**/*')
.pipe(gulp.dest(dist + '/media/'))
.pipe($.connect.reload());
});
//
// Image optimization
//
gulp.task('imagemin', function () {
return gulp.src([
dist + '/**/*.{png,jpg,jpeg,gif,svg}',
'!' + dist + '/media/**/*'
])
.pipe($.cache($.imagemin({
optimizationLevel: 5, // png
progressive: true, // jpg
interlaced: true, // gif
multipass: true, // svg
svgoPlugins: [{removeViewBox: false}]
})))
.pipe(gulp.dest(dist));
});
//
// Revision static assets
//
gulp.task('revision', function () {
return gulp.src(dist + '/assets/**/*.{css,js,png,jpg,jpeg,svg,eot,ttf,woff}')
.pipe($.rev())
.pipe(gulp.dest(dist + '/assets/'))
// output rev manifest for next replace task
.pipe($.rev.manifest())
.pipe(gulp.dest(dist + '/assets/'));
});
//
// Replace all links to assets in files
// from a manifest file
//
gulp.task('revision-replace', function() {
var manifest = gulp.src(dist + '/assets/rev-manifest.json');
return gulp.src(dist + '/**/*.{html,xml,txt,json,css,js,png,jpg,jpeg,svg,eot,ttf,woff}')
.pipe($.revReplace({manifest: manifest}))
.pipe(gulp.dest(dist));
});
//
// CDN url injection
//
gulp.task('cdn',function(){
return gulp.src([dist + '/**/*.html', dist + '/assets/css/*.css'], {base: dist})
.pipe($.replace('/assets/css/', cdn + '/assets/css/'))
.pipe($.replace('/assets/js/', cdn + '/assets/js/'))
.pipe($.replace('/assets/img/', cdn + '/assets/img/'))
.pipe($.replace('/media/', cdn + '/media/'))
.pipe($.replace('https://kremalicious.com' + cdn + '/media/', 'https://kremalicious.com/media/'))
.pipe($.replace('../', cdn + '/assets/'))
.pipe(gulp.dest(dist));
});
//
// Dev Server
//
gulp.task('connect', function() {
return $.connect.server({
root: [dist],
livereload: true,
port: 1337
});
});
//
// Watch task
//
gulp.task('watch', function() {
gulp.watch([src + '/_assets/styl/**/*.styl'], ['css']);
gulp.watch([src + '/_assets/js/*.js'], ['js-project']);
gulp.watch([src + '/_assets/img/**/*'], ['images']);
gulp.watch([src + '/**/*.{html,xml,json,txt}'], ['jekyll']);
});
// ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
// Task sequences
// ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
//
// Dev Server
//
gulp.task('server', function(cb) {
runSequence(
'clean',
'jekyll',
['css', 'js', 'images', 'fonts', 'media'],
'watch',
'connect',
cb
);
});
//
// Production build
//
gulp.task('build', function(cb) {
runSequence(
'clean',
'jekyll:production',
['css', 'js', 'images', 'fonts', 'media'],
'revision',
'revision-replace',
'cdn',
'imagemin',
cb
);
});

View File

@ -1,9 +1,14 @@
{
"name": "kremalicious",
"author": "Matthias Kretschmann <m@kretschmann.io>",
"author": {
"name": "Matthias Kretschmann",
"email": "m@kretschmann.io"
},
"description": "Blog of Matthias Kretschmann",
"homepage": "https://kremalicious.com",
"version": "3.0.0",
"main": "Gruntfile.js",
"license": "MIT",
"main": "gulpfile.js",
"scripts": {
"postinstall": "bower install && bundle install"
},
@ -17,23 +22,28 @@
"webcomponents.js": ">=0.7.1"
},
"devDependencies": {
"autoprefixer-core": ">=5.2.0",
"css-mqpacker": ">=3.1.0",
"csswring": ">=3.0.5",
"grunt": ">=0.4.5",
"grunt-contrib-clean": ">=0.5.0",
"grunt-contrib-connect": ">=0.5.0",
"grunt-contrib-imagemin": ">=0.7.0",
"grunt-contrib-stylus": ">=0.18.0",
"grunt-contrib-uglify": ">=0.2.2",
"grunt-contrib-watch": ">=0.5.3",
"grunt-jekyll": ">=0.4.0",
"grunt-postcss": ">=0.4.0",
"grunt-rev": ">=0.1.0",
"grunt-rsync": ">=0.2.1",
"grunt-text-replace": ">=0.3.12",
"grunt-usemin": ">=2.0.2",
"del": ">=1.2.0",
"gulp": ">=3.8.0",
"gulp-autoprefixer": ">=2.3.0",
"gulp-cache": ">=0.2.10",
"gulp-combine-mq": ">=0.4.0",
"gulp-concat": ">=2.5.2",
"gulp-connect": ">=2.0.5",
"gulp-cssmin": ">=0.1.7",
"gulp-header": ">=1.2.2",
"gulp-imagemin": ">=2.2.1",
"gulp-load-plugins": ">=0.10.0",
"gulp-rename": ">=1.2.2",
"gulp-replace": ">=0.5.3",
"gulp-rev": ">=4.0.0",
"gulp-rev-replace": ">=0.4.1",
"gulp-stylus": ">=2.0.3",
"gulp-uglify": ">=1.2.0",
"gulp-uncss": ">=1.0.1",
"gulp-zip": ">=2.0.0",
"merge-stream": ">=0.1.7",
"nib": ">=1.0.3",
"run-sequence": ">=1.1.0",
"stylus": ">=0.45.0"
},
"engines": {
@ -41,6 +51,6 @@
},
"repository": {
"type": "git",
"url": "git@github.com:kremalicious/kremalicious3.git"
"url": "https://github.com/kremalicious/kremalicious3.git"
}
}