Browserify fails to create bundle with babelify transform (TypeError: Path must be a string.) - gulp

I've written a gulp task to compile my .jsx and .js scripts into a bundle using watchify and babelify as a transform. For some reason my gulp script seems to be choking on the transform and I'm not sure why:
gulp.task('browserify', function() {
var bundle = watchify(browserify('./app/jsx/client/index.jsx', {
extensions: ['.js', '.jsx'],
debug: process.env.NODE_ENV === 'development'
}));
bundle.transform(babelify);
bundle.on('update', function() {
rebundle(bundle);
});
function rebundle(bundle) {
return bundle.bundle()
.on('error', function(error) {
console.log(error.stack, error.message);
this.emit('end');
})
.pipe(
gulpif(
(process.env.NODE_ENV == 'production'),
require('gulp-rename')('bundle.min.js'),
require('gulp-rename')('bundle.js')
)
)
.pipe(gulpif((process.env.NODE_ENV == 'production'), buffer()))
.pipe(gulpif((process.env.NODE_ENV == 'production'), uglify()))
.pipe(gulp.dest('dist/js'));
}
return rebundle(bundle);
});
In the console...
path.js:8
throw new TypeError('Path must be a string. Received ' +
^
TypeError: Path must be a string. Received undefined
at assertPath (path.js:8:11)
at Object.posix.join (path.js:480:5)
at Transform.stream._transform (/home/zipp/search-admin/node_modules/gulp-rename/index.js:52:22)
at Transform._read (_stream_transform.js:167:10)
at Transform._write (_stream_transform.js:155:12)
at doWrite (_stream_writable.js:292:12)
at writeOrBuffer (_stream_writable.js:278:5)
at Transform.Writable.write (_stream_writable.js:207:11)
at Readable.ondata (/home/zipp/search-admin/node_modules/browserify/node_modules/read-only-stream/node_modules/readable-stream/lib/_stream_readable.js:572:20)
at emitOne (events.js:77:13)
at Readable.emit (events.js:169:7)

That error is because you need a vinyl-source-stream in there. The result of .bundle() is a standard Node stream of file data. You are taking that data are passing it to rename which expects a stream of Gulp File objects.
var source = require('vinyl-source-stream');
// stuff
function rebundle(bundle) {
return bundle.bundle()
.on('error', function(error) {
console.log(error.stack, error.message);
this.emit('end');
})
.pipe(
gulpif(
(process.env.NODE_ENV == 'production'),
// Use 'source' here instead, which converts binary
// streams to file streams.
source('bundle.min.js'),
source('bundle.js')
)
)
.pipe(gulpif((process.env.NODE_ENV == 'production'), buffer()))
.pipe(gulpif((process.env.NODE_ENV == 'production'), uglify()))
.pipe(gulp.dest('dist/js'));
}
Instead of using rename, you can use source to define the initial name of the file.

Related

AssertionError [ERR_ASSERTION]

I have gulp file that is having issues with latest update to gulp 4 I am getting assertion errors (AssertionError [ERR_ASSERTION]: Task function must be specified) and it seems (from googling) to have to do with how tasks are defined, but not sure if this is the case here and what needs to change.
Node: node -v
v14.16.0
CLI version: 2.3.0
Local version: 4.0.2
NPM: 6.14.11
Here is the code
// ### CSS processing pipeline
// Example
// ```
// gulp.src(cssFiles)
// .pipe(cssTasks('main.css')
// .pipe(gulp.dest(path.dist + 'styles'))
// ```
var cssTasks = function(filename) {
return lazypipe()
.pipe(function() {
return gulpif(!enabled.failStyleTask, plumber());
})
.pipe(function() {
return gulpif(enabled.maps, sourcemaps.init());
})
.pipe(function() {
return gulpif('*.less', less());
})
.pipe(function() {
return gulpif('*.scss', sass({
outputStyle: 'nested', // libsass doesn't support expanded yet
precision: 10,
includePaths: ['.'],
errLogToConsole: !enabled.failStyleTask
}));
})
.pipe(concat, filename)
.pipe(autoprefixer, {
browsers: [
'last 2 versions',
'android 4',
'opera 12'
]
})
.pipe(cssNano, {
safe: true
})
.pipe(function() {
return gulpif(enabled.rev, rev());
})
.pipe(function() {
return gulpif(enabled.maps, sourcemaps.write('.', {
sourceRoot: 'assets/styles/'
}));
})();
};
// ### JS processing pipeline
// Example
// ```
// gulp.src(jsFiles)
// .pipe(jsTasks('main.js')
// .pipe(gulp.dest(path.dist + 'scripts'))
// ```
var jsTasks = function(filename) {
return lazypipe()
.pipe(function() {
return gulpif(enabled.maps, sourcemaps.init());
})
.pipe(concat, filename)
.pipe(uglify, {
compress: {
'drop_debugger': enabled.stripJSDebug
}
})
.pipe(function() {
return gulpif(enabled.rev, rev());
})
.pipe(function() {
return gulpif(enabled.maps, sourcemaps.write('.', {
sourceRoot: 'assets/scripts/'
}));
})();
};
// ### Write to rev manifest
// If there are any revved files then write them to the rev manifest.
// See https://github.com/sindresorhus/gulp-rev
var writeToManifest = function(directory) {
return lazypipe()
.pipe(gulp.dest, path.dist + directory)
.pipe(browserSync.stream, {match: '**/*.{js,css}'})
.pipe(rev.manifest, revManifest, {
base: path.dist,
merge: true
})
.pipe(gulp.dest, path.dist)();
};
// ## Gulp tasks
// Run `gulp -T` for a task summary
// ### Styles
// `gulp styles` - Compiles, combines, and optimizes Bower CSS and project CSS.
// By default this task will only log a warning if a precompiler error is
// raised. If the `--production` flag is set: this task will fail outright.
gulp.task('styles', ['wiredep'], function() {
var merged = merge();
manifest.forEachDependency('css', function(dep) {
var cssTasksInstance = cssTasks(dep.name);
if (!enabled.failStyleTask) {
cssTasksInstance.on('error', function(err) {
console.error(err.message);
this.emit('end');
});
}
merged.add(gulp.src(dep.globs, {base: 'styles'})
.pipe(plumber({errorHandler: onError}))
.pipe(cssTasksInstance));
});
return merged
.pipe(writeToManifest('styles'));
});
// ### Scripts
// `gulp scripts` - Runs JSHint then compiles, combines, and optimizes Bower JS
// and project JS.
gulp.task('scripts', function() {
var merged = merge();
manifest.forEachDependency('js', function(dep) {
merged.add(
gulp.src(dep.globs, {base: 'scripts'})
.pipe(plumber({errorHandler: onError}))
.pipe(jsTasks(dep.name))
);
});
return merged
.pipe(writeToManifest('scripts'));
});
// ### Fonts
// `gulp fonts` - Grabs all the fonts and outputs them in a flattened directory
// structure. See: https://github.com/armed/gulp-flatten
gulp.task('fonts', function() {
return gulp.src(globs.fonts)
//.pipe(flatten())
.pipe(gulp.dest(path.dist + 'fonts'))
.pipe(browserSync.stream());
});
// ### Images
// `gulp images` - Run lossless compression on all the images.
gulp.task('images', function() {
return gulp.src(globs.images)
.pipe(imagemin([
imagemin.jpegtran({progressive: true}),
imagemin.gifsicle({interlaced: true}),
imagemin.svgo({plugins: [
{removeUnknownsAndDefaults: false},
{cleanupIDs: false}
]})
]))
.pipe(gulp.dest(path.dist + 'images'))
.pipe(browserSync.stream());
});
// ### JSHint
// `gulp jshint` - Lints configuration JSON and project JS.
gulp.task('jshint', function() {
return gulp.src([
'bower.json', 'gulpfile.js'
].concat(project.js))
.pipe(jshint())
.pipe(jshint.reporter('jshint-stylish'))
.pipe(gulpif(enabled.failJSHint, jshint.reporter('fail')));
});
// ### Clean
// `gulp clean` - Deletes the build folder entirely.
gulp.task('clean', require('del').bind(null, [path.dist]));
// ### Watch
// `gulp watch` - Use BrowserSync to proxy your dev server and synchronize code
// changes across devices. Specify the hostname of your dev server at
// `manifest.config.devUrl`. When a modification is made to an asset, run the
// build step for that asset and inject the changes into the page.
// See: http://www.browsersync.io
gulp.task('watch', function() {
browserSync.init({
files: ['{lib,templates}/**/*.php', '*.php'],
proxy: config.devUrl,
snippetOptions: {
whitelist: ['/wp-admin/admin-ajax.php'],
blacklist: ['/wp-admin/**']
}
});
gulp.watch([path.source + 'styles/**/*'], ['styles']);
gulp.watch([path.source + 'scripts/**/*'], ['scripts']);
gulp.watch([path.source + 'fonts/**/*'], ['fonts']);
gulp.watch([path.source + 'images/**/*'], ['images']);
gulp.watch(['bower.json', 'assets/manifest.json'], ['build']);
});
// ### Build
// `gulp build` - Run all the build tasks but don't clean up beforehand.
// Generally you should be running `gulp` instead of `gulp build`.
gulp.task('build', function(callback) {
runSequence('styles',
'scripts',
['fonts', 'images'],
callback);
});
// ### Wiredep
// `gulp wiredep` - Automatically inject Less and Sass Bower dependencies. See
// https://github.com/taptapship/wiredep
gulp.task('wiredep', function() {
var wiredep = require('wiredep').stream;
return gulp.src(project.css)
.pipe(wiredep())
.pipe(changed(path.source + 'styles', {
hasChanged: changed.compareSha1Digest
}))
.pipe(gulp.dest(path.source + 'styles'));
});
Any help is greatly appreciated.
So there are a few things wrong with your code.
gulp.task('styles', ['wiredep'], function() {
for example should be
gulp.task('styles', gulp.series('wiredep', function() { etc.
gulp.task only takes three arguments. You may have more places in your code like this.
gulp.watch([path.source + 'styles/**/*'], ['styles']); might actually be fine but lets be careful and make it a little more future-proof:
gulp.watch([path.source + 'styles/**/*'], gulp.series('styles'));
Etc. change all of these in your watch task.
With gulp.series and gulp.parallel you no longer need something like runSequence. So replace
gulp.task('build', function(callback) {
runSequence('styles',
'scripts',
['fonts', 'images'],
callback);
});
with
gulp.task('build', gulp.series(
'styles',
'scripts',
gulp.parallel('fonts', 'images')
// callback); // see below
);
Make these changes and you'll see if you need the `callback` in the `build` task - if you get a message about signaling async completion.
-----------
And you may have to move your `wiredep` task before your `styles` task. Since you are using `gulp.task` rather than functions to create your tasks, you cannot refer to a task that hasn't been created yet. That wouldn't be an issue if you used all named functions to create each task.

Gulp event.js:163 throw err; // Unhandled 'error' event

I have taken git clone and run npm install without sudo, the same setup was working perfect on windows machine but its breaking on Mac OSX:
Here is my gulpfile.js
var gulp = require('gulp');
// Load plugins
var plugin = require('gulp-load-plugins')({
pattern: '*'
});
var paths = {
css: 'app/resources/css',
sass: 'app/resources/scss',
js: 'app/**/*.module.js, app/components/**/*.js',
html: 'app/*.html'
};
// Compile SASS using Compass,
// Compass required as we using its utitlities
gulp.task('compass', function(){
return gulp.src( paths.sass + '/*.scss' )
.pipe(plugin.compass({
css: paths.css,
sass: paths.sass,
task: 'watch',
comments: false
}));
});
// Watch task, keep checking for changes
gulp.task('watch', function(){
gulp.watch([
paths.sass + '/*.scss',
paths.html,
paths.js
]).on('change', plugin.browserSync.reload);
});
// LiveReload Task
gulp.task('serve', function(){
plugin.browserSync.init([], {
server: {
baseDir: ['./', './app']
}
});
});
// Build HTML
gulp.task('html', function(){
return gulp.src('app/*.html')
.pipe(plugin.useref())
.pipe(gulp.dest('dist'));
});
// Copy Images
gulp.task('images', function(){
return gulp.src('app/resources/images/*')
.pipe(gulp.dest('dist/resources/images/'));
});
// Copy Fonts
gulp.task('fonts', function(){
return gulp.src('app/resources/fonts/*')
.pipe(gulp.dest('dist/resources/fonts/'));
});
// Copy Templates
gulp.task('templates', function(){
return gulp.src('app/components/**/*')
.pipe(gulp.dest('dist/components/'));
});
// Clean
gulp.task('clean', function(){
return gulp.src([
'dist/base', 'dist/components', 'dist/resources'
], {
read: false
})
.pipe( plugin.clean());
});
// Build
gulp.task('build', [ 'compass', 'html', 'images', 'fonts', 'templates', 'serve'])
// Default
gulp.task('default', ['clean'], function(){
gulp.start('build');
});
I am getting following error on terminal, thinks path is picking wrong dont know where i made mistake:
events.js:163
throw er; // Unhandled 'error' event
^
Error: Error: File not found with singular glob: /learning/recharge-desktop-code/learning/recharge-desktop-code/app/resources/css/common.css
at DestroyableTransform.<anonymous> (/learning/recharge-desktop-code/node_modules/gulp-useref/index.js:65:28)
at emitOne (events.js:101:20)
at DestroyableTransform.emit (events.js:191:7)
at emitOne (events.js:101:20)
at Through2.emit (events.js:191:7)
at OrderedStreams.<anonymous> (/learning/recharge-desktop-code/node_modules/gulp-useref/node_modules/glob-stream/index.js:140:20)
at emitOne (events.js:96:13)
at OrderedStreams.emit (events.js:191:7)
at emitOne (events.js:96:13)
at DestroyableTransform.emit (events.js:191:7)
Strange, it was path issue i have changed css path in my html and its worked, while same was not required on windows machine, is anyone can help to understand this?
Maybe is this problem.
It's say
Thanks! We are aware of this issue and a fix is being worked on. Closing as this is a duplicate of #12841. Be on the lookout for the next v7.x release (which will probably be next week). Thanks!
https://github.com/nodejs/node/issues/13077

Conditionally running transform on browserify

I have added the babelify transformation and i've noticed that my mainScripts task now takes around 10 seconds instead of 0.5s as before.
I would therefore like to apply .transform("babelify", {presets: ["es2015"]}) only when the environment is or prod in order to speed up the task during development.
My function for determining the current environment
var isLocal = function() {
return argv.env === 'localdev' || argv.env === 'dev';
};
My scripts task:
gulp.task('mainScripts', function() {
return browserify('./app/app.js', {
debug: true
})
.transform("babelify", {presets: ["es2015"]})
.bundle()
.on('error', function(err) {
console.log(err.toString());
this.emit("end");
})
.pipe(source('main.js'))
.pipe(buffer())
.pipe(gulpif(!condition, sourcemaps.init({
loadMaps: true
})))
.pipe(ngAnnotate())
.pipe(gulpif(!condition, uglify({
mangle: true
}).on('error', gutil.log)))
.pipe(gulpif(!condition, sourcemaps.write('./')))
.pipe(gulp.dest('./dist/js/')).
pipe(gulpif(isLocal(), connect.reload()));
});
How can this be achieved?
The call to browserify returns the bundler and the transform call is just chained off that, so you can optionally call transform by doing something like this:
gulp.task('mainScripts', function() {
var bundler = browserify('./app/app.js', {
debug: true
});
if (!isLocal()) {
bundler = bundler.transform("babelify", { presets: ["es2015"] });
}
return bundler
.bundle()
.on('error', function(err) {
...
}
...
Alternatively, you could have a look for some gulp recipes for watchify, which should greatly improve your incremental build times.
How about using .plugin?
var babelify = function (b) {
return isLocal()
? b
: b.transform("babelify", {presets: ["es2015"]});
};
// .plugin(babelify)
browserify Plugins section says: plugin take the bundle instance as their first parameter
For some more advanced use-cases, a transform is not sufficiently extensible. Plugins are modules that take the bundle instance as their first parameter and an option hash as their second.
Applying plugin will be formatted like this:
var babelify = function (b) {
return isLocal()
? b
: b.transform("babelify", {presets: ["es2015"]});
};
gulp.task('mainScripts', function() {
return browserify('./app/app.js', {
debug: true
})
.plugin(babelify)
.bundle()
.on('error', function(err) {
...
}
...

Gulp Task - Pass var to next pipe

I have the following gulp task
// global criticalCSS
criticalCSS = "";
// Generate & Inline Critical-path CSS
gulp.task('optimize:critical', ['styles'], function() {
critical.generate({
base: config.critical.base,
src: 'index.html',
css: config.critical.css
}, function (err, output) {
// You now have critical-path CSS
console.log(output);
criticalCSS = output;
});
return gulp.src(config.critical.base + '/*.html')
.pipe(plumber({
errorHandler: onError
}))
.pipe(
htmlreplace({
'criticalCss': '<style>' + criticalCSS + '</style>',
})
)
.pipe(vinylPaths(del))
.pipe(gulp.dest(config.critical.base));
});
I expected that criticalCSS was globally containing the output of critical.generate. The console.log displays the output properly. But in
'criticalCss': '<style>' + criticalCSS + '</style>',
criticalCSS returns a empty string.
How can i solve this issue?
Just a shot in the dark, but it looks like the initial critical.generate call is being run asynchronously, and the criticalCSS variable isn't guaranteed to be properly initialized.
To ensure that the criticalCSS variable is initialized when you proceed to the gulp stream portion of this task, you can utilize the promise syntax of the critical plugin found at: https://www.npmjs.com/package/critical
However, you still need to let gulp know when the task has completed... You can utilize a callback method in conjunction with the stream events shown at: Run code after gulp task done with all files to let gulp know when the task has completed (and if any errors have occurred):
gulp.task('optimize:critical', ['styles'], function(done) {
critical.generate({
base: config.critical.base,
src: 'index.html',
css: config.critical.css})
// Promise syntax that will run after critical has finished.
.then(function (output) {
// You now have critical-path CSS
console.log(output);
// criticalCSS = output;
var stream = gulp.src(config.critical.base + '/*.html')
.pipe(plumber({
errorHandler: onError
}))
.pipe(
htmlreplace({
'criticalCss': '<style>' + output + '</style>',
})
)
.pipe(vinylPaths(del))
.pipe(gulp.dest(config.critical.base));
stream.on('end', function() {
done();
});
stream.on('error', function(err) {
done(err);
});
// Error on the initial critical call
}).error(function(err){
done(err);
});
});
In this version of the task, you shouldn't even need the criticalCSS variable.

check if runSequence fail

I have the following task on my gulpfile:
gulp.task('build', function (cb) {
return runSequence(
'clean',
'tsd',
'ts-lint',
['sass', 'copy-assets', 'ts-compile', 'templates', 'copy-vendor'],
'karma-once',
'index',
cb
);
});
How can I check if any of the tasks in a runSequence fail in gulp?
The callback function that runSequence accepts as last argument, gives you an err object if some task failed.
runSequence('mytask', ['othertask'], function(err) {
if (err) {
// you can check for err.message or err.task for the name of the task
}
});