Gulp task to only compile files that have changed - gulp

I need to write a gulp task that will only compile those Typescript files that have actually changed and came up with this:
var gulp = require('gulp');
var print = require('gulp-print');
var newer = require('gulp-newer');
var ts = require('gulp-typescript');
gulp.task('compile:ts', function () {
return gulp.src([
'typings/browser.d.ts',
'app/**/*.ts'
])
.pipe(newer('app'))
.pipe(print(function (filepath) {
return 'Compiling ' + filepath + '...';
}))
.pipe(ts({
target: 'es5',
module: 'commonjs',
moduleResolution: 'node',
sourceMap: true,
emitDecoratorMetadata: true,
experimentalDecorators: true,
removeComments: false,
noImplicitAny: false
}))
.pipe(gulp.dest('app'));
});
However, this task doesn't find any modified files although there are .ts files with more recent timestamps than their .js counterpart.
Where did I go wrong?

However, this task doesn't find any modified files although there are .ts files with more recent timestamps than their .js counterpart.
That's because you're not telling gulp-newer to compare .ts files with .js files. You're comparing .ts files with themselves, so there is no change to be detected.
You need to tell gulp-newer to compare each .ts file with its .js counterpart:
.pipe(newer({dest:'app',ext:'.js'}))

There is an easier method of compiling files when they change. Using gulp watch, you can run the function once and whenever you save a change, it'll run the compiling function.
gulp.task('watch', function() {
gulp.watch(['ts/filepaths','more/ts/filepaths'],
['compile:ts','otherFunctionsIfNeeded']);
});
If you rewrite compile:ts to only compile, using the function above, whenever you save a ts file, it will compile it for you

Related

gulp less compile only changed file

i have problem, when i run gulp watch -> run task styles:build, and all of my less files was recompile. How i can compile only changed file?
gulp.task('styles:build', function () {
return gulp.src(pathes.src.styles)
.pipe(changed(pathes.build.styles), {extension: '.css'})
.pipe(print(function(filepath) {
return "➔ file was changed: " + filepath;
}))
.pipe(plumber())
.pipe(less({
plugins: [autoprefix, cleanCSSPlugin],
paths: ['./', 'web/styles']
}))
.pipe(gulp.dest(pathes.build.styles))
});
gulp.task('watch', function() {
gulp.watch(pathes.src.styles, ['styles:build'])
});
You need to modify the line below to add a closing parenthsis:
.pipe(changed(pathes.build.styles, {extension: '.css'}))
Also as I cautioned the first time the task is run it probably will pass through all files.
i think i found solution
just install lessChanged = require('gulp-less-changed')
and include him before less pipe
.pipe(lessChanged())
.pipe(less())

Gulp: minify and unminfy tasks

