gulp-cached
gulp-cached copied to clipboard
Need an option to init the cache
Currently, when I run my gulp watch
task, everything is linted on the first save.
The second time around, only the file I changed gets linted.
My question: Is there a way to enable some sort of init value? I want to cache all my javascript files the first time around if the cache is empty, but NOT lint at all. after that, start my piping and only the changed file will be linted
@Thatkookooguy You can access the cache with cache.caches[cacheName]
- if this allows you to solve the problem I can look into adding an option for this, lmk 🌴
@contra @Thatkookooguy I think i have a similar problem. Imagine you have multiple css tasks that work from the same source (scss-compiler, scss-linter). Because of this you want to cache the contents under the same namespace fe: cache('scss-files')
. In this scenario the very first task will run and all subsequent tasks will do nothing because the first task updated the cache.
Example (with optional pre task):
gulp.task('sass-lint', () => {
return gulp.src(paths.src)
.pipe(gulpIf(config.isDev, cache(config.css.cacheName)))
.pipe(sassLint())
.pipe(sassLint.format())
.pipe(sassLint.failOnError());
});
const preTasks = (!config.sassLint.ideSupport && config.isDev) ? ['sass-lint'] : [];
gulp.task('css', preTasks, () => {
return gulp.src(paths.src)
.pipe(gulpIf(config.isDev, cache(config.css.cacheName)))
.pipe(gulpIf(config.isDev, progeny()))
...
});
Solution: save the previous state of the cache somewhere and only update it at the very last of same cache namespaced task? How would you do this?
+1
Here's a workaround that I implemented in my gulpfile.js
. This example allows creating a watch task that will only lint JavaScript files that have changed:
var gulp = require('gulp');
var gulpif = require('gulp-if');
var gulpCached = require('gulp-cached');
var eslint = require('gulp-eslint');
var jscs = require('gulp-jscs');
var uglify = require('gulp-uglify');
var through2 = require('through2');
(function () {
'use strict';
const linting = 'linting';
var buildConfig = {
flags: {
watch: false,
build: false
},
src: {
scripts: ['./app/**/*.js', './src/**/*.js']
}
};
var preCacheGulpCached = function (src, cache, cacheId, cb) {
/* Pre-build a cache for gulp-cached plugin */
var cacheEntry = cache.caches[cacheId] = cache.caches[cacheId] || {},
cacheFile,
stream;
stream = gulp.src(src).pipe(through2.obj(function (file, encoding, callback) {
var contents = file.checksum;
if (!contents) {
if (file.isStream()) {
this.push(file);
callback();
}
if (file.isBuffer()) {
contents = file.contents.toString('utf8');
}
}
cacheFile = cacheEntry[file.path];
if (typeof cacheFile !== 'undefined' && cacheFile === contents) {
callback();
}
cacheEntry[file.path] = contents;
this.push(file);
callback();
}, cb));
return stream;
};
gulp.task('eslint', function () {
return gulp.src(buildConfig.src.scripts)
.pipe(eslint('.eslintrc'))
.pipe(eslint.format())
.pipe(eslint.failAfterError());
});
gulp.task('jscs', function () {
return gulp.src(buildConfig.src.scripts)
.pipe(jscs({ configPath: '.jscsrc' }))
.pipe(jscs.reporter())
.pipe(jscs.reporter('fail'));
});
gulp.task('lint', function () {
return gulp.src(buildConfig.src.scripts)
.pipe(gulpif(buildConfig.flags.watch, gulpCached(linting)))
.pipe(eslint('.eslintrc'))
.pipe(eslint.format())
.pipe(jscs({ configPath: '.jscsrc' }))
.pipe(jscs.reporter())
.pipe(gulpif(buildConfig.flags.build, jscs.reporter('failImmediately')))
.pipe(gulpif(buildConfig.flags.build, eslint.failAfterError()));
//.on('error', process.exit.bind(process, 1)); alternatively, this could be used in place of eslint.failAfterError.
});
gulp.task('watch', function () {
buildConfig.flags.watch = true;
preCacheGulpCached(buildConfig.src.scripts, gulpCached, linting, function () {
console.log('gulp-cached pre-cache complete');
});
gulp.watch(buildConfig.src.scripts, ['lint']);
});
})();
I'm running into the same problem where I need to pre-cache before the watch triggers linting.
@cookch10 tried your solution and for some reason I don't even see the console.log for the pre-cach being complete.
did something change? thanks for the script btw! it at least gave me a starting point :-)
fixed it by making the following change:
var preCacheGulpCached = function (src, cache, cacheId, cb) {
/* Pre-build a cache for gulp-cached plugin */
var cacheEntry = cache.caches[cacheId] = cache.caches[cacheId] || {},
cacheFile,
stream;
stream = gulp.src(src).pipe(through2.obj(function (file, encoding, callback) {
var contents = file.checksum;
if (!contents) {
if (file.isStream()) {
this.push(file);
callback();
}
if (file.isBuffer()) {
contents = file.contents.toString('utf8');
}
}
cacheFile = cacheEntry[file.path];
if (typeof cacheFile !== 'undefined' && cacheFile === contents) {
callback();
}
cacheEntry[file.path] = contents;
this.push(file);
cb();
}));
return stream;
};
it looks like through2
now accepts only one variable
So, since @cookch10 didn't work for me for some reason, I copied his idea and created a function to initialize the cache.
It's probably bad practice somewhere, but here we go:
var gulp = require('gulp'),
cache = require('gulp-cached'),
gulpif = require('gulp-if'),
gcallback = require('gulp-callback');
var preCacheGulpCached = function (src, cacheId, cb) {
/* Pre-build a cache for gulp-cached plugin */
var callCallback = true; // fix callback executing more than once
return gulp.src(src)
.pipe(cache(cacheId))
.pipe(gcallback(function() {
if (callCallback && cb) {
cb();
callCallback = false;
}
}));
};
gulp.task('jscpd', function() {
return gulp.src(FILES.LINT)
.pipe(gulpif(buildConfig.flags.watch, cache('jscpd')))
.pipe(jscpd({
'min-lines': 10,
verbose : true
}));
});
gulp.task('magicNumbers', function () {
return gulp.src(FILES.JS_ALL)
.pipe(gulpif(buildConfig.flags.watch, cache('magicNumbers')))
.pipe(buddyjs({
reporter: 'detailed'
}));
});
gulp.task('watch', function() {
buildConfig.flags.watch = true;
preCacheGulpCached(FILES.JS_ALL, 'jscpd');
preCacheGulpCached(FILES.JS_ALL, 'magicNumbers');
if (argv.lint) {
preCacheGulpCached(FILES.LINT, 'linting');
}
gulp.watch(argv.lint ? FILES.LINT : [], ['lint-js']);
gulp.watch(FILES.JS_ALL, ['jscpd', 'magicNumbers']);
gulp.watch(FILES.FRONTEND_SASS, ['styles']);
gulp.watch(FILES.SERVER_JS).on('change', restart);
gulp.watch(FILES.FRONTEND_ALL).on('change', function(file) {
reloadBrowser('Frontend file changed.', file.path);
});
});
I use gulp-callback
since I need something after the chache
command. If I don't include something after the cache
in preCacheGulpCached
, The files aren't being cached.
~~I also tried to call the actual callback with gulp-callback
but it printed out 3 times for each run so I removed it.~~
UPDATE: fixed the multiple callback execution
but it works!
How would y'all want to see this functionality added to the project? Anyone want to propose some APIs?
the way i managed files to be precached using @Thatkookooguy function:
gulp.task('watch-pages', function(){
return preCache(templatePagesPath, 'pages', function(){
gulp.watch(templatePagesPath, ['pages']);
});
})
gulp.task('watch-styles', function(){
return preCache(stylesheetsPath, 'styles', function(){
gulp.watch(stylesheetsPath, ['styles']);
});
})
gulp.task('watch', ['watch-pages','watch-styles']);
notice the return
statement - without it caching doesn't work