How to append the main.css file through Roots's Sage gulpfile? - gulp

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.

Related

Tailwind CSS + Gulp + PurgeCSS Removing Some Classes Used In Code But Compiling Others

I'm currently attempting to use Tailwind CSS with gulp and purgeCSS in a WordPress project.
Everything runs as expected and the CSS files are compiling however certain classes don't make it into the compiled CSS no matter how they're used in the markup.
For example, the background color classes, i.e. "bg-white" are included in various theme files, but whenever the CSS recompiles, that class is purged. It was the same with the "margin-top" classes, but not any of the other margin classes.
Here is my gulp file:
var postcss = require('gulp-postcss');
var cssImport = require('postcss-import');
var gulp = require('gulp');
var cssvars = require('postcss-simple-vars');
var nested = require('postcss-nested');
var autoprefixer = require('autoprefixer');
var cssnano = require('cssnano');
var purgecss = require('gulp-purgecss')
var sass = require('gulp-sass');
var gcmq = require('gulp-group-css-media-queries');
var uglify = require('gulp-uglify-es').default;
var del = require('del');
var concat = require('gulp-concat');
var sourcemaps = require('gulp-sourcemaps');
var gutil = require('gulp-util');
var babel = require('gulp-babel');
// ============================================================================
// Main Tasks
// ============================================================================
// Default task is build
gulp.task('default', ['build']);
// Development task (watch alias)
gulp.task('dev', ['watch']);
// Build task
gulp.task('build', ['clean'], function() {
gulp.start(['styles', 'scripts']);
});
// Styles task
gulp.task('styles', function() {
return gulp.src([
'./assets/sass/*.scss'
])
.pipe(sass().on('error', sass.logError))
// .pipe(sourcemaps.init())
.pipe(postcss([
require('postcss-import'),
require('tailwindcss'),
autoprefixer(),
// cssnano()
], {
syntax: require('postcss-scss')
}))
.pipe(purgecss({
content: ['./*.php', './templates/*.php', './partials/*.php', './components/*.php'],
extractors: [
{
extractor: content => {
return content.match(/[A-Za-z0-9-_:\/]+/g) || []
// return content.match(/[^<>"'`\s]*[^<>"'`\s:]/g) || []
// return content.match(/[^<>"'`\s.()]*[^<>"'`\s.():]/g) || []
//return content.match(/[\w-/:]+(?<!:)/g) || [];
},
extensions: ['css', 'php', 'html']
}
],
safelist: {
standard: [/^[^-]*mt-*/, /^[^-]*bg-opacity-*/, /^[^-]*bg-white/]
}
}))
.pipe(gulp.dest('./assets/css/'))
});
// Scripts task
gulp.task('scripts', function() {
return gulp.src([
'./node_modules/mmenu-light/dist/mmenu-light.js',
'./node_modules/mmenu-light/dist/mmenu-light.polyfills.js',
'./assets/js/util-scripts.js',
'./assets/vendors/micromodal/micromodal.min.js',
'./assets/vendors/waypoints/lib/jquery.waypoints.js',
'./assets/js/core-js.js',
'./assets/js/theme-js.js'
])
// .pipe(sourcemaps.init())
.pipe(babel({
presets: ['#babel/env']
}))
.pipe(concat('theme-js.dist.js'))
.pipe(uglify())
// .pipe(sourcemaps.write())
.pipe(gulp.dest('./assets/dist/js/'))
});
// ============================================================================
// Build Tasks
// ============================================================================
/**
* Clean directories
*
* #since 0.1.0
*/
gulp.task('clean', function() {
del([
'./assets/css/*.css',
'!./assets/css/font-awesome.min.css',
'./assets/js/*.dist.js'
]);
});
// END BUILD
// ============================================================================
// Dev Tasks
// ============================================================================
/**
* Execute tasks when files are change and live reload web page, and servers
*
* #since 0.1.0
*/
gulp.task('watch', function() {
gulp.watch('./assets/sass/**/*.scss', ['styles']);
gulp.watch('./assets/js/*.js', ['scripts']);
// gulp.watch('./assets/images/*', ['images']);
gulp.watch("*.html", ['bs-reload']);
});
I also tried a variety of extractor regex matches, but none of them seem to work.
Oddly enough, when I add this into the theme configuration of my tailwind.config.js file the background class does compile
backgroundColor: {
'white': '#fff'
},
It seems the vast majority of classes are compiling though so unsure if it's my purgeCSS configuration or some other configuration that I'm missing in tailwind?