I am new to gulp so i don't know as much good gulp plugins. I wrote a code for minifying js, css and html using gulp and its plugins which is working fine. But now i am stuck in unminifying code. I don't know which plugins to use which can easily unminify code.
guplfile.js:
var gulp = require('gulp'),
uglify = require('gulp-uglify')
htmlmin = require('gulp-html-minifier')
csso = require('gulp-csso');
gulp.task('min_js', function () {
gulp.src('app/**/*.js')
.pipe(uglify())
.pipe(gulp.dest('min'))
});
gulp.task('min_html', function () {
gulp.src('app/**/*.html')
.pipe(htmlmin({ collapseWhitespace: true }))
.pipe(gulp.dest('min'))
});
gulp.task('min_css', function () {
gulp.src('app/**/*.css')
.pipe(csso())
.pipe(gulp.dest('min'))
});
gulp.task('minify_all', ['min_js', 'min_html', 'min_css']);
//pending
//gulp.task('unminify',[]);
Uglifying/Minifying is attended for production, you should not uglify your code while you are developing (except for testing purpose).
When you start gulp tasks, you have to make sure that you have in one part your "working code", that you will transform into a "destination code".
When you are doing this :
gulp.task('min_js', function () {
gulp.src('app/**/*.js')
.pipe(uglify())
.pipe(gulp.dest('min'))
});
The code on which you are working on is in the app folder, and your transformed code is in the min folder (it's the destination folder).
But, if the min directory is also used in development, just disable the uglify task in development (easier to debug a not-uglifyied file).
There is no need to un-minify your sources, there are still present in app folder.

How to run gulp tasks with different parameters depending on the argument on terminal

I have a shared SCSS source files which must be compiled and copied into different project folders.
I have a build task which calls 2 tasks, clean and styles(to compile/minify and copy to build folder).
My source SCSS files are shared between all websites however the destination folders are different.
I would like to be able to run: build websiteA and then clean build folder inside websiteA and compile files from a shared folder and copied to build folder inside Website A.
var assetsDir = '_Assets';
var buildStyleWebsiteA = 'WebsiteA/Assets/build';
var buildStyleWebsiteB = 'WebsiteB/Assets/build';
gulp.task('clean-websiteA', function (cb) {
return del([buildStyleWebsiteA ], cb);
});
gulp.task('styles-websiteA', ['clean-websiteA'], function () {
return gulp.src(assetsDir + '/**/*.scss')
.pipe(sourcemaps.init())
.pipe(sass().on('error', sass.logError))
.pipe(autoprefixer())
.pipe(gulp.dest(buildStyleWebsiteA + '/css'))
.pipe(concat('styles.css'))
.pipe(cleanCss())
.pipe(sourcemaps.write())
.pipe(rename({ suffix: '.min' }))
.pipe(gulp.dest(buildStyleWebsiteA + '/min/'))
.pipe(liveReload());
});
gulp.task('build-websiteA', ['styles']);
PS: I also have same tasks for websiteB (build-websiteB, clean-websiteB, and style-websiteB).
So I ended up with repetitive code and I know there must be a better way.
What I would like to have is provide website name as a parameter for gulp command and then it runs clean and style using correct folder related to that website.
How can I refactor my code to achieve that?
Thanks
I would use environment variables to accomplish this rather than arguments.
var buildDir = process.env.BUILD_DIR + '/Assets/build';
Then you would call it as:
BUILD_DIR=websiteA gulp build

gulp-react. How to compile and save all folders

I use gulp-react to compile jsx to js. I need to save folder structure while compiling.
The code below works good for single folder of all files, but I need dumanic destination
var gulp = require('gulp');
var react = require('gulp-react');
gulp.task('default', function () {
return gulp.src('template.jsx')
.pipe(react())
.pipe(gulp.dest('dist')); // in this line need dumanic destination
});
Any Ideas?
Problem solved like this
gulp.src('./public/js/**/.')

Why don't newly added files trigger my gulp-watch task?

I have a gulp task which uses gulp-imagemin to compress images. When I add new files to this directory I'd like for this task to compress them as well. I read that gulp.watch doesn't trigger on new files and that I should try gulp-watch so I used it like so;
gulp.task('images', function() {
watch({glob: './source/images/*'}, function (files) {
return files
.pipe(plumber())
.pipe(imagemin({
progressive: true,
interlaced: true
}))
.pipe(gulp.dest('./www'));
});
});
This works the same as gulp.watch on the first run, but when I add a new image to the directory nothing happens. If I overwrite an existing file however, it DOES run the task again, so it does behave differently.
The documentation on gulp-watch called this "Batch Mode" and said I could also run the task on a per-file basis, so I tried this way too;
gulp.task('images', function() {
gulp.src('./source/images/*')
.pipe(watch())
.pipe(plumber())
.pipe(imagemin({
progressive: true,
interlaced: true
}))
.pipe(gulp.dest('./www'));
});
But nothing changed. Why isn't adding files to my image directory triggering the task?
Adding an extra argument {cwd:'./'} in gulp.watch worked for me:
gulp.watch('src/js/**/*.js',{cwd:'./'},['scripts']);
2 things to get this working:
1 Avoid ./ in the file/folder patterns
2 Ensure ./ in the value for cwd
Good Luck.
Ref:- https://stackoverflow.com/a/34346524/4742733
Most likely such kind of questions are redirected to gaze package and its internal processes, that runs complicated watching procedures on your OS. In this case you should pass images/**/* to glob option, so gaze will watch all (including new) files in images directory:
var gulp = require('gulp');
var watch = require('gulp-watch');
var imagemin = require('gulp-imagemin');
gulp.task('default', function() {
watch({glob: 'images/**/*'}, function (files) {
files.pipe(imagemin({
progressive: true,
interlaced: true
}))
.pipe(gulp.dest('./www'));
});
});
But this fill not fix case, when you have empty images directory. If you want to watch them, pass ['images', 'images/**/*'] to glob, and it will watch directory, that initially empty.
P.s. also you dont need gulp-plumber in this case, because watch will rerun function, that uses imagemin every time, even when imagemin pops an error.