hbsfy outputs hbsfy code on compile - using Gulp + Browserify - javascript

I am trying to get any variation of hbsfy or browserify-handlebars to compile correctly using browserify. Compiling results in the handlebars.js(hbsfy) code outputting to my browser. I've tried just using the browserify command browserify -t hbsfy app.js > bundle.js but it doesn't change anything
I haven't the reputation to post images but basically this is the output:
var templater = require("handlebars/runtime").default.template;module.exports = templater(function (Handlebars,depth0,helpers,partials,data) { this.compilerInfo = [4,'>= 1.0.0']; helpers = this.merge(helpers, Handlebars.helpers); data = data || {}; var buffer = "", stack1, helper, functionType="function", escapeExpression=this.escapeExpression; buffer += "
Hello "; if (helper = helpers.name) { stack1 = helper.call(depth0, {hash:{},data:data}); } else { helper = (depth0 && depth0.name); stack1 = typeof helper === functionType ? helper.call(depth0, {hash:{},data:data}) : helper; } buffer += escapeExpression(stack1) + "
"; return buffer; });
My template (template.hbs) is simply <h1>Hello {{name}}</h1>
My gulpfile setup:
var gulp = require('gulp');
var livereload = require('gulp-livereload');
var browserify = require('gulp-browserify');
var hbsfy = require('browserify-handlebars');
//var hbsfy = require('hbsfy'); //this one shows up the same way
gulp.task('scripts', function() {
return gulp.src('./app/app.js')
.pipe(browserify({
transform: [hbsfy]
}))
.pipe(rename('bundle.js'))
.pipe(gulp.dest('./build/js'))
.pipe(connect.reload());
});
and my js file:
var Handlebars = require('hbsfy/runtime');
var $ = require('jquery'),
router = require('./router/routerDefault'),
template = require('./template.hbs');
$(document).ready(function(){
document.body.innerHTML = template({name: 'browserify'});
})
Does anyone have any experience on how to handle this? Any suggestions would be heplful!

The cause of this issue is redundant compiling. Listing a transform in both the packages.json and the gulpfile.js will perform it twice, I believe. In my packages.json, I now just use this 'node':
"browserify": {
"transform": [
"hbsfy"
]
},
This will compile your templates for you. Your gulpfile.js DOES NOT require this section:
.pipe(browserify({
transform: [hbsfy]
}))
You can use either one. My scripts gulp task now looks like this:
gulp.task('scripts', function() {
return browserify('./app/app.js')
.bundle()
.pipe(source('bundle.js'))
.pipe(gulp.dest('./build/js'))
.pipe(connect.reload());
});

I am experiencing something similar.
Just curious, what OS are you using? Seems to affect Mac but Windows seems OK.
I'm not entirely sure what's causing this but I stopped using gulp-browserify as it is now blacklisted.
I followed the suggestions from this blog post and it seems to solve the issue: http://viget.com/extend/gulp-browserify-starter-faq
The last bit is most relevant.
EDIT:
While using gulp-browserify, I would also check if you've listed your transforms in package.json. I think you may only need to specify transforms in one place (either in gulpfile as you have now or in package.json).

Related

How to sync a local folder with gulp, with update for deleted files and folders?

I am working on a WordPress plugin and have all the files in my working directory and run gulp in that project folder. Now, I'd like to have a watch task that copies all the changes to my local WP installation for testing.
Therefore I am looking for a way to sync (only in one direction) the project folder with the plugin folder of WP.
I managed to get it to work with gulp-directory-sync
...
var dirSync = require("gulp-directory-sync");
var localDir = "../newDir/";
var buildDir = "./buildDir/";
...
function copy_to_local_folder() {
return pipeline(
gulp.src(buildDir+'**/*'),
dirSync( buildDir, localDir, { printSummary: true } )
);
}
function watch_local() {
gulp.watch(buildDir+'**/*', copy_to_local_folder);
exports.default = watch_local;
However, the plugin hasn't been updated in 4 years and according to this answer, it is not doing it the proper "gulp way" (e.g. not using gulp-src) and this task should be possible with other basic gulp functions.
Copying changed files is pretty easy, but also keeping track of deleted files is more complicated. I also would prefer to only update changed/deleted/new files and not clearing the folder every time before coping all files.
Starting with the updated code in the aforementioned answer, I tried to implement it and made changes to make it work.
...
var newer = require("gulp-newer");
var pipeline = require("readable-stream").pipeline;
var del = require("del");
var localDir = "../newDir/";
var buildDir = "./buildDir/";
function copy_to_local_folder() {
return pipeline(
gulp.src([buildDir+'**/*']),
newer(localDir),
gulp.dest(localDir),
);
}
function watch_local() {
var watcher = gulp.watch(buildDir + '**/*', copy_to_local_folder );
watcher.on('unlink', function(path) {
console.log(path);
var newPath = './'+path;
newPath = newPath.replace(buildDir, localDir);
console.log(newPath);
(async () => {
const deletedPaths = await del(newPath, {dryRun: true, force: true});
console.log('Deleted files and directories:\n', deletedPaths.join('\n'));
})();
});
}
exports.default = watch_local;
With this code, the folder gets updated when I change or delete files, but it does not trigger when I delete an entire folder. Which is probably because I use unlink and not unlinkDir. But even if I use the version of the function below, it doesn't get triggered by deleting a folder (with containing files).
watcher.on('unlinkDir', function(path) {
console.log('folder deleted');
console.log(path);
var newPath = './'+path;
newPath = newPath.replace(buildDir, localDir);
console.log(newPath);
});
What am I doing wrong?
Or is there in general a better way to achieve this?
PS: I'm using
node v11.15.0
gulp v4.0.2
on Linux
deleting files and folders in VS Code
Update:
When I run it with:
watcher.on('unlink', ... and delete a file:
it works
with the console.log output and the ( async () => ...
and Starting and Finished for copy_to_local_folder
watcher.on('unlinkDir', ... and delete a folder:
it works not
nothing happens in the console output
(not even Starting)
watcher.on('unlinkDir', ... and delete a file:
Starting and Finished for copy_to_local_folder
but not the console.log and ( async () => ...
watcher.on('add', ... and watcher.on('addDir', ...
work both
Seems to me that the watcher.on('unlinkDir', ... does never get triggered ... is unlinkDir not supported by gulp-watch?

With the Browserify API, use require and exclude on a local file

With the Browserify API and Gulp, I have this:
var browserify = require('browserify');
var gulp = require('gulp');
var source = require('vinyl-source-stream');
var dependencies = [
'lodash',
'./test.js',
];
gulp.task('lib', function() {
return browserify()
.require(dependencies)
.bundle()
.pipe(source('lib.js'))
.pipe(gulp.dest('./'));
});
gulp.task('app', function() {
return browserify('./app.js')
.external(dependencies)
.bundle()
.pipe(source('bundle.js'))
.pipe(gulp.dest('./'));
});
And in app.js I have this:
var _ = require('lodash');
var test = require('./test.js');
The Lodash line works fine, but the ./test.js does not work. I get the error Error: Cannot find module '/test.js'.
How do I get this to work?
For some reason, the key differs between bundle.js and lib.js. In lib.js, the key for test.js is the full path (/Users/gary/Projects/browserify-test/test.js) whereas in bundle.js it's looking for a module with the key ./test.js. If I manually change the latter to be the same as the former, then it works.
I'm guessing that ultimately, Browserify doesn't support require on local files that are excluded from the same bundle.
browserify needs an absolute path to retrieve the file and it leaves that as the bundle key. The way to fix it is to use the expose option...
In your build..
var dependencies = [
'lodash',
{file: './test.js', expose: 'test'},
];
and in app.js...
var _ = require('lodash');
var test = require('test');

Gulp task apply uglify if file in pipe is javascript

I want to check if the file in the pipe is .js or not (it could be .map, .html, ...). And if so, uglifying it before copying it in the correct path.
ʕ •́؈•̀) I've try something like this (which not working):
gulpfile.js
gulp.src(current + '/**/*', {base: current})
.pipe($.tap(function (file) {
if (path.extname(file.path) === '.js') {
return gulp.src(file.path)
.pipe($.uglify());
}
}))
.pipe(gulp.dest(destination + '/' + name));
But for now, the uglify seems to do nothing...
Is anyone have a clue on how to do this ? (╥﹏╥)
If you're open to using plugins there is one called gulp-filter that does what you're asking for. https://www.npmjs.com/package/gulp-filter
It would probably look something like this
var gulp = require('gulp');
var gulpFilter = require('gulp-filter');
gulp.task('default', function () {
// create filter instance inside task function
var jsfilter = gulpFilter('**/*.js', {restore: true});
return gulp.src(current + '/**/*', {base: current})
// filter a subset of the files
.pipe(jsFilter)
// run them through a plugin
.pipe($.uglify())
// bring back the previously filtered out files (optional)
.pipe(jsFilter.restore)
.pipe(gulp.dest(destination + '/' + name));
});
try using gulp-filter
something like
var filter = require('gulp-filter');
var jsFilter = filter('**/*.js');
gulp.src('*/*')
.pipe(jsFilter)
.pipe(uglify)

Set working directory in gulpfile.js?

Is there a way to set the working directory for Gulp within a gulpfile, so that I can run a gulp command from a subdirectory without running into any issues? I ran a search for this and didn't find what I was looking for.
To clarify, I'm aware of adding a prefix to the files I'm using. However, instead of this -
var gulp = require('gulp');
var jshint = require('gulp-jshint');
...
var paths = {
js: [__dirname + 'app/*/*.js', __dirname + '!app/lib/**'],
css: __dirname + 'app/*/*.styl',
img: __dirname + 'app/img/*',
index: __dirname + '*.html',
dist: __dirname + 'dist'
};
I'd like to do something like this:
var gulp = require('gulp');
var jshint = require('gulp-jshint');
...
gulp.cwd(__dirname); // This would be much easier to understand, and would make future edits a bit safer.
var paths = {
js: ['app/*/*.js', '!app/lib/**'],
css: 'app/*/*.styl',
img: 'app/img/*',
index: '*.html',
dist: 'dist'
};
I'm wondering if Gulp exposes this functionality. Perhaps node itself allows this.
(I realize that there is likely a way to do command line itself when I run the command, but I would like to include it in the gulp file, especially for distribution purposes. I want the working directory for gulp to match the directory in which the gulpfile resides.)
Thanks!
Besides option.cwd, you can also use process.chdir(yourDir)
it could be used anywhere in a gulpfile. e.g.
process.chdir(yourDir);
var gulp = require('gulp');
Make sure your gulp is up-to-date( > 3.8.10), this may not work in older gulp.
Instead of concatenating strings by yourself, you should be using path.join since it will take care of the proper slash, and following that path you can add a shorcut:
var path = require('path'),
p = function () {
Array
.prototype
.unshift
.call(arguments, __dirname);
return path.join.apply(path, arguments);
};
console.log(p('a', 'b', 'c'));
Or, well, you can just:
gulp.src(..., {cwd: __dirname})
gulp.dest(..., {cwd: __dirname})
Something like:
var src = function (globs, options) {
options = options || {};
options.cwd = __dirname;
return gulp.src(globs, options);
};
var dest = function (folder, options) {
options = options || {};
options.cwd = __dirname;
return gulp.dest(folder, options);
};
Look here and here.

How to add a path prefix to globs passed to gulp.src?

Consider the following two files:
config.json
{
"vendorFiles": [
"vendor/angular/angular.js",
"vendor/angular-ui-router/release/angular-ui-router.js",
"vendor/angular-ui-utils/modules/utils.js"
]
}
gulpfile.js
var gulp = require("gulp"),
concat = require("gulp-concat"),
config = require("./config");
gulp.task("build-vendor", function() {
gulp.src(config.vendorFiles)
.pipe(concat("vendor.js"))
.pipe(gulp.dest("build"));
});
How can I eliminate the need to specify vendor/ for each file in config.json? That file is one that is manually edited by other developers by hand, so I want to make it as hassle-free on them as possible.
Ideally I'd like my gulpfile.js to take care of adding that prefix (somehow), and for my config.json to look like this:
{
"vendorFiles": [
"angular/angular.js",
"angular-ui-router/release/angular-ui-router.js",
"angular-ui-utils/modules/utils.js"
]
}
There may be a better way with a Gulp specific solution, but this should work.
var gulp = require("gulp"),
concat = require("gulp-concat"),
config = require("./config");
gulp.task("build-vendor", function() {
gulp.src(config.vendorFiles.map(function(a) {return 'vendor/' + a}))
.pipe(concat("vendor.js"))
.pipe(gulp.dest("build"));
});
Demo:
http://jsfiddle.net/AK4tP/
Can't you just do
var gulp = require("gulp"),
concat = require("gulp-concat"),
config = require("./config");
gulp.task("build-vendor", function() {
gulp.src(config.vendorFiles, {root: 'vendor/'})
.pipe(concat("vendor.js"))
.pipe(gulp.dest("build"));
});
Gulp should accept root option in src() although it's not documented.

Categories