Setting up development stages using gulp / package.json

OK, so I am trying a new setup to give me a more efficient way of developing my sites.
At the moment I can only think of 3 stages, development, staging and build
As I'm using gulp, I have been typing gulp into Terminal to get started which then creates my build site.
Rather than run the Gulp command, I would like to use something like npm run development or npm run staging or npm run build
I understand by typing Gulp it automatically looks for the gulpfile.js file. How do I creat my own files?
I understand its something to do with scripts in the package.json file but I can't workout how.
Here's what I have so far:
{
"name": "Name",
"version": "1.0.0",
"description": "Description",
"main": "index.html",
"scripts": {
"test": "echo \"Error: no test specified\" && exit 1",
"development": "node builds/development.js",
"staging": "node builds/staging.js",
"build": "node builds/build.js"
},
"author": "Author name here",
"license": "ISC",
"devDependencies": {
"gulp": "^4.0.2",
},
"dependencies": {
}
}
Now when I type 'npm run staging' (being a exact copy of gulpfile.js) I would expect it to start just like if I typed Gulp
UPDATE:
Here is my gulpfile
// --------------------------------------------
// Gulp Loader
// --------------------------------------------
// Stop having to put gulp. infront of the following
const {
src,
dest,
task,
watch,
series,
parallel
} = require("gulp");
// --------------------------------------------
// Dependencies
// --------------------------------------------
// HTML plugins
var htmlmin = require("gulp-htmlmin");
// CSS / SASS plugins
var sass = require('gulp-sass');
var cleanCSS = require('gulp-clean-css');
// Images plugins
// let imagemin = require("gulp-imagemin");
var embedSvg = require("gulp-embed-svg");
// Browser plugins
var browserSync = require('browser-sync').create();
// Utility plugins
var plumber = require("gulp-plumber");
var rename = require("gulp-rename");
var cache = require('gulp-cache');
var autoprefixer = require('gulp-autoprefixer');
var sourcemaps = require('gulp-sourcemaps');
var shell = require('shelljs');
var uglify = require('gulp-uglify');
var del = require("del");
var inject = require('gulp-inject');
var shell = require('shelljs');
var noop = require('gulp-noop');
// --------------------------------------------
// Get Home Folder location
// --------------------------------------------
//Displays Users/User
const homedir = require("os").homedir();
// Needed for next part
var path = require("path");
//Displays Users/User/Documents/Clients/clientname/Projects (This is where I create my client folders)
var pathDir = require("path").resolve(__dirname, "../../");
var pathSrc = require("path").resolve(__dirname, "../../../");
//Display the name of the Clients folder name
var parentFld = path
.dirname(pathDir)
.split(path.sep)
.pop();
var parentDir = path.basename(path.dirname(pathDir));
parentDir = parentFld.replace(/[^\w]/g, "");
parentDir = parentFld.replace(/[^\w]/g, "").toLowerCase();
// BrowserSync
function server(done) {
browserSync.init({
proxy: "http://" + parentDir + ".test",
host: parentDir + ".test",
open: "external",
notify: false
});
done();
}
// function watcher() {
// Serve files from the root of this project
// browserSync.init({
// proxy: "https://" + parentdir + ".test",
// // host: parentdir + ".test",
// open: "external",
// https: {
// key: homedir + "/.config/valet/Certificates/" + parentdir + ".test.key",
// cert: homedir + "/.config/valet/Certificates/" + parentdir + ".test.crt"
// },
// browser: "Google Chrome Canary",
// notify: false
// });
// --------------------------------------------
// Paths
// --------------------------------------------
var paths = {
htaccess: {
src: './source/.htaccess',
dest: './development/.htaccess',
},
html: {
src: './source/*.html',
prt: './source/partials/*.html',
dest: './development/'
},
styles: {
src: 'source/styles/*.css',
dest: 'development/styles/'
},
scripts: {
src: 'source/scripts/*.js',
dest: 'development/scripts'
}
}
// --------------------------------------------
// Tasks
// --------------------------------------------
//Basic task with a log - SHOW $homedir
function home(cb) {
console.log(fontBld);
cb()
}
task('default', function () {
console.log('Hello World!');
});
//Basic task with a log
function ssg(cb) {
console.log(parentDir);
cb()
}
// CONSOLE LOG
function console_log(cb) {
console.log(parentDir);
cb()
}
function valet_link(cb) {
shell.mkdir(['development']);
shell.cd(['./development']);
if (shell.exec('sudo valet link' + ' ' + parentDir).code !== 0) {
shell.echo('Error: Git commit failed');
shell.exit(1);
}
shell.cd(['..']);
cb()
}
// CLEAN
function clean(cb) {
del.sync(paths.html.dest, {
force: true
});
cb()
}
// HT ACCESS
function htaccess() {
return src(paths.htaccess.src)
.pipe(dest(paths.htaccess.dest));
}
// HTML
function html() {
var injectPartials = src(paths.html.prt, {
relative: true
});
var injectStyles = src([paths.styles.src], {
relative: true
});
var injectScripts = src(paths.scripts.src, {
relative: true
});
return src(paths.html.src)
.pipe(inject(injectPartials, {
starttag: '<!-- inject:header:{{ext}} -->',
transform: function (filePath, file) {
// return file contents as string
return file.contents.toString('utf8')
}
}))
.pipe(inject(injectStyles, {
addRootSlash: false,
ignorePath: '/source/'
}))
.pipe(inject(injectScripts, {
addRootSlash: false,
ignorePath: '/source/'
}))
.pipe(
embedSvg({
root: "./source/images/",
selectors: ".inline-svg"
})
)
.pipe(dest(paths.html.dest));
}
// CSS
function css() {
return src(paths.styles.src)
.pipe(sass({
outputStyle: 'compressed'
}))
.pipe(plumber())
.pipe(dest(paths.styles.dest))
}
// JS
function js() {
return src(paths.scripts.src)
.pipe(
rename({
basename: "main",
suffix: ".min"
})
)
.pipe(plumber())
.pipe(uglify())
.pipe(dest(paths.scripts.dest));
}
// IMAGES
function img(done) {
src(imageSrc + "*")
.pipe(imagemin())
.pipe(dest(imageDest));
done();
}
// FONTS
function fonts(done) {
src(fontSrc + "*").pipe(dest(fontDest));
done();
}
function clearCache(done) {
cache.clearAll();
done();
}
// --------------------------------------------
// Watch
// --------------------------------------------
function watcher() {
watch(paths.styles.src).on('change', series(css, browserSync.reload));
watch(paths.scripts.src).on('change', series(js, browserSync.reload));
watch(paths.htaccess.src).on('change', series(htaccess, browserSync.reload));
watch(paths.html.src).on('change', series(html, browserSync.reload));
}
// --------------------------------------------
// Compile
// --------------------------------------------
exports.test = series(clean, html)
exports.log = console_log
exports.valet = valet_link
// --------------------------------------------
// Build
// --------------------------------------------
// CONSOLE LOG
function build_log(cb) {
console.log("Please either use 'npm run production' or 'npm run development'");
cb()
}
var compile = series(clean, valet_link, series(html, css, js));
task('default', series(compile, parallel(server, watcher)));
You dont need to create multiple gulp files, you can simply have one gulp.js file and simply call your gulp file in you package.json the way you are already doing like so:
"scripts": {
"gulp": "gulp",
"test": "echo \"Error: no test specified\" && exit 1"
},
Than, on your gulp file you just create your exports like so:
exports.development = function devFunction(){ ... };
exports.staging = function stagingFunction(){ ... };
exports.build = function buildFunction(){ ... };
You would than run each task, you would call "gulp task" like so:
gulp development

