I am trying to upgrade gulp from 3.x to 4.x
When using gulp watch, the styles, scripts and inject function works well.But when I make any file changes the scripts and styles need to be loaded automatically. This is not working.
I have tried adding gulp.series to each function.
function isOnlyChange(event) {
return event.type === 'changed';
}
gulp.watch([
path.join(conf.paths.src, '/app/**/*.css'),
path.join(conf.paths.src, '/app/**/*.scss')
], gulp.series(function (event) {
if (isOnlyChange(event)) {
gulp.series('styles-reload');
} else {
gulp.series('inject-reload');
}
}));
Gulp watch needs to reload styles when I make changes in styles file but this is not performing.
Can someone help me out how to perform in gulp 4.x
You might try something like this:
function myWatch() {
gulp.watch(['./scss/*.scss'], { events: 'change' }, function (cb) {
console.log("here 1");
// gulp.series('styles-reload');
cb();
});
gulp.watch(['./scss/*.scss'], { events: ['add', 'addDir', 'unlink', 'unlinkDir', 'ready', 'error'] }, function (cb) {
console.log("here 2");
// gulp.series('inject-reload');
cb();
});
}
See https://gulpjs.com/docs/en/api/watch#options to see a description of the events you can include in the second gulp.watch.
I am currently working on migrating gulp from 3.x to 4.x
I am struck while converting gulp.
Below is the gulp.watch code
function isOnlyChange(event) {
return event.type === 'changed';
}
function watch(){
gulp.watch([path.join(conf.paths.src, '/*.html')], ['inject-reload']);
gulp.watch([
path.join(conf.paths.src, '/app/**/*.css'),
path.join(conf.paths.src, '/app/**/*.scss')
], function (event) {
if (isOnlyChange(event)) {
gulp.start('styles-reload');
} else {
gulp.start('inject-reload');
}
});
gulp.watch([path.join(conf.paths.src, '/app/**/*.js'), path.join(conf.paths.src, '/app/**/*.json')], function (event) {
if (isOnlyChange(event)) {
gulp.start('scripts-reload');
} else {
gulp.start('inject-reload');
}
});
gulp.watch(path.join(conf.paths.src, '/app/**/*.html'), function (event) {
browserSync.reload(event.path);
});
};
gulp.task('watch', gulp.series(watch));
})();
I am getting the following error
Error: watching src*.html: watch task has to be a function (optionally generated by using gulp.parallel or gulp.series)
Do I need to add series and parallel for each gulp.watch?
How to migrate this, is there any sample code available for reference.
The error states that the watch task has to be a function, while yours is an array. Change it to:
gulp.watch([path.join(conf.paths.src, '/*.html')], gulp.series('inject-reload'));
For more info, have a look at this question.
When I use the stream() method like this it works well:
var gulp = require('gulp'),
watch = require('gulp-watch'),
browserSync = require('browser-sync').create();
gulp.task('watch', function () {
browserSync.init({
notify: false,
server: {
baseDir: "app"
}
});
watch('./app/assets/styles/**/*.css', gulp.series('cssInject'));
});
gulp.task('cssInject', function () {
return gulp.src('./app/temp/styles/styles.css').pipe(browserSync.stream());
});
When I add another task before executing the stream() only that task is accomplished.
gulp.task('cssInject', gulp.series('styles'), function () {
return gulp.src('./app/temp/styles/styles.css').pipe(browserSync.stream());
});
The console outputs then:
[15:16:00] Starting 'cssInject'...
[15:16:00] Starting 'styles'...
[15:16:00] Finished 'styles' after 50 ms
[15:16:00] Finished 'cssInject' after 53 ms
but CSS wasn't injected, the changes are applied only after manual reload.
I followed this course where they use few outdated packages with different syntax: e.g. the second argument of the task() is set as an array: ['styles']. It didn't work and I found out that you should use series() or paralell() instead.
There is a question on StackOverflow which looks the same as mine, but I didn't manage to find the answer for my issue there as I am gulp novice user.
Solved by: Defined the cssInject as separate task() and put it then into series() as second argument.
gulp.task('cssInject', function () {
return gulp.src('./app/temp/styles/styles.css').pipe(browserSync.stream());
});
gulp.task('manageCSS', gulp.series('styles', 'cssInject'));
I'm trying to create two gulp tasks, and I'd like the second task to take the first one's output stream and keep applying plugins to it.
Can I pass the first task's return value to the second task?
The following doesn't work:
// first task to be run
gulp.task('concat', function() {
// returning a value to signal this is sync
return
gulp.src(['./src/js/*.js'])
.pipe(concat('app.js'))
.pipe(gulp.dest('./src'));
};
// second task to be run
// adding dependency
gulp.task('minify', ['concat'], function(stream) {
// trying to get first task's return stream
// and continue applying more plugins on it
stream
.pipe(uglify())
.pipe(rename({suffix: '.min'}))
.pipe(gulp.dest('./dest'));
};
gulp.task('default', ['minify']);
Is there any way to do this?
you can't pass stream to other task.
but you can use gulp-if module to skip some piped method depending on conditions.
var shouldMinify = (0 <= process.argv.indexOf('--uglify'));
gulp.task('script', function() {
return gulp.src(['./src/js/*.js'])
.pipe(concat('app.js'))
.pipe(gulpif(shouldMinify, uglify())
.pipe(gulpif(shouldMinify, rename({suffix: '.min'}))
.pipe(gulp.dest('./dest'));
});
execute task like this to minify
gulp script --minify
I am looking for the same solution, but ended up just chaining functions.
This is quite flexible.
Please share if anyone has better solution without using additional packages.
function concatenate() {
return gulp
.src(['./src/js/*.js'])
.pipe(concat('app.js'));
}
function minify() {
return this
.pipe(uglify())
.pipe(rename({suffix: '.min'}));
}
function output() {
return this.pipe(gulp.dest('./src'));
}
gulp.task('concat', function() {
return output.call(concatenate());
});
gulp.task('minify', function() {
return output.call(minify.call(concatenate()));
});
gulp.task('default', ['minify']);
I'm aware this has probably been asked before, but I can't seem to be able to ask Google the right questions to find what I need. So I'm possibly thinking about this in the wrong way.
Basically, I need to know if there is a way to use Gulp with Bower so that all css files in subdirectories under bower_components are combined into one styles.css, all js files in subdirectories under bower_components are combined into one scripts.js. Kind of how assetic works in symfony2 to combine assets into single files. Does each 'built' file in each bower_componets subdirectory have to be linked to manually (in the Gulp config file), or is it more common to loop through them programatically?
Thanks
Would something like the below help? It loops through all css files in my 'src' directory and spits out one css file in the 'dist' folder. It does the same for my js files:
// Config
var requireJsRuntimeConfig = vm.runInNewContext(fs.readFileSync('src/app/require.config.js') + '; require;');
requireJsOptimizerConfig = merge(requireJsRuntimeConfig, {
out: 'scripts.js',
baseUrl: './src',
name: 'app/startup',
paths: {
requireLib: 'bower_modules/requirejs/require'
},
include: [
'requireLib',
'components/nav-bar/nav-bar',
'components/home-page/home',
'text!components/about-page/about.html'
],
insertRequire: ['app/startup'],
bundles: {
// If you want parts of the site to load on demand, remove them from the 'include' list
// above, and group them into bundles here.
// 'bundle-name': [ 'some/module', 'another/module' ],
// 'another-bundle-name': [ 'yet-another-module' ]
}
});
// Discovers all AMD dependencies, concatenates together all required .js files, minifies them
gulp.task('js', function () {
return rjs(requireJsOptimizerConfig)
.pipe(uglify({ preserveComments: 'some' }))
.pipe(gulp.dest('./dist/'));
});
// Concatenates CSS files, rewrites relative paths to Bootstrap fonts, copies Bootstrap fonts
gulp.task('css', function () {
var bowerCss = gulp.src('src/bower_modules/components-bootstrap/css/bootstrap.min.css')
.pipe(replace(/url\((')?\.\.\/fonts\//g, 'url($1fonts/')),
appCss = gulp.src('src/css/*.css'),
combinedCss = es.concat(bowerCss, appCss).pipe(concat('css.css')),
fontFiles = gulp.src('./src/bower_modules/components-bootstrap/fonts/*', { base: './src/bower_modules/components-bootstrap/' });
return es.concat(combinedCss, fontFiles)
.pipe(gulp.dest('./dist/'));
});
there is a way and its honestly really simple. you can install "gulp-run" to your npm devDependencies and then use the run to execute bower install.
var gulp = require('gulp'),
del = require('del'),
run = require('gulp-run'),
sass = require('gulp-sass'),
cssmin = require('gulp-minify-css'),
browserify = require('browserify'),
uglify = require('gulp-uglify'),
concat = require('gulp-concat'),
jshint = require('gulp-jshint'),
browserSync = require('browser-sync'),
source = require('vinyl-source-stream'),
buffer = require('vinyl-buffer'),
reactify = require('reactify'),
package = require('./package.json'),
reload = browserSync.reload;
/**
* Running Bower
*/
gulp.task('bower', function() {
run('bower install').exec();
})
/**
* Cleaning lib/ folder
*/
.task('clean', function(cb) {
del(['lib/**'], cb);
})
/**
* Running livereload server
*/
.task('server', function() {
browserSync({
server: {
baseDir: './'
}
});
})
/**
* sass compilation
*/
.task('sass', function() {
return gulp.src(package.paths.sass)
.pipe(sass())
.pipe(concat(package.dest.style))
.pipe(gulp.dest(package.dest.lib));
})
.task('sass:min', function() {
return gulp.src(package.paths.sass)
.pipe(sass())
.pipe(concat(package.dest.style))
.pipe(cssmin())
.pipe(gulp.dest(package.dest.lib));
})
/**
* JSLint/JSHint validation
*/
.task('lint', function() {
return gulp.src(package.paths.js)
.pipe(jshint())
.pipe(jshint.reporter('default'));
})
/** JavaScript compilation */
.task('js', function() {
return browserify(package.paths.app)
.transform(reactify)
.bundle()
.pipe(source(package.dest.app))
.pipe(gulp.dest(package.dest.lib));
})
.task('js:min', function() {
return browserify(package.paths.app)
.transform(reactify)
.bundle()
.pipe(source(package.dest.app))
.pipe(buffer())
.pipe(uglify())
.pipe(gulp.dest(package.dest.lib));
})
/**
* Compiling resources and serving application
*/
.task('serve', ['bower', 'clean', 'lint', 'sass', 'js', 'server'], function() {
return gulp.watch([
package.paths.js, package.paths.jsx, package.paths.html, package.paths.sass
], [
'lint', 'sass', 'js', browserSync.reload
]);
})
.task('serve:minified', ['bower', 'clean', 'lint', 'sass:min', 'js:min', 'server'], function() {
return gulp.watch([
package.paths.js, package.paths.jsx, package.paths.html, package.paths.sass
], [
'lint', 'sass:min', 'js:min', browserSync.reload
]);
});
what is really beautiful with this setup I just posted is this is making a custom gulp run called "serve" that will run your setup with a development server (with live reload and much better error intelligence) all you have to do is go to your directory and type "gulp serve" and it'll run bower install and build everything for you. obviously the folder structure is different so you will need to make some modifications, but hopefully this shows how you can run bower with gulp :)
Something like the below was what I was looking for, except I don't like having to add the paths manually. This is why I prefer something like CommonJS for Javascript. I definitely remember seeing a way in which CSS files were picked up automatically from the bower_components folder, I believe it was in the Wordpress Roots project (based on the settings/overrides in bower.json).
gulp.task('css', function () {
var files = [
'./public/bower_components/angular-loading-bar/build/loading-bar.css',
'./public/bower_components/fontawesome/css/font-awesome.css'
];
return gulp.src(files, { 'base': 'public/bower_components' })
.pipe(concat('lib.css'))
.pipe(minifyCss())
.pipe(gulp.dest('./public/build/css/')
);
});
gulp.task('js-lib', function () {
var files = [
'public/bower_components/jquery/dist/jquery.js',
'public/bower_components/bootstrap-sass/assets/javascripts/bootstrap.js'
];
return gulp.src(files, { 'base': 'public/bower_components/' })
.pipe(sourcemaps.init())
.pipe(uglify({ mangle: false }))
.pipe(concat('lib.js'))
.pipe(sourcemaps.write('./'))
.pipe(gulp.dest('./public/build/js/')
);
});
You can use gulp-main-bower-files library to add the main files of packages in .bower.json instead to declare them manually