Forward reference tasks not defined before use - javascript

I am using multiple files with gulp#4 where the main gulpfile.js includes all other files within the ./tasks/ directory. We are using the npm gulp-hub package to include multiple gulpfiles with the ./tasks/ directory. However we are getting the following error message when calling the tasks.
Forward referenced tasks 'clean-minify-js` not defined before use
How can we include multiple gulpfiles within the main gulpfile.js so that we can call tasks?
Current gulpfile.js:
'use strict';
var gulp = require('gulp'),
HubRegistry = require('gulp-hub');
var genericHub = new HubRegistry('./tasks/scripts.js');
gulp.registry(genericHub);
var watchers = function(done) {
gulp.watch('src/*.js', gulp.parallel('clean-minify-js'));
done();
}
gulp.task('watch', gulp.series(watchers));
Current ./tasks/scripts.js
'use strict';
var gulp = require('gulp'),
clean = require('gulp-clean'),
uglify = require('gulp-uglify');
gulp.task('clean-scripts', function() {
return gulp.src(dest.js)
.pipe(clean({read:false, force: true});
});
gulp.task('minify-js', gulp.series('clean-scripts', function() {
gulp.src(src.js)
.pipe(uglify())
.pipe(gulp.dest(dest.js));
}));
gulp.task('clean-minify-js', gulp.series('minify-js'));
Folder structure:
some/path/gulpfile.js
some/path/tasks/scripts.js

To resolve the issue, I had to do the following.
Use the require-dir package to include all files within the ./tasks/ directory.
convert tasks that were designed for gulp#3.9.1 into functions for gulp#4
use gulp.series to set the functions to run in the particular order we needed
gulpfile.js
'use strict';
var gulp = require('gulp'),
requireDir = require('require-dir');
requireDir('./tasks/');
var watchers = function(done) {
gulp.watch('src/*.js', gulp.parallel('clean-minify-js'));
done();
}
gulp.task('watch', gulp.series(watchers));
./tasks/scripts.js
'use strict';
var gulp = require('gulp'),
clean = require('gulp-clean'),
uglify = require('gulp-uglify');
function cleanScripts() {
return gulp.src(dest.js)
.pipe(clean({read:false, force: true});
}
function minJs() {
return gulp.src(src.js)
.pipe(uglify())
.pipe(gulp.dest(dest.js));
}
gulp.task('clean-minify-js', gulp.series(cleanScripts, minJs));

Related

gulp error - _.flattenDeep is not a function when using gulp.watch

Why do I get TypeError: _.flattenDeep is not a function when I run a watch task
This is my gulpfile.js :
var gulp = require('gulp');
var sass = require('gulp-sass');
var sourcemaps = require('gulp-sourcemaps');
var autoprefixer = require('gulp-autoprefixer');
var cleanCSS = require('gulp-clean-css');
gulp.task('css', function(){
gulp.src('public/sass2/**/*.scss')
.pipe(sourcemaps.init())
.pipe(sass())
.pipe(sourcemaps.write())
.pipe(autoprefixer())
.pipe(gulp.dest('public/css'))
});
gulp.task('default', function() {
gulp.watch('public/sass2/**/*.scss', ['css']);
});
I'm always getting this error when using the watch task, how do I get passed it?
try installing lodash in the project
npm i --save lodash

Gulp watch doesn't "feel" new files

This is my watch.js as written by yeoman gulp-angular generator
'use strict';
var path = require('path');
var gulp = require('gulp');
var conf = require('./conf');
var browserSync = require('browser-sync');
function isOnlyChange(event) {
return event.type === 'changed';
}
gulp.task('watch', ['scripts:watch', 'markups', 'inject'], function () {
gulp.watch([path.join(conf.paths.src, '/*.html'), 'bower.json'], ['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/**/*.jade'), ['markups']);
gulp.watch(path.join(conf.paths.src, '/app/**/*.html'), function(event) {
browserSync.reload(event.path);
});
});
It works fine for already created files, but for some reason gulp.watch doesn't see the new ones (in particular .jade, but maybe also other types), eg.
myApp/src/components/header/headerView.jade
The only solution for me to run task as markup is to stop and restart gulp serve. Then gulp will recognizes changes in my .jade files

Detect what file change with gulp

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.

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.

Can I set gulp livereload to run after all files are compiled?

I've got a gulp set up to work with Stylus, Jade and tiny-lr. My problem is that when I save one jade file, it start's compiling them all, therefore live reloading fires on the first file copied to the destination, before the file I am working on currently is compiled, resulting in me having to refresh manually. I have fixing this issue using "gulp-changed" but I don't seem to be able to configure it or something. Anyone had this problem before? I am posting my Gulp file so you can take a look.
A timeline diagram of the problem can be found here: https://www.dropbox.com/s/3g37oy25s9mq969/jade_compile_frefresh_problem.png?dl=0
Any help is appreciated!
'use strict';
var gulp = require('gulp');
var jade = require('gulp-jade');
var gutil = require('gulp-util');
var stylus = require('gulp-stylus');
var jeet = require('jeet');
var nib = require('nib');
var uglify = require('gulp-uglify');
var lr = require('tiny-lr')();
// var mainBowerFiles = require('main-bower-files');
// Define sources object
var sources = {
jade: "jade/**/*.jade",
partials: "partials/**/*.jade",
stylus: "styl/**/*.styl",
scripts: "js/**/*.js"
};
// Define destinations object
var destinations = {
html: "dist/",
css: "dist/css",
js: "dist/js"
};
// Compile and copy Jade
gulp.task("jade", function(event) {
return gulp.src(sources.jade)
.pipe(jade({
pretty: true
})).pipe(gulp.dest(destinations.html));
});
// Compile and copy Stylus
gulp.task("stylus", function(event) {
return gulp.src(sources.stylus).pipe(stylus({
use: [nib(), jeet()],
import: [
'nib',
'jeet'
],
style: "compressed"
})).pipe(gulp.dest(destinations.css));
});
// Minify and copy all JavaScript
gulp.task('scripts', function() {
gulp.src(sources.scripts)
.pipe(uglify())
.pipe(gulp.dest(destinations.js));
});
// Consolidate Bower Files and copy to /dist/js/
// gulp.task('bower-files', function() {
// return gulp.src(mainBowerFiles(/* options */), {})
// .pipe(gulp.dest(destinations.js));
// });
// Watch for file changes and execute tasks
gulp.task("watch", function() {
gulp.watch(sources.jade, ["jade"]);
gulp.watch(sources.partials, ["jade"]);
gulp.watch(sources.stylus, ["stylus"]);
gulp.watch(sources.scripts, ["scripts"]);
gulp.watch('dist/**/*', refresh);
});
// Live Reload
gulp.task('serve', function () {
var express = require('express');
var app = express();
app.use(require('connect-livereload')());
app.use(express.static(__dirname+'/dist/'));
app.listen(4000, '0.0.0.0');
lr.listen(35729);
});
// Define default task
gulp.task("default", ["jade", "stylus", "scripts", "serve", "watch"]);
// Refresh function
var refresh = function(event) {
var fileName = require('path').relative(__dirname, event.path);
gutil.log.apply(gutil, [gutil.colors.magenta(fileName), gutil.colors.cyan('built')]);
lr.changed({
body: { files: [fileName] }
});
};
I have achieve this by writing a simple javascript function in my gulpfile.js
I did this because when I compile my sass files, livereload will run around 10 times, this method will make it only run once.
My gulpfile.js
gulp.task('watch', function() {
$.livereload.listen();
gulp.watch([
path.join(config.path.app, 'media/js/**/*.js'),
path.join(config.path.app, 'media/css/**/*.css'),
path.join(config.path.app, 'templates/**/*.html')
]).on('change', stackReload);
// a timeout variable
var timer = null;
// actual reload function
function stackReload() {
var reload_args = arguments;
// Stop timeout function to run livereload if this function is ran within the last 250ms
if (timer) clearTimeout(timer);
// Check if any gulp task is still running
if (!gulp.isRunning) {
timer = setTimeout(function() {
$.livereload.changed.apply(null, reload_args);
}, 250);
}
}
});
I have done it. What I had to do is create a new task called "Reload", put dependencies on it and run it after each of the other tasks. Here is the new Gulpfile":
'use strict';
var gulp = require('gulp');
var jade = require('gulp-jade');
var gutil = require('gulp-util');
var stylus = require('gulp-stylus');
var jeet = require('jeet');
var nib = require('nib');
var uglify = require('gulp-uglify');
var livereload = require('gulp-livereload');
var sources = {
jade: "jade/**/*.jade",
partials: "partials/**/*.jade",
stylus: "styl/**/*.styl",
scripts: "js/**/*.js"
};
// Define destinations object
var destinations = {
html: "dist/",
css: "dist/css",
js: "dist/js"
};
// Compile and copy Jade
gulp.task("jade", function(event) {
return gulp.src(sources.jade)
.pipe(jade({pretty: true}))
.pipe(gulp.dest(destinations.html))
});
// Compile and copy Stylus
gulp.task("stylus", function(event) {
return gulp.src(sources.stylus).pipe(stylus({
use: [nib(), jeet()],
import: [
'nib',
'jeet'
],
style: "compressed"
})).pipe(gulp.dest(destinations.css));
});
// Minify and copy all JavaScript
gulp.task('scripts', function() {
gulp.src(sources.scripts)
.pipe(uglify())
.pipe(gulp.dest(destinations.js));
});
// Server
gulp.task('server', function () {
var express = require('express');
var app = express();
app.use(require('connect-livereload')());
app.use(express.static(__dirname+'/dist/'));
app.listen(4000, '0.0.0.0');
});
// Watch sources for change, executa tasks
gulp.task('watch', function() {
livereload.listen();
gulp.watch(sources.jade, ["jade", "refresh"]);
gulp.watch(sources.partials, ["jade", "refresh"]);
gulp.watch(sources.stylus, ["stylus", "refresh"]);
gulp.watch(sources.scripts, ["scripts", "refresh"]);
});
// Refresh task. Depends on Jade task completion
gulp.task("refresh", ["jade"], function(){
livereload.changed();
console.log('LiveReload is triggered');
});
// Define default task
gulp.task("default", ["jade", "stylus", "scripts", "server", "watch"]);
You can use gulp-livereload and write your own callback which send reload event when you want it:
var livereload = require('gulp-livereload'),
path = require('path');
module.exports = function(gulp) {
gulp.task('watch', function() {
livereload.listen();
gulp.watch([
path.resolve(__dirname, '../src/**/*.js'),
path.resolve(__dirname, '../index.html')
]).on('change', function(event) {
livereload.changed();
console.log('File', event.path, 'was', event.type);
console.log('LiveReload is triggered');
});
});
};
UPD: So, for your case you can do this in this way:
1) Install gulp-livereload:
npm install gulp-livereload --save-dev
2) Include gulp-livereload in your gulpfile.js
var livereload = require('gulp-livereload');
3) Replace your old code with watch task, I mean that:
// Watch for file changes and execute tasks
gulp.task("watch", function() {
gulp.watch(sources.jade, ["jade"]);
gulp.watch(sources.partials, ["jade"]);
gulp.watch(sources.stylus, ["stylus"]);
gulp.watch(sources.scripts, ["scripts"]);
gulp.watch('dist/**/*', refresh);
});
And replace it with new code:
gulp.task('watch', function() {
livereload.listen();
gulp.watch([
sources.jade,
sources.partials,
sources.stylus,
sources.scripts,
'dist/**/*'
]).on('change', function(event) {
livereload.changed();
console.log('File', event.path, 'was', event.type);
console.log('LiveReload is triggered');
});
});
4) Of cource check that this configuration fits to your requirements.
I had a similar issue when compiling typescript and then refreshing using livereload. To solve the problem, I created "watch tasks" that run a refresh task once the work is finished.
Below is a minimal code sample taken from your question with the pattern that I've used:
'use strict';
var gulp = require('gulp');
var jade = require('gulp-jade');
var livereload = require('gulp-livereload');
var sources = {
jade: "jade/**/*.jade"
};
var destinations = {
html: "dist/"
};
// Compile and copy Jade
gulp.task("jade", function() {
return gulp.src(sources.jade)
.pipe(jade({pretty: true}))
.pipe(gulp.dest(destinations.html));
});
gulp.task('refresh', function() { return livereload.reload(); });
// execute task, then when finished, refresh
gulp.task("watch-jade", ["jade"], function() { return gulp.start('refresh'); });
gulp.task("watch", function() {
livereload.listen();
gulp.watch(sources.jade, ["watch-jade"]);
});

Categories