Detect what file change with gulp - javascript

I have this gulpfile:
var gulp = require('gulp'),
concat = require('gulp-concat'),
uglify = require('gulp-uglify');
gulp.task('minifyJS', function() {
return gulp.src(['src/*.js'])
.pipe(uglify())
.pipe(gulp.dest('min'));
});
gulp.task('watch', function() {
gulp.watch(['src/*.js'], ['minifyJS']);
});
I want to know what file trigger the watcher and his absolute path.
For example: if my project is placed in /myCode and I change the file src/main.js, I want to see /myCode/src/main.js inside minifyJS task. Is there a way to do it?
Thank you for your time.

You can do it by using gulp-ng-annotate and gulp-changed:
var gulp = require('gulp');
var changed = require('gulp-changed');
var rename = require('gulp-rename');
var ngAnnotate = require('gulp-ng-annotate'); // just as an example
var SRC = 'src/*.js';
var DEST = 'src/';
//Function to get the path from the file name
function createPath(file) {
var stringArray = file.split('/');
var path = '';
var name = stringArray[1].split('.');
stringArray = name[0].split(/(?=[A-Z])/);
if (stringArray.length>1) {stringArray.pop()};
return {folder: stringArray[0], name: name[0]}
}
gulp.task('default', function () {
return gulp.src(SRC)
.pipe(changed(DEST))
// ngAnnotate will only get the files that
// changed since the last time it was run
.pipe(ngAnnotate())
.pipe(rename(function (path) {
var createdPath = createPath(path);
path.dirname = createdPath.folder;
path.basename: createdPath.name,
path.prefix: "",
path.suffix: "",
path.extname: ".min.js"
}))
.pipe(gulp.dest(DEST));
});
Result:

