I'm using browserify and knockout and am trying to load html files for knockout component templates. I have browserify successfully loading javascript files, but I'm unclear on how to get it to load html files.
I'm trying to do something like this:
(function() {
var ko = require('./lib/knockout/dist/knockout.js');
var authenticationViewModel = require('./viewmodels/authentication.js');
var authenticationView = require('./views/authentication.html');
ko.components.register('authentication', {
template: authenticationView,
viewModel: authenticationViewModel
});
})();
But the template is obviously not loading. Can someone please explain to me how this is to be accomplished?
This is what I have in my gulpfile.js to get browserify to work with .js files:
gulp.task('browserify', function () {
var browserified = transform(function(filename) {
var b = browserify(filename);
return b.bundle();
});
return gulp.src([paths.appJs])
.pipe(browserified)
.pipe(gulp.dest(paths.public));
});
I'm looking into the html-browserify plugin:
https://www.npmjs.com/package/html-browserify
The example they are using looks like this:
gulp.task('js', function() {
gulp.src('js/app.js')
.pipe(browserify({
insertGlobals: true,
transform: html
}))
.pipe(concat('app.js'))
.pipe(gulp.dest('./public/js'));
});
But I'm unclear on how to reconcile this example with my current code that is already working.
brfs should be one option.
In one of my own apps I use gulp to read some template files, combine them into an object, and write a JSON file that I load in my (browserified) app.
I ended up finding and using partialify. It works perfectly for inporting html files as dependencies.
//Gulp Plugins
var gulp = require('gulp');
var browserify = require('browserify');
var source = require('vinyl-source-stream');
var partialify = require('partialify');
//Browserify
gulp.task('browserify', function() {
return browserify()
.add(paths.browserifyEntry)
.bundle()
.pipe(source('main.js'))
.pipe(gulp.dest(paths.public));
});
Related
I am using express and node in server side and handlebars as templating engine.
Now from the official documentation of gulp-compile-handlebars I came to know about pre-compiling technique of handlebars templates, which I am doing as below -
const handlebars = require('gulp-compile-handlebars');
const rename = require('gulp-rename');
gulp.task('compile-handlebars', function () {
var templateData = {
data: 'Kaanon'
},
options = {
batch : ['./views/partials'],
helpers : {
capitals : function(str){
return str.toUpperCase();
}
}
}
return gulp.src('views/home.handlebars')
.pipe(handlebars(templateData, options))
.pipe(rename('home.html'))
.pipe(gulp.dest('build'));
});
But this allows me to precompile the handlebar templates one by one, whereas I want a process which will compile all files to html in that process itself.
e.g SASS compilation and converting to Css files I am doing like this,
const sass = require('gulp-sass');
gulp.task('styles', function() {
gulp.src('sass/*.scss')
.pipe(sass(compile_config).on('error', sass.logError))
.pipe(gulp.dest('./assets/css/'))
});
This converts all sass files to respective css files.
I want a similar thing for my handlebar templates.
Attaching my directory structure for better understanding,
Right now I have two tasks: templates and js. templates has to run first so that changes are be picked up by js. I want to combine these, eliminating the intermediate file, so that the task works like this:
Compile and concatenate templates into a single chunk of JS
Concatenate that chunk with the rest of my application's JS code
Output the whole thing as a single file
How can I do this?
Here's my current code:
var gulp = require('gulp');
var handlebars = require('gulp-handlebars');
var concat = require('gulp-concat');
var wrap = require('gulp-wrap');
var declare = require('gulp-declare');
// Compile Handlebars templates into JS
gulp.task('templates', function() {
return gulp.src('./templates/*.hbs')
.pipe(handlebars({
handlebars: require('handlebars')
}))
.pipe(wrap('Handlebars.template(<%= contents %>)'))
.pipe(declare({
namespace: 'templates',
noRedeclare: true,
}))
.pipe(concat('templates.js'))
.pipe(gulp.dest('./js/'));
});
// Concatenate and minify application JS
gulp.task('js', function() {
return gulp.src('./js/*.js')
.pipe(concat('app.js'))
.pipe(gulp.dest('./dist/js'));
For me the easyest and cleaner way is to call one task after the other with
gulp.task('js', ['templates'], function(){
....
In this way the js task need the execution of templates task
Keeping the compilation and the final concat in 2 separate task it's not that bad for me.
Let me know if it's not a viable solution for you
EDIT
in one single task you can try to use merge-stream
and do
var merge = require('merge-stream');
gulp.task('templates', function() {
var jsStream = gulp.src('./js/*.js')
.pipe(concat('all.js'));
var templateStream = gulp.src('./templates/*.hbs')
.pipe(handlebars({
handlebars: require('handlebars')
}))
.pipe(wrap('Handlebars.template(<%= contents %>)'))
.pipe(declare({
namespace: 'templates',
noRedeclare: true,
}))
.pipe(concat('templates.js'));
merge(jsStream, templateStream)
.pipe(concat('app.js'))
.pipe(gulp.dest('./dist/js'));
});
I've done it by heart without trying so my not work as intended
I am using gulp to uglify and make ready my javascript files for production. What I have is this code:
var concat = require('gulp-concat');
var del = require('del');
var gulp = require('gulp');
var gzip = require('gulp-gzip');
var less = require('gulp-less');
var minifyCSS = require('gulp-minify-css');
var uglify = require('gulp-uglify');
var js = {
src: [
// more files here
'temp/js/app/appConfig.js',
'temp/js/app/appConstant.js',
// more files here
],
gulp.task('scripts', ['clean-js'], function () {
return gulp.src(js.src).pipe(uglify())
.pipe(concat('js.min.js'))
.pipe(gulp.dest('content/bundles/'))
.pipe(gzip(gzip_options))
.pipe(gulp.dest('content/bundles/'));
});
What I need to do is to replace the string:
dataServer: "http://localhost:3048",
with
dataServer: "http://example.com",
In the file 'temp/js/app/appConstant.js',
I'm looking for some suggestions. For example perhaps I should make a copy of the appConstant.js file, change that (not sure how) and include appConstantEdited.js in the js.src?
But I am not sure with gulp how to make a copy of a file and replace a string inside a file.
Any help you give would be much appreciated.
Gulp streams input, does all transformations, and then streams output. Saving temporary files in between is AFAIK non-idiomatic when using Gulp.
Instead, what you're looking for, is a streaming-way of replacing content. It would be moderately easy to write something yourself, or you could use an existing plugin. For me, gulp-replace has worked quite well.
If you want to do the replacement in all files it's easy to change your task like this:
var replace = require('gulp-replace');
gulp.task('scripts', ['clean-js'], function () {
return gulp.src(js.src)
.pipe(replace(/http:\/\/localhost:\d+/g, 'http://example.com'))
.pipe(uglify())
.pipe(concat('js.min.js'))
.pipe(gulp.dest('content/bundles/'))
.pipe(gzip(gzip_options))
.pipe(gulp.dest('content/bundles/'));
});
You could also do gulp.src just on the files you expect the pattern to be in, and stream them seperately through gulp-replace, merging it with a gulp.src stream of all the other files afterwards.
You may also use module gulp-string-replace which manages with regex, strings or even functions.
Example:
Regex:
var replace = require('gulp-string-replace');
gulp.task('replace_1', function() {
gulp.src(["./config.js"]) // Every file allown.
.pipe(replace(new RegExp('#env#', 'g'), 'production'))
.pipe(gulp.dest('./build/config.js'))
});
String:
gulp.task('replace_1', function() {
gulp.src(["./config.js"]) // Every file allown.
.pipe(replace('environment', 'production'))
.pipe(gulp.dest('./build/config.js'))
});
Function:
gulp.task('replace_1', function() {
gulp.src(["./config.js"]) // Every file allown.
.pipe(replace('environment', function () {
return 'production';
}))
.pipe(gulp.dest('./build/config.js'))
});
I think that the most correct solution is to use the gulp-preprocess module. It will perform the actions you need, depending on the variable PRODUCTION, defined or not defined during the build.
Source code:
/* #ifndef PRODUCTION */
dataServer: "http://localhost:3048",
/* #endif */
/* #ifdef PRODUCTION **
dataServer: "http://example.com",
/* #endif */
Gulpfile:
let preprocess = require('gulp-preprocess');
const preprocOpts = {
PRODUCTION: true
};
gulp.task('scripts', ['clean-js'], function () {
return gulp.src(js.src)
.pipe(preprocess({ context: preprocOpts }))
.pipe(uglify())
.pipe(concat('js.min.js'))
.pipe(gulp.dest('content/bundles/'));
}
This is the best solution because it allows you to control the changes that are made during the build phase.
There I have a versioning specific example for your reference.
let say you have version.ts file and it contains the version code inside it. You now can do as the follows:
gulp.task ('version_up', function () {
gulp.src (["./version.ts"])
.pipe (replace (/(\d+)\.(\d+)(?:\.(\d+))?(?:\-(\w+))?/, process.env.VERSION))
.pipe (gulp.dest ('./'))
});
the above regex works for many situation on any conventional version formats.
I am currently using gulp-jade and I am struggling on how to setup Jade includes in my gulpfile.js.(For clarification, I am referring to this here http://jade-lang.com/reference/includes/) The following is the code in my gulpfile.js
var gulp = require('gulp');
var browserSync = require('browser-sync');
var sass = require('gulp-sass');
var uglify = require('gulp-uglify');
var jade = require('gulp-jade');
var jshint = require('gulp-jshint');
var fileinclude = require('gulp-file-include');
var reload = browserSync.reload;
//compile jade to html
gulp.task('templates', function() {
var YOUR_LOCALS = {};
gulp.src('./app/jade/*.jade')
.pipe(jade({
locals: YOUR_LOCALS
}))
.pipe(gulp.dest('./dist/'))
});
//reload files, once jade compilation happens
gulp.task('jade-watch', ['templates'], reload);
//Sass task for live injecting into all browsers
gulp.task('sass', function () {
gulp.src('./app/scss/*.scss')
.pipe(sass())
.pipe(gulp.dest('./dist/css'))
.pipe(reload({stream: true}));
});
//Separate task for the reaction to js files make change even without compilation and what not
gulp.task('compress', function() {
return gulp.src('./app/js/*.js')
.pipe(uglify())
.pipe(gulp.dest('./dist/js'));
});
gulp.task('js-watch', ['compress'], reload);
//Serve and watch the scss/jade files for changes
gulp.task('default', ['sass', 'templates', 'compress'], function () {
browserSync({server: './dist'});
gulp.watch('./app/**/*.jade', ['jade-watch']);
gulp.watch('./app/scss/*.scss', ['sass']);
gulp.watch('./app/js/*.js', ['js-watch']);
});
I know it is quite a bit to parse through. I am hoping it is a standard something, that won't take too long. If you are interested in seeing the entire file structure, it can be seen at my github here https://github.com/CharlieGreenman/Gulp-with-foundation-and-sass
Thank you, and any help would be more than appreciated!
I wrote a Gulp plugin that simplifies your includes by allowing you to add some arbitrary paths to resolve includes and extends to, so you don't have to worry so much about relative pathing. Take a look: https://github.com/tomlagier/gulp-jade-modules
Turns out it was really simple. There were one thing I was doing wrong
I was using includes ../includes/head instead of include ../includes/head (using includes actually worked for me in grunt, upon further research I saw I was using it wrong for gulp.).
I have a library lib.js that I want to create from lib/a.js and lib/b.js and to be able to use it from a script client.js using var a = require('lib/a.js'); and that it works when I just include the compiled lib.js library before client.js (therefore, lib.js has to declare a require function that knows about lib/a.js)
I guess I have to use external and alias but I am not sure what is the proper way to do it
Also, is it possible to have a Gulp file that creates all the alias automatically for the folders in my library? eg. creates an alias for all the files in the lib/ dir?
Here are a couple of gulp tasks that would help to build your common lib.js and the client.js bundles separately.
Note that you have to tell browserify to b.require() lib/*.js when bundling lib.js, and you have to tell it to b.external() the libraries that will be loaded separately when bundling client.js
var path = require('path');
var gulp = require('gulp');
var browserify = require('browserify');
var concat = require('gulp-concat');
var transform = require('vinyl-transform');
gulp.task('build-lib', function () {
// use `vinyl-transform` to wrap around the regular ReadableStream returned by b.bundle();
// so that we can use it down a vinyl pipeline as a vinyl file object.
// `vinyl-transform` takes care of creating both streaming and buffered vinyl file objects.
var browserified = transform(function(filename) {
// basename, for eg: 'a.js'
var basename = path.basename(filename);
// define the exposed name that your client.js would use to require();
// for eg: require('lib/a.js'); // -> exposed name should be 'lib/a.js'
var expose = 'lib/' + basename;
return browserify(filename)
.require(filename, { expose: expose})
.bundle();
});
return gulp.src(['./lib/*.js'])
.pipe(browserified)
.pipe(concat('lib.js'))
.pipe(gulp.dest('./dist'));
});
gulp.task('build-client', function () {
var browserified = transform(function(filename) {
// filename = './client.js'
// let browserify know that lib/a.js and and lib/b.js are external files
// and will be loaded externally (in your case, by loading the bundled lib.js
// for eg: <script src='dist/lib.js'>)
return browserify(filename)
.external('lib/a.js')
.external('lib/b.js')
.bundle();
});
return gulp.src(['./client.js'])
.pipe(browserified)
.pipe(gulp.dest('./dist'));
});
gulp.task('default', ['build-lib', 'build-client']);
Are you looking for external requires?
To use with gulp-browserify, check the README
.on('prebundle', function(bundle) {
bundle.external('domready');
bundle.external('react');
})
Should work with bundle.require as well.