gulp-file-include and BrowserSync Doesn't Reflect the Changes to Browser

I am trying to use gulp-file-include for include some common sections like header or footer from /src/includes folder into any .html pages in a project tree along with BrowserSync to refresh changes.
When I use gulp command from command line it's compiling all files into /dist folder without problems (I hope). But after, if I change anything from /src/index.html it doesn't reflect changes to browser or write changes into /dist/index.html.
I can't figure out exactly where the problem is. You can see the project from this Git repo and here is my gulpfile.js content:
var gulp = require('gulp');
var autoprefixer = require('gulp-autoprefixer');
var plumber = require('gulp-plumber');
var gutil = require('gulp-util');
var concat = require('gulp-concat');
var cleanCSS = require('gulp-clean-css');
var rename = require("gulp-rename");
var sass = require('gulp-sass');
var uglify = require('gulp-uglify');
var browserSync = require('browser-sync').create();
var sourcemaps = require("gulp-sourcemaps");
var fileinclude = require("gulp-file-include");
// File Paths
var CSS_PATH = { src: "./src/sass/*.scss", dist: "./dist/css/"};
var JS_PATH = { src: "./src/js/*.js", dist: "./dist/js/"};
var HTML_PATH = { src: "./src/*.html", dist: "./dist/html/*.html"};
var INCLUDES_PATH = "./src/includes/**/*.html";
var JQUERY_PATH = "node_modules/jquery/dist/jquery.min.js";
// Error Handling
var gulp_src = gulp.src;
gulp.src = function() {
return gulp_src.apply(gulp, arguments)
.pipe(plumber(function(error) {
// Output an error message
gutil.log(gutil.colors.red('Error (' + error.plugin + '): ' + error.message));
// emit the end event, to properly end the task
this.emit('end');
})
);
};
// Styles
gulp.task('styles', function() {
return gulp.src(CSS_PATH["src"])
.pipe(sass())
.pipe(autoprefixer('last 2 versions'))
.pipe(sourcemaps.init())
.pipe(gulp.dest(CSS_PATH["dist"]))
.pipe(cleanCSS())
.pipe(sourcemaps.write())
.pipe(concat("main.css", {newLine: ""}))
.pipe(gulp.dest(CSS_PATH["dist"]))
.pipe(browserSync.reload({ stream: true }))
});
// Scripts
gulp.task('scripts', function() {
return gulp.src([JS_PATH["src"], JQUERY_PATH])
.pipe(uglify())
.pipe(concat('main.min.js'))
.pipe(gulp.dest(JS_PATH["dist"]));
});
// File Include
gulp.task('fileinclude', function() {
return gulp.src(HTML_PATH["src"])
.pipe(fileinclude({
prefix: '##',
basepath: 'src/includes'
}))
.pipe(gulp.dest('dist'));
});
// BrowserSync
gulp.task('browserSync', function() {
browserSync.init({
server: {
baseDir: 'dist/'
},
open: false,
browser: "Google Chrome",
notify: true,
notify: {
styles: {
top: 'auto',
bottom: '0',
borderRadius: '4px 0 0 0',
opacity: .9
}
},
snippetOptions: {
rule: {
match: /<\/body>/i,
fn: function (snippet, match) {
return snippet + match;
}
}
}
})
})
// Watch task
gulp.task('watch', ['fileinclude', 'browserSync'], function() {
gulp.watch(CSS_PATH["src"], ['styles']);
gulp.watch(JS_PATH["src"], ['scripts']);
gulp.watch(INCLUDES_PATH, ['fileinclude']);
gulp.watch([HTML_PATH["src"], HTML_PATH["src"]], browserSync.reload);
});
gulp.task('default', ['fileinclude', 'styles', 'scripts', 'browserSync', 'watch' ]);
I seem to have it working. I added the following to the end of the 'scripts' and 'fileinclude' tasks:
.pipe(browserSync.reload({ stream: true }))
// File Include
gulp.task('fileinclude', function() {
return gulp.src(HTML_PATH.src)
.pipe(fileinclude({
prefix: '##',
basepath: 'src/includes'
}))
.pipe(gulp.dest('dist'))
.pipe(browserSync.reload({ stream: true }))
});
// Scripts
gulp.task('scripts', function() {
// return gulp.src([JS_PATH["src"], JQUERY_PATH])
return gulp.src(JS_PATH.src)
.pipe(uglify())
.pipe(concat('main.min.js'))
.pipe(gulp.dest(JS_PATH.dist))
.pipe(browserSync.reload({ stream: true }))
});
so that the browser is reloaded after any changes to those two groups. I changed the 'watch' task to:
// Watch task
// gulp.task('watch', ['fileinclude', 'browserSync'], function() {
// 'browserSync' is already running from 'default' task so remove it from above
// 'fileinclude' is called below only where it is needed, not for changes to js/scss files
gulp.task('watch', function() {
gulp.watch(CSS_PATH.src, ['styles']);
gulp.watch(JS_PATH.src, ['scripts']);
gulp.watch(INCLUDES_PATH, ['fileinclude']);
// gulp.watch([HTML_PATH["src"], HTML_PATH["src"]], browserSync.reload);
// the above looks for changes to the source and immediately reloads,
// before any changes are made to the dist/html
// Watch for changes in the html src and run 'fileinclude'
// browserSync reload moved to end of 'fileinclude'
gulp.watch([HTML_PATH.src], ['fileinclude']);
});
Edit: to handle the subsequent question about gulp failing to watch new files, I have made some changes to my original answer. But you should really be using gulp4.0 now IMO. Gulp3.9.x relied on a library that was problematic in watching for new, deleted or renamed files.
You will need two more plugins:
var watch = require("gulp-watch");
var runSequence = require("run-sequence");
The gulp-watch plugin is better at watching for new, etc. files, but doesn't take 'tasks' as arguments but instead it takes functions as arguments so that is why I used run-sequence. [You could rewrite your tasks as regular functions - but then you might as well shift to gulp4.0].
Then use this 'watch' task:
gulp.task('watch', function () {
watch(CSS_PATH.src, function () {
runSequence('styles');
});
watch(JS_PATH.src, function () {
runSequence('scripts');
});
watch(INCLUDES_PATH, function () {
runSequence('fileinclude');
});
watch([HTML_PATH.src], function () {
runSequence('fileinclude');
});
});

