Reputation: 6710
I want to combine bootstrap.js & jquery.js (both installed with npm) into vendors.js file but still be able to use jquery by calling require('$')
.
So I created gulp task:
'use strict';
var gulp = require('gulp'),
helpers = require('./../utilities/gulp-helpers'),
source = require('vinyl-source-stream'),
plumber = require('gulp-plumber'),
browserifyShim = require('browserify-shim'),
browserify = require('browserify');
gulp.task('bulld-frontend:vendors', function(done) {
var build = browserify({
entries: [
'jquery',
'bootstrap'
]
});
build
.transform(browserifyShim)
.require('jquery')
.bundle()
.pipe(source('vendors.js'))
.pipe(gulp.dest('build/public/js'))
.pipe(plumber({
errorHandler: helpers.logError
}));
done();
});
then added configuration to package.json
"browser": {
"bootstrap": "./node_modules/bootstrap/dist/js/bootstrap.js",
"jquery": "./node_modules/jquery/dist/jquery.js"
},
"browserify-shim": "./gulp/utilities/shim-config.js",
},
and finally configure my shims in gulp/utilities/shim-config.js
'use strict';
module.exports = {
'jquery' : '$',
'bootstrap' : { 'depends': { 'jquery': 'jQuery'} }
};
but after running task I receive file, where bootstrap goes prior to jquery, so it throws Uncaught Error: Bootstrap's JavaScript requires jQuery
I added
"browserify": {
"transform": [
"browserify-shim"
]
}
to package.json but it didn't help. It seems to me, that browserify never applies this transformation, because if I replace .transform(browserifyShim)
with .transform(function() { throw new Error("OLOLO"); })
task is still working.
Upvotes: 3
Views: 5469
Reputation: 948
Tried what Torin posted. But no luck. Still complain about jQuery is undefined.
Just a bit of ranting. All this craze about doing modular require but the tooling is confusing and let say, 1 step forward then 3 steps back. We ended up doing hardcoding script tag again?
OK, enough ranting. This is how I get jQuery and ANY jQuery plugin to work.
FIRST THING - jQuery and any associated plugin only required one thing - $ / jQuery then everything will work. So why bother to require('jquery') and require('bootstrap') (and if you need more, you hard coding every single one of them in your js as well as in your package.json - sounds fun?!?)
I just re-use bower and the good old wiredep.
My HTML:
<head>
<!-- bower:css -->
<!-- endinject -->
<!-- inject:css -->
<!-- endinject -->
</head>
<body>
<app></app>
<!-- bower:js -->
<!-- endinject -->
<script src="bundle.js"></script>
OK, this is the classic wiredep setup. You just need to get the gulp file to watch bower.json. And whenever you add any deps via bower. This will get wire up and serve.
The bundle.js file is generate from within the gulpfile.js
gulp.task('bundle' , ['wiredep'] , function()
{
browserify({debug: true})
.transform(
babelify.configure({stage: 0})
)
.transform(
stringify(['html'])
)
.require(
'./app/index.js', {entry: true}
)
.bundle()
.on('error' , errorHandler)
.pipe(source('bundle.js')) // vinyl-source-stream
.pipe(buffer()) // vinyl-buffer
.pipe(sourcemaps.init({loadMaps: true})
.pipe(sourcemaps.write('./'))
.on('error' , errorHandler)
.pipe(gulp.dest('./dev'));
});
Now in my package json
"browser": {
"jquery": "./bower_components/jquery/dist/jquery.min.js",
"bootstrap": "./bower_components/bootstrap/dist/jst/bootstrap.min.js",
"mdbootstrap":"./bower_components/mdbootstrap/js/mdb.min.js"
},
"browserify": {
"transform": ["browserfiy-shim"]
},
"browserify-shim": {
"jquery": "global:$"
}
The last part is the key `global:jQuery" or "global:$"
Then in your js file (I am using Angular with ng-forward)
'use strict';
import 'bableify/polyfill';
import 'reflect-metadata';
import 'angular';
import 'angular-ui-router';
import {bootstrap} from 'ng-forward';
import {App} from './components/app/app';
import config from './config/config';
// try to test if we get the bootstrap
console.log($.fn.modal);
bootstrap(App , ['ui.router',config.name]);
You should see the console will show you the bootstrap modal code.
Of course, (in Angular) you should really only call the $ from within your directive (not even in the component).
Hope this help.
P.S. this will package into a yeoman generator (generator-ngf2) shortly. Check my website http://panesjs.com for more info.
Upvotes: 0
Reputation: 793
Here is what worked for me, using browserify-shim and stating all of the vendor libraries in the package.json file along with all of it's dependencies and exports within the 'browserify-shim' field.
"browser": {
"modernizr": "./app/assets/javascripts/vendor/modernizr.js",
"jquery": "./bower_components/jquery/jquery.js",
"angular": "./bower_components/angular/angular.min.js",
"angular-touch": "./bower_components/angular-touch/angular-touch.js",
},
"browserify-shim": {
"modernizr": {
"exports": "Modernizr"
},
"jquery": "$",
"angular": {
"depends": "jquery",
"exports": "angular"
},
"angular-touch": {
"depends": "angular",
"exports": "angular.module('ngTouch')"
}
}
Then on my gulpfile.js i have the following functions to generate the vendor bundle.
// function to fetch the 'browserify-shim' json field from the package.json file
function getNPMPackageBrowser() {
// read package.json and get dependencies' package ids
var packageManifest = {};
try {
packageManifest = require('./package.json');
} catch (e) {
// does not have a package.json manifest
}
return packageManifest['browserify-shim'] || {};
}
function vendor() {
var deferred = q.defer(),
b = browserify({ debug: true }).transform('browserify-shim'),
libs = getNPMPackageBrowser(),
lib;
plugins.util.log('Rebuilding vendor JS bundle');
// recursively add all of the vendor libraries as a --require or bundle.require() to browserify
for (lib in libs) {
if (libs.hasOwnProperty(lib)) {
b.require(lib);
}
}
b.bundle()
//Pass desired output filename to vinyl-source-stream
.pipe(source('vendor.js'))
.pipe(gulp.dest(publicDir + '/assets/javascripts'))
.on('end', deferred.resolve)
.on('error', handleError);
return deferred.promise;
}
Upvotes: 2
Reputation: 6710
I used browserify and shims in wrong way.
Fist, .transform(browserifyShim)
is not needed and this is wrong syntax to call transformations from code at all.
Second, transformation is working fine, all I needed were just create vendors.js file and require bootstrap in it with require('bootstrap')
. Then specify vendors.js as entry point of bulld-frontend:vendors task:
var build = browserify({
basedir: 'sources/client/js'
entries: [
'./vendors.js'
]
});
and it is working.
Upvotes: 5