Use gulp-changed npm package.
$ npm install --save-dev gulp-changed
Try the below in gulp file, (I haven't tried)
var gulp = require('gulp'),
concat = require('gulp-concat'),
uglify = require('gulp-uglify'),
changed = require('gulp-changed');
gulp.task('minifyJS', function() {
return gulp.src(['src/*.js'])
.pipe(changed('min'))
.pipe(uglify())
.pipe(gulp.dest('min'));
});
gulp.task('watch', function() {
gulp.watch(['src/*.js'], ['minifyJS']);
});
see the documentation of this package https://www.npmjs.com/package/gulp-changed

Based on your comment to Julien's answer this should be fairly close to what you want, or at least get you going in the right direction:
var gulp = require('gulp'),
concat = require('gulp-concat'),
uglify = require('gulp-uglify'),
cache = require('gulp-cached'),
rename = require('gulp-rename'),
path = require('path');
function fileName(file) {
return file.dirname + path.sep + file.basename + file.extname;
}
gulp.task('minifyJS', function() {
return gulp.src(['src/*.js'])
.pipe(cache('minifyJS'))
.pipe(rename(function(file) {
var nameOfChangedFile = fileName(file);
if (nameOfChangedFile == './main.js') {
file.basename = 'main.min'
}
if (nameOfChangedFile == './userView.js') {
file.basename = 'user/userView.min'
}
console.log(nameOfChangedFile + ' -> ' + fileName(file));
}))
.pipe(uglify())
.pipe(gulp.dest('min'));
});
gulp.task('watch', function() {
gulp.watch(['src/*.js'], ['minifyJS']);
});
This uses gulp-cached to keep an in-memory cache of all the files in your src/ folder that have passed through the stream. Only files that have changed since the last invocation of minifyJS are passed down to the gulp-rename plugin.
The gulp-rename plugin itself is then used to alter the destination path of the changed files.
Note: the cache is empty on first run, since no files have passed through the gulp-cached plugin yet. This means that the first time you change a file all files in src/ will be written to the destination folder. On subsequent changes only the changed files will be written.

Related

How to install gulp-sass-glob

When I am trying to save scss files which are imported to main sccs file - every time I need resave main scss file to apply changes. therefore I have decided to install gulp-sass-glob according to this https://www.npmjs.com/package/gulp-sass-glob
but unfortunately it does not work.
Here is my code, please help me how to integrate gulp-sass-glob in my gulp file or what is wrong here. Thank you.
const { src, dest, parallel, series, watch } = require('gulp');
// Load plugins
const sass = require('gulp-sass');
const browsersync = require('browser-sync').create();
const htmlmin = require('gulp-htmlmin');
// Directories
const SRC = './src/';
const DEST = './dist/';
const DEST_CSS = `${DEST}css/`;
const SRC_CSS = `${SRC}scss/*main.scss`;
var gulp = require('gulp');
var sassGlob = require('gulp-sass-glob');
gulp.task('styles', function () {
return gulp
.src(SRC_CSS)
.pipe(sassGlob())
.pipe(sass())
.pipe(gulp.dest(DEST_CSS));
});
// Watch files
function watchFiles() {
watch(`${SRC_CSS}*`, css);
watch(`${SRC}lang`, html);
}
// BrowserSync
function browserSync() {
browsersync.init({
server: {
baseDir: DEST
},
port: PORT
});
}
// Tasks to define the execution of the functions simultaneously or in series
exports.watch = series(
clear,
parallel( css, html, copyStaticHTML, watchFiles, browserSync)
);
exports.default = series(clear, parallel(js, css, html, copyStaticHTML));

Set a different destination folder structure than the source folder

I'm running a gulp task to minify and move JS files.
var js_modules = 'application/modules/**/assets/js/*.js';
var js_dist_modules = 'assets/js/modules/';
gulp.task('dev_scripts', function() {
return gulp.src(js_modules)
.pipe(plumber())
.pipe(uglify())
.pipe(gulp.dest(js_dist_modules));
});
With this task the output is:
Source:
application/modules/users/assets/js/users.js
application/modules/menu/assets/js/menu.js
Destination:
assets/js/modules/users/assets/js/users.js
assets/js/modules/menu/assets/js/menu.js
And I want the destinations to be:
assets/js/modules/users/users.js
assets/js/modules/menu/menu.js
How do I achiev that?
I used gulp-rename:
var rename = require('gulp-rename');
var js_modules = 'application/modules/**/assets/js/*.js';
var js_dist_modules = 'assets/js/modules/';
gulp.task('dev_scripts', function() {
return gulp.src(js_modules)
.pipe(plumber())
.pipe(uglify())
.pipe(rename(function(file) {
file.dirname = js_dist_modules + file.basename;
}))
.pipe(gulp.dest(.));
});
Using gulp-flatten it appears something like this may work (untested):
var flatten= require('gulp-flatten);
var js_modules = 'application/modules/**/assets/js/*.js';
var js_dist_modules = 'assets/js/modules/';
gulp.task('dev_scripts', function() {
return gulp.src(js_modules)
.pipe(plumber())
.pipe(uglify())
.pipe(flatten({ subPath: [2, 1] } ))
.pipe(gulp.dest(js_dist_modules));
});
You could play with the subPath numbers to get the third (2) or whichever subDirectory you want.
This answer is more general than the previous using rename in case your desired directories - in your case the glob ** - are not the same as files' basenames.

How to setup gulp for this type of scaffolding?

Folder Structure
Components
------component1
-partials
- js
- html
- scss
- component1.css
- component1.js
------component2
-partials
- js
- html
- scss
- component2.css
- component2.js
Functionality is all my js, html and scss file convert into one css and js fine but inside into the component folder.
If I create a new component I don't want every time to add them separately into gulp It will automatically add through gulp. How can I write my gulp to achieve this type of functionality ?
Help will be really appreaticed...!!!
You can use this code that I created for your case:
Project structure:
folder structure tested
gulpfile.js
/**
* Created by Anderson on 22/04/2016.
*/
'use strict';
var gulp = require('gulp');
var data = require('gulp-data');
var concat = require('gulp-concat');
var sass = require('gulp-sass');
var gcallback = require('gulp-callback');
var rename = require('gulp-rename');
var del = require('del');
var path = require('path');
var fs = require('fs');
gulp.task('main',function(){
//scan componens folder all files and folders
gulp.src("./components/**")
.pipe(data(function(file,cb){
var filepath = file.path;
var stats = fs.lstatSync(filepath);
var base = file.base;
var fpath = filepath.replace(file.base,"");
//console.log(fpath);
var array = fpath.split("\\");
var basename = path.basename(fpath);
var componentName = array[0];
//destiny
var dest = base + fpath.replace(basename,"");
dest = dest.replace("partials\\","");
//process the scss
if(stats.isDirectory() && basename == "scss"){
//console.log(array,componentName,basename);
//console.log(file.path);
var scssScan = base + fpath+"\\*.scss";
console.log("scan",scssScan );
console.log("dest",dest);
//scan dir for scss
gulp.src(scssScan)
//concat all scss in a temporary file
.pipe(concat(componentName+".scss"))
.pipe(gulp.dest(dest))
.pipe(gcallback(function(){
//scan to process the scss
var componentPath = base + componentName;
var componentScssScan = componentPath + "\\*.scss";
//console.log(componentPath,componentScssScan);
//console.log(componentPath + "\\" + componentName+".scss");
//scan the component dir for scss
gulp.src(componentScssScan)
//process the sass
.pipe(sass())
.pipe(gulp.dest(dest));
//delete the temporary scss
//.pipe(del(componentPath + "\\" + componentName+".scss"));
}));
}
//process the js
if(stats.isDirectory() && basename == "js"){
//console.log(array,componentName,basename);
//console.log(file.path);
var scssScan = base + fpath+"\\*.js";
console.log("scan",scssScan );
console.log("dest",dest);
//scan dir for js
gulp.src(scssScan)
//concat all js in a temporary file
.pipe(concat(componentName+".js"))
.pipe(gulp.dest(dest));
}
cb(undefined,undefined);
}));
});
I think what you need to do is add watcher for the css and js files and run specific task based on the changes, here's some example:
var gulp = require('gulp'),
less = require('gulp-less'),
cleancss = require('gulp-clean-css'),
server = require('gulp-server-livereload'),
rename = require('gulp-rename');
gulp.task('server', ['watch', 'webserver']);
gulp.task('styles', function() {
return gulp.src('public/assets/less/app.less')
.pipe(less())
.pipe(rename('app.css'))
.pipe(cleancss())
.pipe(rename({suffix: '.min'}))
.pipe(gulp.dest('public/dist/css'))
});
// Add watcher for the changes in files
gulp.task('watch', function() {
gulp.watch('public/assets/less/*.less', ['styles']);
})
gulp.task('webserver', function() {
gulp.src('public')
.pipe(server({
livereload: true,
port: 8080,
open: true,
}))
});
And you can use Livereload Chrome Extension to enable browser auto-refresh whenever there's a changes in your code as well.

gulp will not output js min file

Cant seem to find my problem here. After I run Gulp, the all-css.min.css gets outputted to _build folder but the JS will not go! am I missing something? Cant seem to find what is making this not work.
var gulp = require('gulp');
var concat = require('gulp-concat');
var uglify = require('gulp-uglify');
var minifyHTML = require('gulp-minify-html');
var sourcemaps = require('gulp-sourcemaps');
var minifyCSS = require('gulp-minify-css');
var inlineCss = require('gulp-inline-css');
var rev = require("gulp-rev");
var del = require('del');
var jsBase = {
src: [
'/Scripts/Core/ko.bindinghandlers-1.0.0.js',
'/Scripts/Twitter/typeahead-0.10.2.js',
'/Scripts/LdCore/mobile-core.js',
'/Scripts/LDCore/Chat.js',
'/Scripts/unsure.js' // These have any unknown lines in them.
]
};
gulp.task('clean', function () {
del.sync(['_build/*'])
});
gulp.task('produce-css', function () {
return gulp.src(cssBase.src)
.pipe(minifyCSS({ keepBreaks: false }))
.pipe(concat('all-css.min.css'))
.pipe(gulp.dest('_build/'))
});
gulp.task('produce-minified-js', function () {
return gulp.src(jsBase.src)
//.pipe(sourcemaps.init())
//.pipe(uglify())
.pipe(concat('all.min.js'))
//.pipe(rev()) // adds random numbers to end.
//.pipe(sourcemaps.write('.'))
.pipe(gulp.dest('_build/'));
});
gulp.task('default', ['clean'], function () {
gulp.start('produce-css', 'produce-minified-js');
});
According to Contra at this post, we shouldn't be using gulp.start.
gulp.start is undocumented on purpose because it can lead to
complicated build files and we don't want people using it
Bad:
gulp.task('default', ['clean'], function () {
gulp.start('produce-css', 'produce-minified-js');
});
Good:
gulp.task('default', ['clean','produce-css','produce-minified-js'], function () {
// Run the dependency chains asynchronously 1st, then do nothing afterwards.
});
It's totally legit to have nothing in the gulp.task, as what it's doing is running the dependency chains asynchronously & then terminating successfully.
You could also do the following:
gulp.task('default', ['clean','produce-css','produce-minified-js'], function (cb) {
// Run a callback to watch the gulp CLI output messages.
cb();
});
Since Gulp creates "Starting default" on the CLI, this would help to display "Finished default" in the CLI after everything else runs.

Get Gulp watch to perform function only on changed file

I am new to Gulp and have the following Gulpfile
var gulp = require('gulp');
var jshint = require('gulp-jshint');
var concat = require('gulp-concat');
var rename = require('gulp-rename');
var uglify = require('gulp-uglify');
gulp.task('compress', function () {
return gulp.src('js/*.js') // read all of the files that are in js with a .js extension
.pipe(uglify()) // run uglify (for minification)
.pipe(gulp.dest('dist/js')); // write to the dist/js file
});
// default gulp task
gulp.task('default', function () {
// watch for JS changes
gulp.watch('js/*.js', function () {
gulp.run('compress');
});
});
I would like to configure this to rename, minify and save only my changed file to the dist folder. What is the best way to do this?
This is how:
// Watch for file updates
gulp.task('watch', function () {
livereload.listen();
// Javascript change + prints log in console
gulp.watch('js/*.js').on('change', function(file) {
livereload.changed(file.path);
gutil.log(gutil.colors.yellow('JS changed' + ' (' + file.path + ')'));
});
// SASS/CSS change + prints log in console
// On SASS change, call and run task 'sass'
gulp.watch('sass/*.scss', ['sass']).on('change', function(file) {
livereload.changed(file.path);
gutil.log(gutil.colors.yellow('CSS changed' + ' (' + file.path + ')'));
});
});
Also great to use gulp-livereload with it, you need to install the Chrome plugin for it to work btw.
See incremental builds on the Gulp docs.
You can filter out unchanged files between runs of a task using the gulp.src function's since option and gulp.lastRun

Categories