I am trying to merge two gulp sources as follows:
gulp.task("build", ["clean"], function () {
var sb = gulp.src([
paths.bower + "jquery/jquery.js",
paths.bower + "angular/angular.js"
])
.pipe(flatten())
.pipe(gulp.dest(paths.scripts.vnd));
var sm = gulp.src([
paths.scripts.vnd + "jquery.js",
paths.scripts.vnd + "angular.js"
])
.pipe(concat("app.js"))
.pipe(gulp.dest(paths.scripts.dst))
.pipe(rename("app.min.js"))
.pipe(uglify())
.pipe(gulp.dest(paths.scripts.dst));
return merge(sb, sm);
});
Somehow only the first one is executed.
However, if I move the second one to another task with dependency on build then both are executed ...
Am I doing the merging the wrong way?
UPDATE 1
I updated my task to build both LESS files and JS files so I have:
var
gulp = require("gulp"),
fs = require("fs"),
merge = require("merge2"),
concat = require("gulp-concat"),
flatten = require("gulp-flatten"),
less = require('gulp-less'),
minify = require('gulp-minify-css'),
rename = require("gulp-rename"),
rimraf = require("gulp-rimraf"),
uglify = require("gulp-uglify");
var paths = {
bower: "./bower_components/",
scripts: {
app: "./" + "/scripts/app/",
dst: "./" + "/scripts/dst/",
vnd: "./" + "/scripts/vnd/"
},
styles: {
app: "./" + project.webroot + "/styles/app/",
dst: "./" + project.webroot + "/styles/dst/"
}
};
gulp.task("build", function () {
var sbm = gulp.src([
paths.styles.app + "*.less",
paths.styles.vnd + "*.less"
])
.pipe(less())
.pipe(minify())
.pipe(concat("app.css"))
.pipe(gulp.dest(paths.styles.dst))
.pipe(rename("app.min.css"))
.pipe(gulp.dest(paths.styles.dst));
var scb = gulp.src(
[
paths.bower + "jquery/jquery.js",
paths.bower + "angular/angular.js"
])
.pipe(flatten())
.pipe(gulp.dest(paths.scripts.vnd));
var scm = gulp.src(
[
paths.scripts.vnd + "jquery.js",
paths.scripts.vnd + "angular.js"
])
.pipe(concat("app.js"))
.pipe(gulp.dest(paths.scripts.dst))
return merge(sbm, scb, scm);
});
Somehow, this only executes sbm ... Does anyone knows why?
I also tried #topleft's suggestion but when including the LESS tasks at the end the app.min.js file get's the Less code in it ...
try this with merge2 plugin, that's how I do it
var merge = require('merge2');
gulp.task("build", ["clean"], function () {
var sb = gulp.src([
paths.bower + "jquery/jquery.js",
paths.bower + "angular/angular.js"
])
.pipe(flatten())
.pipe(gulp.dest(paths.scripts.vnd));
var sm = gulp.src([
paths.scripts.vnd + "jquery.js",
paths.scripts.vnd + "angular.js"
])
return merge(sb, sm)
.pipe(concat("app.js"))
.pipe(gulp.dest(paths.scripts.dst))
.pipe(rename("app.min.js"))
.pipe(uglify())
.pipe(gulp.dest(paths.scripts.dst));
});
as an example, here is how I merge my two LESS streams : (one is unCSS'ed, the other is not)
/* ===== LESS START ===== */
gulp.task('less', function() {
// Get static styles
var streamMain = gulp.src([
srcAssets + '/less/**/*.less',
srcAssets + '!/less/**/interactive.less',])
// Convert to CSS
.pipe(less())
// Remove unused CSS rules
.pipe(uncss({
html: [dest + '/index.html']
}))
// Get dynamic styles
var streamEvents = gulp.src(srcAssets + '/less/global/interactive.less')
// Convert to CSS
.pipe(less())
// Merge dynamic and static styles
return merge(streamMain, streamEvents)
// Concatenate in a single file
.pipe(concat('main.css'))
// Remove all comments
.pipe(stripCssComments({
all: true
}))
// Autoprefixer for browser compatibility
.pipe(autoprefixer())
// Compression
.pipe(minifyCSS())
// Output file
.pipe(gulp.dest(dest + '/css'));
});
/* ===== LESS END ===== */
Related
I have the following folder structure:
theme
assets
build
css
style.css
src
theme
buttons.scss
style.scss
components
hero
hero.html
hero.scss
index.html
Any changes in src theme and any scss file for a component (i.e. hero.scss) should all compile into style.css.
My theme files compile correctly, but my component scss files don't appear in style.css.
Instead, when I run gulp css, a separate css file appears under the build folder, i.e.
build
css
style.css
hero.css
How can I get it to compile everything into style.css?
gulpfile.js
const assetsSRC = 'assets/src/',
assetsDST = 'assets/build/',
components = 'components/';
const gulp = require('gulp'),
sass = require('gulp-sass')(require('sass')),
sourcemaps = require('gulp-sourcemaps'),
fs = require('fs'),
path = require('path'),
merge = require('merge-stream'),
postcss = require('gulp-postcss'),
autoprefixer = require('gulp-autoprefixer'),
plumber = require('gulp-plumber'),
concat = require('gulp-concat'),
uglify = require('gulp-uglify'),
strip = require('gulp-strip-comments');
const componentCSS = components + '**/*.scss',
componentJS = components + '**/*.js',
globalCSS = assetsSRC + 'scss/style.scss';
configCSS = assetsSRC + 'scss/config/**.scss';
themeCSS = assetsSRC + 'scss/theme/**.scss';
globalJS = assetsSRC + 'js/*.js';
libJS = assetsSRC + 'js/lib/*.js';
var sassOptions = {
errLogToConsole: true,
outputStyle: 'compressed'
};
function getFolders(dir) {
return fs.readdirSync(dir).filter(function(file) {
return fs.statSync(path.join(dir, file)).isDirectory();
});
}
function css() {
var folders = getFolders(components);
var tasks = folders.map(function(folder) {
var src = path.join(components, folder);
var dst = path.join(assetsDST + 'css');
return gulp.src(path.join(src, '/**/*.scss'))
.pipe(sourcemaps.init())
.pipe(sass(sassOptions).on('error', sass.logError))
.pipe(autoprefixer('last 2 versions'))
.pipe(sourcemaps.write('.'))
.pipe(gulp.dest(dst));
});
return merge(tasks);
}
function mainCSS() {
var dst = path.join(assetsDST + 'css/');
return gulp.src(globalCSS, { allowEmpty: true })
.pipe(sourcemaps.init())
.pipe(sass(sassOptions).on('error', sass.logError))
.pipe(autoprefixer('last 2 versions'))
.pipe(sourcemaps.write('.'))
.pipe(gulp.dest(dst));
}
function libraryJS() {
var dst = path.join(assetsDST + 'JS/lib');
return gulp.src(libJS).pipe(gulp.dest(dst));
}
function watch() {
gulp.watch([globalCSS,configCSS,themeCSS, componentCSS],mainCSS);
}
exports.mainCSS = mainCSS;
exports.mainJS = mainJS;
exports.libraryJS = libraryJS;
exports.css = css;
exports.javascript = javascript;
exports.watch = watch;
const build = gulp.series(watch);
gulp.task('default', build);
Edit
Attempt using gulp-sass-glob:
function css() {
gulp.task('styles', function () {
var src = path(components);
return gulp
.src(src, '/**/*.scss')
.pipe(sassGlob())
.pipe(sourcemaps.init())
.pipe(sass(sassOptions).on('error', sass.logError))
.pipe(autoprefixer('last 2 versions'))
.pipe(sourcemaps.write('.'))
.pipe(sass())
.pipe(gulp.dest(assetsDST + 'css'));
});
}
Re-ran gulp watch (no errors). Made a change and saved hero.scss. Then went into style.css to find css that has been compiled from hero.scss - nothing shows. scss not compiled into style.css
Edit 2
I have the following:
function css() {
var folders = getFolders(components);
var tasks = folders.map(function(folder) {
var src = path.join(components, folder);
var dst = path.join(assetsDST + 'css/');
return gulp.src(path.join(src, '**/*.scss'))
.pipe(sourcemaps.init())
.pipe(sass(sassOptions).on('error', sass.logError))
.pipe(autoprefixer('last 2 versions'))
.pipe(sourcemaps.write('.'))
.pipe(gulp.dest(dst));
});
return merge(tasks);
}
This is creating individual css files (rather than collating into style.css). I think this one is close, but unsure how to proceed.
Have you tried gulp-sass-glob?
https://www.npmjs.com/package/gulp-sass-glob
I am not able to get the sass code I write to compile into CSS when I use any of the following commands:
gulp watch
gulp scss-for-prod
gulp scripts-for-prod
The strange thing is though that fork picks up when I make a change
SOLVED: add a clean package.json file
This is the Gulp.js
// Defining requirements
var gulp = require('gulp');
var plumber = require('gulp-plumber');
var sass = require('gulp-sass');
var watch = require('gulp-watch');
var cssnano = require('gulp-cssnano');
var rename = require('gulp-rename');
var concat = require('gulp-concat');
var terser = require('gulp-terser');
//var uglify = require('gulp-uglify');
var merge2 = require('merge2');
var imagemin = require('gulp-imagemin');
var ignore = require('gulp-ignore');
var rimraf = require('gulp-rimraf');
var clone = require('gulp-clone');
var merge = require('gulp-merge');
var sourcemaps = require('gulp-sourcemaps');
var browserSync = require('browser-sync').create();
var del = require('del');
var cleanCSS = require('gulp-clean-css');
var gulpSequence = require('gulp-sequence');
var replace = require('gulp-replace');
var autoprefixer = require('gulp-autoprefixer');
//var babel = require('gulp-babel');
var webpack = require('webpack-stream');
//var haml = require('gulp-haml');
// Configuration file to keep your code DRY
var cfg = require('./gulpconfig.json');
var paths = cfg.paths;
// Run:
// gulp sass + cssnano + rename
// Prepare the min.css for production (with 2 pipes to be sure that "theme.css" == "theme.min.css")
gulp.task('scss-for-prod', function () {
var source = gulp.src(paths.sass + '/*.scss')
.pipe(plumber({
errorHandler: function (err) {
console.log(err);
this.emit('end');
}
}))
.pipe(sourcemaps.init({ loadMaps: true }))
.pipe(sass());
var pipeoutput = source.pipe(clone())
//.pipe(minifycss())
.pipe(cleanCSS({compatibility: 'ie8'}))
.pipe(rename({ suffix: '.min' }))
.pipe(gulp.dest(paths.css));
return pipeoutput;
});
// Run:
// gulp sourcemaps + sass + reload(browserSync)
// Prepare the child-theme.css for the development environment
gulp.task('scss-for-dev', function () {
gulp.src(paths.sass + '/*.scss')
.pipe(plumber({
errorHandler: function (err) {
console.log(err);
this.emit('end');
}
}))
.pipe(sourcemaps.init({ loadMaps: true }))
.pipe(sass())
.pipe(sourcemaps.write(undefined, { sourceRoot: null }))
.pipe(gulp.dest(paths.css));
});
gulp.task('watch-scss', ['browser-sync'], function () {
gulp.watch(paths.sass + '/**/*.scss', ['scss-for-dev']);
});
// Run:
// gulp sass
// Compiles SCSS files in CSS
gulp.task('sass', function () {
var stream = gulp.src(paths.sass + '/*.scss')
.pipe(plumber({
errorHandler: function (err) {
console.log(err);
this.emit('end');
}
}))
.pipe(sass({ errLogToConsole: true }))
.pipe(autoprefixer('last 2 versions'))
.pipe(gulp.dest(paths.css));
return stream;
});
// Run:
// gulp watch
// Starts watcher. Watcher runs gulp sass task on changes
gulp.task('watch', function () {
gulp.watch(paths.haml + '/**/*.haml', ['convert-haml']);
gulp.watch(paths.sass + '/**/*.scss', ['styles']);
gulp.watch([paths.dev + '/js/**/*.js', 'js/**/*.js', '!js/theme.js', '!js/theme.min.js'], ['scripts']);
//Inside the watch task.
gulp.watch(paths.imgsrc + '/**', ['imagemin-watch']);
//browserSync.reload();
});
/**
* Ensures the 'imagemin' task is complete before reloading browsers
* #verbose
*/
gulp.task('imagemin-watch', ['imagemin'], function (done) {
browserSync.reload();
done();
});
// Run:
// gulp imagemin
// Running image optimizing task
gulp.task('imagemin', function () {
gulp.src(paths.imgsrc + '/**')
.pipe(imagemin())
.pipe(gulp.dest(paths.img));
});
// Run:
// gulp cssnano
// Minifies CSS files
gulp.task('cssnano', function () {
return gulp.src(paths.css + '/theme.css')
.pipe(sourcemaps.init({ loadMaps: true }))
.pipe(plumber({
errorHandler: function (err) {
console.log(err);
this.emit('end');
}
}))
.pipe(rename({ suffix: '.min' }))
.pipe(cssnano({ discardComments: { removeAll: true } }))
.pipe(sourcemaps.write('./'))
.pipe(gulp.dest(paths.css));
});
gulp.task('minifycss', function () {
return gulp.src(paths.css + '/theme.css')
.pipe(sourcemaps.init({ loadMaps: true }))
.pipe(cleanCSS({ compatibility: '*' }))
.pipe(plumber({
errorHandler: function (err) {
console.log(err);
this.emit('end');
}
}))
.pipe(rename({ suffix: '.min' }))
.pipe(sourcemaps.write('./'))
.pipe(gulp.dest(paths.css));
});
gulp.task('cleancss', function () {
return gulp.src(paths.css + '/*.min.css', { read: false }) // Much faster
.pipe(ignore('theme.css'))
.pipe(rimraf());
});
//gulp.task( 'convert-haml', function( callback ) {
// gulp.src('./haml/**/*.haml')
// .pipe(haml({ext: '.php'}))
// .pipe(gulp.dest('./'));
//} );
gulp.task('styles', function (callback) {
//gulpSequence('sass', 'minifycss')(callback);
gulpSequence('sass', 'cleancss')(callback);
});
// Run:
// gulp browser-sync
// Starts browser-sync task for starting the server.
gulp.task('browser-sync', function () {
browserSync.init(cfg.browserSyncWatchFiles, cfg.browserSyncOptions);
});
// Run:
// gulp watch-bs
// Starts watcher with browser-sync. Browser-sync reloads page automatically on your browser
gulp.task('watch-bs', ['browser-sync', 'watch', 'scripts'], function () {
});
// gulp scripts.
// Uglifies and concat all JS files into one
gulp.task('scripts', function () {
var scripts = [
//paths.dev + '/js/paginate.js',
//paths.dev + "/js/Select2.js",
paths.dev + "/js/slick/slick.js",
paths.dev + '/js/main.js',
];
gulp.src(scripts)
//.pipe(babel())
.pipe(webpack({
mode: 'development'
}))
.pipe(concat('theme.js'))
.pipe(gulp.dest(paths.js));
});
gulp.task('scripts-for-prod', function () {
var scripts = [
//paths.dev + '/js/paginate.js',
//paths.dev + "/js/Select2.js",
paths.dev + "/js/slick/slick.js",
paths.dev + '/js/main.js',
];
gulp.src(scripts)
//.pipe(babel())
.pipe(webpack({
mode: 'development'
}))
.pipe(concat('theme.min.js'))
//.pipe( uglify().on('error', function(e){
// console.log(e);
// }) )
/*.pipe(terser().on('error', function(e){
console.log(e);
}) )*/
.pipe(gulp.dest(paths.js));
});
// Deleting any file inside the /src folder
gulp.task('clean-source', function () {
return del(['src/**/*']);
});
// Run:
// gulp copy-assets.
// Copy all needed dependency assets files from bower_component assets to themes /js, /scss and /fonts folder. Run this task after bower install or bower update
////////////////// All Bootstrap SASS Assets /////////////////////////
gulp.task('copy-assets', function () {
// Tachyons CSS
//var stream = gulp.src( paths.node + 'tachyons-sass/tachyons.scss' )
//.pipe( gulp.dest( paths.dev + '/sass/tachyons-sass' ) );
var stream = gulp.src(paths.node + 'normalize-scss/sass/**/*')
.pipe(gulp.dest(paths.dev + '/sass/normalize-scss'));
//gulp.src( paths.node + 'tachyons-sass/scss/*.scss' )
//.pipe( gulp.dest( paths.dev + '/sass/tachyons-sass/scss' ) );
// Flexbox Grid
//gulp.src( paths.node + 'flexboxgrid-sass/flexboxgrid.scss' )
//.pipe( gulp.dest( paths.dev + '/sass/flexboxgrid-sass' ) );
//gulp.src( paths.node + 'sass-flex-mixin/**/*' )
//.pipe( gulp.dest( paths.dev + '/sass/sass-flex-mixin' ) );
gulp.src(paths.node + '#drewbot/sass-flexbox-grid/public/sass-flexbox/scss/**/*')
.pipe(gulp.dest(paths.dev + '/sass/sass-flexbox-grid'));
////////////////// All Bootstrap 4 Assets /////////////////////////
// Copy all JS files
//var stream = gulp.src( paths.node + 'bootstrap/dist/js/**/*.js' )
// .pipe( gulp.dest( paths.dev + '/js/bootstrap4' ) );
// Copy all Bootstrap SCSS files
//gulp.src( paths.node + 'bootstrap/scss/**/*.scss' )
// .pipe( gulp.dest( paths.dev + '/sass/bootstrap4' ) );
////////////////// End Bootstrap 4 Assets /////////////////////////
gulp
.src(paths.node + "slick-carousel-latest/slick/slick.js")
.pipe(gulp.dest(paths.dev + "/js/utils/slick"));
gulp
.src(paths.node + "slick-carousel-latest/slick/*")
.pipe(gulp.dest(paths.dev + "/sass/slick"));
gulp
.src(paths.node + "slick-carousel-latest/slick/fonts/*")
.pipe(gulp.dest(paths.css + "/fonts"));
//gulp.src(paths.node + 'vanillajs-datepicker/dist/**/*')
// .pipe(gulp.dest(paths.dev + '/js/utils/vanillajs-datepicker'));
gulp.src(paths.node + 'js-datepicker/src/**/*')
.pipe(gulp.dest(paths.dev + '/js/utils/js-datepicker'));
gulp.src(paths.node + 'js-datepicker/dist/**/*')
.pipe(gulp.dest(paths.dev + '/js/utils/js-datepicker'));
// Copy Sass Mq
gulp.src(paths.node + 'sass-mq/_mq.scss')
.pipe(gulp.dest(paths.dev + '/sass/sass-mq'));
// Copy all Font Awesome Fonts
gulp.src(paths.node + '#fortawesome/fontawesome-free/**/*.{ttf,woff,woff2,eot,svg}')
.pipe(gulp.dest('./fonts/fortawesome'));
// Copy all Font Awesome SCSS files
gulp.src(paths.node + '#fortawesome/fontawesome-free/scss/**/*.scss')
.pipe(gulp.dest(paths.dev + '/sass/fortawesome'));
return stream;
});
// Deleting the files distributed by the copy-assets task
gulp.task('clean-vendor-assets', function () {
return del([
paths.dev + '/js/vanillajs-datepicker/**',
paths.dev + '/sass/sass-flex-mixin/**',
paths.dev + '/sass/flexboxgrid-sass/**',
'./fonts/*wesome*.{ttf,woff,woff2,eot,svg}',
paths.dev + '/sass/fortawesome/**',
paths.dev + "/js/utils/slick/**",
paths.dev + "/sass/slick/**",
paths.fonts + "/slick/**",
paths.vendor !== '' ? (paths.js + paths.vendor + '/**') : ''
]);
});
// Run
// gulp dist
// Copies the files to the /dist folder for distribution as simple theme
gulp.task('dist', ['clean-dist'], function () {
return gulp.src(['**/*', '!' + paths.bower, '!' + paths.bower + '/**', '!' + paths.node, '!' + paths.node + '/**', '!' + paths.dev, '!' + paths.dev + '/**', '!' + paths.dist, '!' + paths.dist + '/**', '!' + paths.distprod, '!' + paths.distprod + '/**', '!' + paths.sass, '!' + paths.sass + '/**', '!readme.txt', '!readme.md', '!package.json', '!package-lock.json', '!gulpfile.js', '!gulpconfig.json', '!CHANGELOG.md', '!.travis.yml', '!jshintignore', '!codesniffer.ruleset.xml', '*'], { 'buffer': false })
//.pipe( replace( '/js/jquery.slim.min.js', '/js' + paths.vendor + '/jquery.slim.min.js', { 'skipBinary': true } ) )
.pipe(replace('/js/main.js', '/js' + paths.vendor + '/main.js', { 'skipBinary': true }))
.pipe(gulp.dest(paths.dist));
});
// Deleting any file inside the /dist folder
gulp.task('clean-dist', function () {
return del([paths.dist + '/**']);
});
// Run
// gulp dist-product
// Copies the files to the /dist-prod folder for distribution as theme with all assets
gulp.task('dist-product', ['clean-dist-product'], function () {
return gulp.src(['**/*', '!' + paths.bower, '!' + paths.bower + '/**', '!' + paths.node, '!' + paths.node + '/**', '!' + paths.dist, '!' + paths.dist + '/**', '!' + paths.distprod, '!' + paths.distprod + '/**', '*'])
.pipe(gulp.dest(paths.distprod));
});
// Deleting any file inside the /dist-product folder
gulp.task('clean-dist-product', function () {
return del([paths.distprod + '/**']);
});
I'm trying to get Browser Sync and Live Reload working in my gulp file but it doesn't want to run correctly.
I want to be able to detect any file change in 'src' and my 'templates' folder which are both contained within the root. The gulp file is detecting the changes in the src folder fine but the template files are not getting reloaded in the browser on save.
Note:
I have the live reload chrome browser extension.
I'm not compiling the templates folder but am compiling everything in src to the web destination folder.
The Gulp File:
// -------------------- Configuration Settings --------------------
var config = {};
//basics
config.siteName = 'Franklin';
config.proxyDomain = 'https://franklin.test';
//source directory
config.src = 'src/';
//twig templates
config.templates = 'templates';
//destinations
config.dest = 'web/';
config.destJS = config.dest + 'assets/js';
config.destCSS = config.dest + 'assets/css';
config.destFonts = config.dest + 'assets/fonts';
config.destPWA = config.dest;
//globs
config.globs = {
templates : config.templates + '/**/*.twig',
scss : config.src + 'scss/**/*.scss',
js : {
individual : config.src + 'js/individual/**/*.js',
combined : [
config.src + 'js/combined/libs/*.js',
config.src + 'js/combined/plugins/*.js',
config.src + 'js/combined/pluginSubs/*.js',
config.src + 'js/combined/site/*.js',
config.src + 'js/combined/site.js'
]
},
fonts : config.src + 'fonts/**/*',
pwa : config.src + 'pwa/**/*',
watched : [
config.templates + '/**/*.twig',
config.destJS + '/**/*.min.js',
config.destCSS + '/**/*.min.css',
config.destFonts + '/**/*',
config.destPWA + '/**/*'
]
};
//browser sync
config.browserSync = {
files: config.globs.watched,
proxy: config.proxyDomain
};
// -------------------- Require Statements --------------------
var gulp = require('gulp'),
autoprefixer = require('gulp-autoprefixer'),
concat = require('gulp-concat'),
livereload = require('gulp-livereload'),
browserSync = require('browser-sync').create(),
newer = require('gulp-newer'),
notify = require('gulp-notify'),
plumber = require('gulp-plumber'),
rename = require('gulp-rename'),
sass = require('gulp-sass'),
size = require('gulp-size'),
uglify = require('gulp-uglify'),
watch = require('gulp-watch'),
path = require('path'),
cssnano = require('gulp-cssnano'),
sourcemaps = require('gulp-sourcemaps'),
lazypipe = require('lazypipe'),
fs = require('fs');
// -------------------- Notification Icon Detection --------------------
/**
* Checks to see if a file exists.
*
* #param filePath
* #returns {*}
*/
function fileExists(filePath)
{
try {
return fs.statSync(filePath).isFile();
} catch (err) {
return false;
}
}
var iconPath = path.join(__dirname, 'gulp.png');
var icon = fileExists( iconPath ) ? iconPath : null;
// -------------------- Plumber Error Handler --------------------
var plumberErrorHandler = function(err) {
console.log( 'plumber error! "' + err.message + '"' );
notify.onError({
title: config.siteName,
message: "Error: <%= err.message %>",
sound: 'Pop'
});
this.emit('end');
};
// -------------------- Processors --------------------
//individual scripts (not combined)
var jsIndividualScripts = lazypipe()
.pipe(plumber, {errorHandler: plumberErrorHandler})
.pipe(newer, { dest: config.destJS, ext: '.min.js' })
.pipe(gulp.dest, config.destJS)
.pipe(size, {showFiles: true})
.pipe(uglify)
.pipe(rename, { suffix: '.min' })
.pipe(gulp.dest, config.destJS)
.pipe(size, {showFiles: true});
//combined scripts
var jsCombinedScripts = lazypipe()
.pipe(plumber, {errorHandler: plumberErrorHandler})
.pipe(newer, config.dest + 'js/scripts.min.js')
.pipe(concat, 'scripts.js')
.pipe(gulp.dest, config.destJS)
.pipe(size, {showFiles: true})
.pipe(uglify)
.pipe(rename, { suffix: '.min' })
.pipe(gulp.dest, config.destJS)
.pipe(size, {showFiles: true});
//scss compiling
var scssProcessing = lazypipe()
.pipe(plumber, {errorHandler: plumberErrorHandler})
.pipe(sass, {outputStyle: ':compact'})
.pipe(autoprefixer, 'last 2 version')
.pipe(gulp.dest, config.destCSS)
.pipe(size, {showFiles: true})
.pipe(rename, { suffix: '.min' })
.pipe(sourcemaps.init)
.pipe(cssnano)
.pipe(sourcemaps.write, '.')
.pipe(gulp.dest, config.destCSS)
.pipe(size, {showFiles: true});
//fonts compiling
var fontsProcessing = lazypipe()
.pipe(plumber, {errorHandler: plumberErrorHandler})
.pipe(gulp.dest, config.destFonts);
//pwa compiling
var pwaProcessing = lazypipe()
.pipe(plumber, { errorHandler: plumberErrorHandler })
.pipe(gulp.dest, config.destPWA);
// -------------------- Tasks --------------------
//styles task
gulp.task('styles', function() {
if ( browserSync.active ) {
return gulp.src(config.globs.scss)
.pipe(scssProcessing())
.pipe(browserSync.reload({stream:true}));
}
return gulp.src(config.globs.scss).pipe(scssProcessing());
});
//template task
gulp.task('templates', function() {
if ( browserSync.active ) {
return gulp.src(config.globs.templates)
.pipe(browserSync.reload({stream:true}));
}
});
//scripts individual task
gulp.task('scripts-individual', function() {
return gulp.src(config.globs.js.individual).pipe(jsIndividualScripts());
});
//scripts combined task
gulp.task('scripts-combined', function() {
return gulp.src(config.globs.js.combined).pipe(jsCombinedScripts());
});
//fonts task
gulp.task('fonts', function() {
return gulp.src(config.globs.fonts).pipe(fontsProcessing());
});
//pwa task
gulp.task('pwa', function () {
return gulp.src(config.globs.pwa).pipe(pwaProcessing());
});
//watch task
gulp.task('live', function() {
//watch all .scss files
gulp.watch(config.globs.scss, ['styles']);
//watch all twig template files
gulp.watch(config.globs.templates, ['templates']);
//watch each individual .js file
watch(config.globs.js.individual).pipe(jsIndividualScripts());
//watch all combined .js files
gulp.watch(config.globs.js.combined, ['scripts-combined']);
});
//default task - one time styles and scripts
gulp.task('default', ['styles', 'templates', 'scripts-individual', 'scripts-combined', 'fonts', 'pwa']);
//start browser-sync server
gulp.task('serve-bs', ['live'], function() {
browserSync.init(config.browserSync)
});
//start livereload
gulp.task('watch', ['live'], function() {
livereload.listen();
//watch for changes on transpired templates, css, and js files
gulp.watch(config.globs.watched, function(event) {
gulp.src(event.path)
.pipe(plumber({errorHandler: plumberErrorHandler}))
.pipe(livereload())
.pipe(notify({
title: config.siteName,
message: event.type + ': ' + event.path.replace(__dirname, '').replace(/\\/g, '/') + ' was reloaded',
sound: 'Pop',
icon: icon
})
);
});
});
I'm very new to gulp and seeing as how complex the Roots's Sage gulpfile is, I'm so lost as to which block of code I should put in my code in.
The usage examples for both packages is as follows:
CSS Shrink
var gulp = require('gulp');
var cssshrink = require('gulp-cssshrink');
gulp.task('default', function() {
gulp.src('css/**/*.css')
.pipe(cssshrink())
.pipe(gulp.dest('dist/css/'));
});
Combine Media Queries
var cmq = require('gulp-combine-media-queries');
gulp.task('cmq', function () {
gulp.src('src/**/*.css')
.pipe(cmq({
log: true
}))
.pipe(gulp.dest('dist'));
});
Manifest.json file:
{
"dependencies": {
"main.js": {
"files": [
"scripts/main.js"
],
"main": true
},
"main.css": {
"files": [
"styles/main.scss"
],
"main": true
},
"customizer.js": {
"files": [
"scripts/customizer.js"
]
},
"jquery.js": {
"bower": [
"jquery"
]
}
},
"config": {
"devUrl": "http://yaharga/"
}
}
I tried to put it in the Styles task at the gulpfile.js, but nothing happened:
// ## Globals
var argv = require('minimist')(process.argv.slice(2));
var autoprefixer = require('gulp-autoprefixer');
var browserSync = require('browser-sync').create();
var changed = require('gulp-changed');
var concat = require('gulp-concat');
var flatten = require('gulp-flatten');
var gulp = require('gulp');
var gulpif = require('gulp-if');
var imagemin = require('gulp-imagemin');
var jshint = require('gulp-jshint');
var lazypipe = require('lazypipe');
var less = require('gulp-less');
var merge = require('merge-stream');
var cssNano = require('gulp-cssnano');
var plumber = require('gulp-plumber');
var rev = require('gulp-rev');
var runSequence = require('run-sequence');
var sass = require('gulp-sass');
var sourcemaps = require('gulp-sourcemaps');
var uglify = require('gulp-uglify');
var cmq = require('gulp-combine-media-queries');
var cssshrink = require('gulp-cssshrink');
// See https://github.com/austinpray/asset-builder
var manifest = require('asset-builder')('./assets/manifest.json');
// `path` - Paths to base asset directories. With trailing slashes.
// - `path.source` - Path to the source files. Default: `assets/`
// - `path.dist` - Path to the build directory. Default: `dist/`
var path = manifest.paths;
// `config` - Store arbitrary configuration values here.
var config = manifest.config || {};
// `globs` - These ultimately end up in their respective `gulp.src`.
// - `globs.js` - Array of asset-builder JS dependency objects. Example:
// ```
// {type: 'js', name: 'main.js', globs: []}
// ```
// - `globs.css` - Array of asset-builder CSS dependency objects. Example:
// ```
// {type: 'css', name: 'main.css', globs: []}
// ```
// - `globs.fonts` - Array of font path globs.
// - `globs.images` - Array of image path globs.
// - `globs.bower` - Array of all the main Bower files.
var globs = manifest.globs;
// `project` - paths to first-party assets.
// - `project.js` - Array of first-party JS assets.
// - `project.css` - Array of first-party CSS assets.
var project = manifest.getProjectGlobs();
// CLI options
var enabled = {
// Enable static asset revisioning when `--production`
rev: argv.production,
// Disable source maps when `--production`
maps: !argv.production,
// Fail styles task on error when `--production`
failStyleTask: argv.production,
// Fail due to JSHint warnings only when `--production`
failJSHint: argv.production,
// Strip debug statments from javascript when `--production`
stripJSDebug: argv.production
};
// Path to the compiled assets manifest in the dist directory
var revManifest = path.dist + 'assets.json';
// ## Reusable Pipelines
// See https://github.com/OverZealous/lazypipe
// ### CSS processing pipeline
// Example
// ```
// gulp.src(cssFiles)
// .pipe(cssTasks('main.css')
// .pipe(gulp.dest(path.dist + 'styles'))
// ```
var cssTasks = function(filename) {
return lazypipe()
.pipe(function() {
return gulpif(!enabled.failStyleTask, plumber());
})
.pipe(function() {
return gulpif(enabled.maps, sourcemaps.init());
})
.pipe(function() {
return gulpif('*.less', less());
})
.pipe(function() {
return gulpif('*.scss', sass({
outputStyle: 'nested', // libsass doesn't support expanded yet
precision: 10,
includePaths: ['.'],
errLogToConsole: !enabled.failStyleTask
}));
})
.pipe(concat, filename)
.pipe(autoprefixer, {
browsers: [
'last 2 versions',
'android 4',
'opera 12'
]
})
.pipe(cssNano, {
safe: true
})
.pipe(function() {
return gulpif(enabled.rev, rev());
})
.pipe(function() {
return gulpif(enabled.maps, sourcemaps.write('.', {
sourceRoot: 'assets/styles/'
}));
})();
};
// ### JS processing pipeline
// Example
// ```
// gulp.src(jsFiles)
// .pipe(jsTasks('main.js')
// .pipe(gulp.dest(path.dist + 'scripts'))
// ```
var jsTasks = function(filename) {
return lazypipe()
.pipe(function() {
return gulpif(enabled.maps, sourcemaps.init());
})
.pipe(concat, filename)
.pipe(uglify, {
compress: {
'drop_debugger': enabled.stripJSDebug
}
})
.pipe(function() {
return gulpif(enabled.rev, rev());
})
.pipe(function() {
return gulpif(enabled.maps, sourcemaps.write('.', {
sourceRoot: 'assets/scripts/'
}));
})();
};
// ### Write to rev manifest
// If there are any revved files then write them to the rev manifest.
// See https://github.com/sindresorhus/gulp-rev
var writeToManifest = function(directory) {
return lazypipe()
.pipe(gulp.dest, path.dist + directory)
.pipe(browserSync.stream, {match: '**/*.{js,css}'})
.pipe(rev.manifest, revManifest, {
base: path.dist,
merge: true
})
.pipe(gulp.dest, path.dist)();
};
// ## Gulp tasks
// Run `gulp -T` for a task summary
// ### Styles
// `gulp styles` - Compiles, combines, and optimizes Bower CSS and project CSS.
// By default this task will only log a warning if a precompiler error is
// raised. If the `--production` flag is set: this task will fail outright.
gulp.task('styles', ['wiredep'], function() {
var merged = merge();
manifest.forEachDependency('css', function(dep) {
var cssTasksInstance = cssTasks(dep.name);
if (!enabled.failStyleTask) {
cssTasksInstance.on('error', function(err) {
console.error(err.message);
this.emit('end');
});
}
merged.add(gulp.src(dep.globs, {base: 'styles'})
.pipe(cssTasksInstance));
});
/************************* This is where I added it! *************************/
gulp.src(path.dist + 'styles/main.css')
.pipe(cssshrink())
.pipe(cmq())
.pipe(gulp.dest(path.dist + 'styles/main.css'));
return merged
.pipe(writeToManifest('styles'));
});
// ### Scripts
// `gulp scripts` - Runs JSHint then compiles, combines, and optimizes Bower JS
// and project JS.
gulp.task('scripts', ['jshint'], function() {
var merged = merge();
manifest.forEachDependency('js', function(dep) {
merged.add(
gulp.src(dep.globs, {base: 'scripts'})
.pipe(jsTasks(dep.name))
);
});
return merged
.pipe(writeToManifest('scripts'));
});
// ### Fonts
// `gulp fonts` - Grabs all the fonts and outputs them in a flattened directory
// structure. See: https://github.com/armed/gulp-flatten
gulp.task('fonts', function() {
return gulp.src(globs.fonts)
.pipe(flatten())
.pipe(gulp.dest(path.dist + 'fonts'))
.pipe(browserSync.stream());
});
// ### Images
// `gulp images` - Run lossless compression on all the images.
gulp.task('images', function() {
return gulp.src(globs.images)
.pipe(imagemin({
progressive: true,
interlaced: true,
svgoPlugins: [{removeUnknownsAndDefaults: false}, {cleanupIDs: false}]
}))
.pipe(gulp.dest(path.dist + 'images'))
.pipe(browserSync.stream());
});
// ### JSHint
// `gulp jshint` - Lints configuration JSON and project JS.
gulp.task('jshint', function() {
return gulp.src([
'bower.json', 'gulpfile.js'
].concat(project.js))
.pipe(jshint())
.pipe(jshint.reporter('jshint-stylish'))
.pipe(gulpif(enabled.failJSHint, jshint.reporter('fail')));
});
// ### Clean
// `gulp clean` - Deletes the build folder entirely.
gulp.task('clean', require('del').bind(null, [path.dist]));
// ### Watch
// `gulp watch` - Use BrowserSync to proxy your dev server and synchronize code
// changes across devices. Specify the hostname of your dev server at
// `manifest.config.devUrl`. When a modification is made to an asset, run the
// build step for that asset and inject the changes into the page.
// See: http://www.browsersync.io
gulp.task('watch', function() {
browserSync.init({
files: ['{lib,templates}/**/*.php', '*.php'],
proxy: config.devUrl,
snippetOptions: {
whitelist: ['/wp-admin/admin-ajax.php'],
blacklist: ['/wp-admin/**']
}
});
gulp.watch([path.source + 'styles/**/*'], ['styles']);
gulp.watch([path.source + 'scripts/**/*'], ['jshint', 'scripts']);
gulp.watch([path.source + 'fonts/**/*'], ['fonts']);
gulp.watch([path.source + 'images/**/*'], ['images']);
gulp.watch(['bower.json', 'assets/manifest.json'], ['build']);
});
// ### Build
// `gulp build` - Run all the build tasks but don't clean up beforehand.
// Generally you should be running `gulp` instead of `gulp build`.
gulp.task('build', function(callback) {
runSequence('styles',
'scripts',
['fonts', 'images'],
callback);
});
// ### Wiredep
// `gulp wiredep` - Automatically inject Less and Sass Bower dependencies. See
// https://github.com/taptapship/wiredep
gulp.task('wiredep', function() {
var wiredep = require('wiredep').stream;
return gulp.src(project.css)
.pipe(wiredep())
.pipe(changed(path.source + 'styles', {
hasChanged: changed.compareSha1Digest
}))
.pipe(gulp.dest(path.source + 'styles'));
});
// ### Gulp
// `gulp` - Run a complete build. To compile for production run `gulp --production`.
gulp.task('default', ['clean'], function() {
gulp.start('build');
});
Ideally, I would need to capture the main.css code and implement the cmq and cssshrink to it just before it is finally exported into the distribution folder.
I followed the post on Roots Discourse to help me do it; will update with full answer once done.
I have a git repo with multiple plugins (1 main one and several that are only intended to work with the main one). I am using this approach for distribution, since bower doesn't provide a way to have more than one plugin per git repo.
So, I need to minify each plugin, create a sourcemap for each plugin, and drop each one into an individual distribution folder that corresponds to a git submodule, which by convention I am naming the same as the plugin to make it simple. I came up with the following Gulp script that does that all in one step, which is mostly based off of the answers I found here.
return gulp.src(['./jquery.dirtyforms.js', './helpers/*.js', './dialogs/*.js'], { base: './' })
.pipe(jshint())
.pipe(jshint.reporter(stylish))
.pipe(rename(function (path) {
var baseName = path.basename;
var dirName = path.dirname;
if (dirName == 'helpers' || dirName == 'dialogs') {
path.basename = 'jquery.dirtyforms.' + dirName + '.' + baseName;
console.log(path.basename);
}
path.dirname = path.basename;
}))
.pipe(gulp.dest(distributionFolder))
.pipe(sourcemaps.init())
.pipe(rename(function (path) {
var baseName = path.basename;
var dirName = path.dirname;
if (dirName == 'helpers' || dirName == 'dialogs') {
path.basename = 'jquery.dirtyforms.' + dirName + '.' + baseName;
console.log(path.basename);
}
path.dirname = path.basename;
path.extname = '.min.js';
}))
.pipe(uglify({
outSourceMap: true,
sourceRoot: '/'
}))
.pipe(gulp.dest(distributionFolder))
.pipe(sourcemaps.write('.', {
includeContent: true,
sourceRoot: '/'
}))
.pipe(gulp.dest(distributionFolder));
It does exactly what I want except for one thing. The sourcemap file that is generated for each plugin includes the subdirectory in the path. Since the final destination of the plugin won't include this path, this is invalid.
In the jquery.dirtyforms.min.js.map file:
{"version":3,"sources":["jquery.dirtyforms/jquery.dirtyforms.min.js"]...
Should be
{"version":3,"sources":["jquery.dirtyforms.min.js"]...
And in the jquery.dirtyforms.min.js file:
//# sourceMappingURL=../jquery.dirtyforms/jquery.dirtyforms.min.js.map
Should be
//# sourceMappingURL=jquery.dirtyforms.min.js.map
I dug through the source of gulp-sourcemaps to try to find an option to override the file name, but there doesn't seem to be one.
Two possible solutions I came up with for this are:
Do a replace in each of the files using a regular expression
Generate the files in the distributionFolderand then move them to the correct subfolder after they are generated
But both of these seem like hacks. It would be better if the stream created them correctly in the first place. Is there a way to make that so?
I ended up going with the second option I mentioned - that is, generate the minified files in the distributionFolder (now settings.dest) and then moved them with separate copy and delete tasks.
var gulp = require('gulp'),
uglify = require('gulp-uglify'),
jshint = require('gulp-jshint'),
stylish = require('jshint-stylish'),
rename = require('gulp-rename'),
sourcemaps = require('gulp-sourcemaps'),
del = require('del');
var settings = {
baseProject: 'jquery.dirtyforms',
src: ['./jquery.dirtyforms.js', './helpers/*.js', './dialogs/*.js'],
dest: './dist/'
};
// Moves the .js files to the distribution folders and creates a minified version and sourcemap
gulp.task('build', ['copy-minified'], function (cb) {
del([settings.dest + '*.js', settings.dest + '*.map'], cb);
});
gulp.task('copy-minified', ['uglify'], function () {
return gulp.src([settings.dest + '*.js', settings.dest + '*.map'], { base: './' })
.pipe(rename(function (path) {
console.log('moving: ' + path.basename)
path.dirname = path.basename.replace(/\.min(?:\.js)?/g, '');
}))
.pipe(gulp.dest(settings.dest));
});
gulp.task('uglify', ['clean', 'test'], function () {
return gulp.src(settings.src, { base: './' })
.pipe(rename(function (path) {
var baseName = path.basename;
var dirName = path.dirname;
if (dirName == 'helpers' || dirName == 'dialogs') {
path.basename = settings.baseProject + '.' + dirName + '.' + baseName;
}
path.dirname = path.basename;
}))
.pipe(gulp.dest(settings.dest))
.pipe(sourcemaps.init())
.pipe(rename(function (path) {
path.dirname = '';
path.extname = '.min.js';
}))
.pipe(uglify({
outSourceMap: true,
sourceRoot: '/'
}))
.pipe(gulp.dest(settings.dest))
.pipe(sourcemaps.write('.', {
includeContent: true,
sourceRoot: '/'
}))
.pipe(gulp.dest(settings.dest));
});
// Tests the source files (smoke test)
gulp.task('test', function () {
return gulp.src(settings.src, { base: './' })
.pipe(jshint())
.pipe(jshint.reporter(stylish));
});
Maybe there is a better alternative that isn't such a hack, but this worked for me.