gulp browserify does not exit

Following is the code I inherited for gulp and browserify
'use strict';
var gulp = require('gulp'),
browserify = require('browserify'),
glob = require('glob'),
path = require('path'),
source = require('vinyl-source-stream'),
notifier = require('node-notifier'),
_ = require('underscore'),
watchify = require('watchify'),
jshint = require('gulp-jshint'),
chalk = require('chalk'),
del = require('del'),
webserver = require('gulp-webserver'),
cleanCSS = require('gulp-clean-css'),
babelify = require("babelify"),
jasmine = require('gulp-jasmine');
var browserifyables = './web-app/**/*-browserify.js';
function logError(error){
/* jshint validthis: true */
notifier.notify({
title: 'Browserify compilation error',
message: error.toString()
});
console.error(chalk.red(error.toString()));
this.emit('end');
}
function bundleShare(b, config) {
b.bundle()
.on('error', logError)
.pipe(source(config.destFilename))
.pipe(gulp.dest(config.destDir));
}
function browserifyShare(config, watch) {
var browserifyConfig = {
cache: {},
packageCache: {},
fullPaths: true,
insertGlobals: true
};
if(process.env.NODE_ENV !== 'production'){
browserifyConfig.debug = true;
}
var b = browserify(browserifyConfig);
b.transform('browserify-css', {});
b.transform(babelify, {presets: ["es2015"]});
// Need to fix dollar sign getting effed in angular when it gets minified before we can enable
if(process.env.NODE_ENV === 'production'){
b.transform('uglifyify', {global: true});
}
if(watch) {
// if watch is enable, wrap this bundle inside watchify
b = watchify(b);
b.on('update', function(ids) {
ids.forEach(function(id){
console.log(chalk.green(id + ' finished compiling'));
});
bundleShare(b, config);
});
b.on('log', function(message){
console.log(chalk.magenta(message));
});
}
// source to watch
b.add(config.sourceFile);
bundleShare(b, config);
}
gulp.task('minify-css', function() {
var minifyConfig = {compatibility: 'ie8'};
if(process.env.NODE_ENV !== 'production'){
minifyConfig.debug = true;
}
return gulp.src('./web-app/css/*/*.css')
.pipe(cleanCSS(minifyConfig))
.pipe(gulp.dest('./web-app/css'))
;
});
gulp.task('browserify', ['minify-css'], function(){
glob(browserifyables, {}, function(err, files){
_.each(files, function(file){
browserifyShare({
sourceFile: file,
destDir: path.dirname(file),
destFilename: path.basename(file).replace('-browserify', '')
});
});
});
});
I run the gulp task using
NODE_ENV='production' gulp browserify
The gulp tasks complete but does not terminate. The following is the output
[22:40:57] Using gulpfile ~/some/dir/Gulpfile.js
[22:40:57] Starting 'minify-css'...
[22:40:58] Finished 'minify-css' after 565 ms
[22:40:58] Starting 'browserify'...
[22:40:58] Finished 'browserify' after 2.12 ms
This slows down my build on jenkins considerably.
However if i comment out this line:
b.add(config.sourceFile);
The tasks exit but then it does not work ( for obvious reasons ).
So not sure what I am missing here. I need to figure out what prevents the task from exiting.

