Browserify-shim does not resolve dependencies

I want to combine bootstrap.js and jquery.js (both installed with npm) into a vendors.js file, but still use jquery by calling require('$')

. So I created a 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 config 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 set up my shims in gulp / utilities / shim-config.js

'use strict';

module.exports = {
  'jquery'    :  '$',
  'bootstrap' :  { 'depends': { 'jquery': 'jQuery'} }
};

      

but after running the task, I get a file where bootstrap goes before jquery, so it throws Uncaught Error: Bootstrap JavaScript requires jQuery

I added

"browserify": {
    "transform": [
        "browserify-shim"
    ]
}

      

before package.json but it didn't help. It seems to me that the browser does not apply this transformation, because if I replace .transform(browserifyShim)

with .transform(function() { throw new Error("OLOLO"); })

, the task still works.

+3


source to share


3 answers


I have used scrolling and shimming wrong.

Fist is .transform(browserifyShim)

not required and it is incorrect syntax for converting calls from code in general.

Second, the conversion is working fine, all I need to do is just create a vendors.js file and require a reload in it with require('bootstrap')

. Then specify vendors.js as the entry point for the bulld-frontend: vendors function:



var build = browserify({
  basedir: 'sources/client/js'
  entries: [
  './vendors.js'
  ]
});

      

and it works.

+5


source


Here's what worked for me, using browser scrolling and listing all vendor libraries in the package.json file along with all its dependencies and exporting in the browser scroll box.

"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 in my gulpfile.js, I have the following functions to create a provider package.

// 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;
}

      

+2


source


Tried what Thorin wrote. But no luck. Still complaining that jQuery is undefined.

Just rant a little. This is all a modular need craze, but the tool is confusing and lets you say 1 step forward and then 3 steps back. Are we done with the hardcoding script tag again?

OK, enough ranting. This is how I can work with jQuery and ANY jQuery.

FIRST THING - Only one thing is required for jQuery and any related plugin: $ / jQuery, then everything will work. So why require ("jquery") and require ("bootstrap") (and if you need more, you hardcode each one in js as well as your package. Json - sounds fun?!?)

I just use conversation and good old guide again.

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 look at bower.json. And whenever you add any prints through the gazebo. This will lead to plugging and feeding.

The bundle.js file is generated from the gulpfile.js file

 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 json package

 "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 show you the modal bootstrap code.

Of course (in Angular) you really only need to call $ from your directive (not even in a component).

Hope for this help.

PS this will soon fall into a generator-generator (generator-ngf2). For more information visit my website at http://panesjs.com .

0


source







All Articles