Gulp not watching files with gulp-watch plugin

I'm trying to rebuild only files that change in my gulpfile.js by using this recipe via the gulp-watch plugin. The problem is when I run my default task gulp, it doesn't watch the files at all after saving any of the files I want it to watch. What am I doing wrong here in my gulpfile.js? Thanks in advance.
/* ----------------------------------------------------- */
/* Gulpfile.js
/* ----------------------------------------------------- */
'use strict';
// Setup modules/Gulp plugins
var gulp = require('gulp'),
del = require('del'),
runSequence = require('run-sequence'),
less = require('gulp-less'),
// minifyCSS = require('gulp-minify-css'),
fileinclude = require('gulp-file-include'),
order = require('gulp-order'),
concat = require('gulp-concat'),
uglify = require('gulp-uglify'),
sourcemaps = require('gulp-sourcemaps'),
imagemin = require('gulp-imagemin'),
pngquant = require('imagemin-pngquant'),
plumber = require('gulp-plumber'),
watch = require('gulp-watch'),
// browserify = require('browserify'),
// sourceStream = require('vinyl-source-stream'),
connect = require('gulp-connect');
// Configure file paths
var path = {
DEST: 'dist/',
SRC: 'src/',
INCLUDES: 'include/',
LESS_SRC: 'src/frontend/less/',
LESS_MANIFEST: 'src/frontend/less/all.less',
CSS_DEST: 'dist/frontend/css/',
JS_SRC: 'src/frontend/js/',
JS_MINIFIED_OUT: 'all.js',
JS_DEST: 'dist/frontend/js',
IMG_SRC: 'src/frontend/img/',
IMG_DEST: 'dist/frontend/img/',
};
// Clean out build folder each time Gulp runs
gulp.task('clean', function (cb) {
del([
path.DEST
], cb);
});
// Compile LESS
gulp.task('less', function(){
return gulp.src(path.LESS_MANIFEST)
.pipe(watch(path.LESS_MANIFEST))
.pipe(plumber({
handleError: function (err) {
console.log(err);
this.emit('end');
}
}))
.pipe(sourcemaps.init())
.pipe(less())
.pipe(sourcemaps.write('./'))
.pipe(gulp.dest(path.CSS_DEST))
.pipe(connect.reload());
});
// Allow HTML files to be included
gulp.task('html', function() {
return gulp.src([path.SRC + '*.html'])
.pipe(watch(path.SRC + '*.html'))
.pipe(plumber({
handleError: function (err) {
console.log(err);
this.emit('end');
}
}))
.pipe(fileinclude({
prefix: '##',
basepath: path.INCLUDES
}))
.pipe(gulp.dest(path.DEST))
.pipe(connect.reload());
});
// Concatenate and minify JavaScript
gulp.task('js', function() {
return gulp.src(path.JS_SRC + '**/*.js')
.pipe(watch(path.JS_SRC + '**/*.js'))
.pipe(order([
path.JS_SRC + 'framework/*.js',
path.JS_SRC + 'vendor/*.js',
path.JS_SRC + 'client/*.js'
], {base: '.'} ))
.pipe(concat(path.JS_MINIFIED_OUT))
.pipe(uglify())
.pipe(gulp.dest(path.JS_DEST))
.pipe(connect.reload());
});
// Minify images
gulp.task('imagemin', function () {
return gulp.src(path.IMG_SRC + '**/*')
.pipe(imagemin({
progressive: true,
use: [pngquant()]
}))
.pipe(gulp.dest(path.IMG_DEST));
});
// Copy folders
gulp.task('copy', function() {
gulp.src(path.SRC + 'extjs/**/*')
.pipe(gulp.dest(path.DEST + 'extjs/'));
// Copy all Bower components to build folder
gulp.src('bower_components/**/*')
.pipe(gulp.dest('dist/bower_components/'));
});
// Connect to a server and livereload pages
gulp.task('connect', function() {
connect.server({
root: path.DEST,
livereload: true
});
});
// Organize build tasks into one task
gulp.task('build', ['less', 'html', 'js', 'imagemin', 'copy']);
// Organize server tasks into one task
gulp.task('server', ['connect']);
// Default task
gulp.task('default', function(cb) {
// Clean out dist/ folder before everything else
runSequence('clean', ['build', 'server'],
cb);
});
Try and remove the watch from your build tasks, and have separate tasks that handle the watching. Something like:
gulp.task("watch-less", function() {
watch(path.LESS_MANIFEST, function () {
gulp.start("less");
));
});
That way, it'll just trigger the task when a file changes. And the task for watching is able to be run separate from your build (which will also make your life easier if you use some form of build automation).
Also, you can specify many watch tasks, like so:
gulp.task("watch", function() {
watch(paths.FOO, function() {
gulp.start("foo");
});
watch(paths.BAR, function() {
gulp.start("bar");
});
});