3

How can I import jQuery as the dependency for bootstrap in ES6?

I tried with:

import {$,jQuery}  from 'jquery';
import bootstrap from 'bootstrap';

But I always get this error:

transition.js:59 Uncaught ReferenceError: jQuery is not defined

Which points to this file:

/* ========================================================================
 * Bootstrap: transition.js v3.3.7
 * http://getbootstrap.com/javascript/#transitions
 * ========================================================================
 * Copyright 2011-2016 Twitter, Inc.
 * Licensed under MIT (https://github.com/twbs/bootstrap/blob/master/LICENSE)
 * ======================================================================== */


+function ($) {
  'use strict';

  // CSS TRANSITION SUPPORT (Shoutout: http://www.modernizr.com/)
  // ============================================================

  function transitionEnd() {
    var el = document.createElement('bootstrap')

    var transEndEventNames = {
      WebkitTransition : 'webkitTransitionEnd',
      MozTransition    : 'transitionend',
      OTransition      : 'oTransitionEnd otransitionend',
      transition       : 'transitionend'
    }

    for (var name in transEndEventNames) {
      if (el.style[name] !== undefined) {
        return { end: transEndEventNames[name] }
      }
    }

    return false // explicit for ie8 (  ._.)
  }

  // http://blog.alexmaccaw.com/css-transitions
  $.fn.emulateTransitionEnd = function (duration) {
    var called = false
    var $el = this
    $(this).one('bsTransitionEnd', function () { called = true })
    var callback = function () { if (!called) $($el).trigger($.support.transition.end) }
    setTimeout(callback, duration)
    return this
  }

  $(function () {
    $.support.transition = transitionEnd()

    if (!$.support.transition) return

    $.event.special.bsTransitionEnd = {
      bindType: $.support.transition.end,
      delegateType: $.support.transition.end,
      handle: function (e) {
        if ($(e.target).is(this)) return e.handleObj.handler.apply(this, arguments)
      }
    }
  })

}(jQuery);

Any ideas?

EDIT:

my gulp file:

var gulp = require('gulp');
var browserify = require('browserify');
var babelify = require('babelify');
var source = require('vinyl-source-stream');
var gutil = require('gulp-util');

gulp.task('es6', function() {
    browserify({
        entries: 'js/app.js',
        debug: true
    })
    .transform(babelify, { presets: ['es2015'] })
    .on('error',gutil.log)
    .bundle()
    .on('error',gutil.log)
    .pipe(source('compile.js'))
    .pipe(gulp.dest('js'));
});

gulp.task('default', ['es6']);

EDIT 2:

package.json:

{
  "name": "es6",
  "version": "1.0.0",
  "description": "",
  "main": "index.js",
  "scripts": {
    "test": "echo \"Error: no test specified\" && exit 1"
  },
  "author": "",
  "license": "ISC",
  "devDependencies": {
    "babel-preset-es2015": "^6.16.0",
    "babelify": "^7.3.0",
    "browserify": "^13.1.0",
    "gulp": "^3.9.1",
    "gulp-uglify": "^2.0.0",
    "gulp-util": "^3.0.7",
    "pump": "^1.0.1",
    "vinyl-source-stream": "^1.1.0"
  },
  "browser": {
    "jquery": "./node_modules/jquery/dist/jquery.js",
  },
  "browserify-shim": {
    "jquery": "$", // or change it to jQuery
  },
  "browserify": {
    "transform": [
      "browserify-shim"
    ]
  }
}

error:

Starting 'build'... events.js:160 throw er; // Unhandled 'error' event ^

Error: SyntaxError: Unexpected token } in JSON at position 526 while parsing json file

Run
  • 54,938
  • 169
  • 450
  • 748
  • 1
    What you are using in `import` is an ES6 feature called "destructuring": it looks inside the object you are importing for two properties named `$` and `jQuery`. The problem you have is that the actual object imported is the `$` one. Try this instead: `import $ from "jquery"; window.jQuery = $;` – MarcoL Oct 10 '16 at 09:07
  • thanks. i have tried that but still the same error. – Run Oct 10 '16 at 09:16
  • 1
    THen probably you have to say to `webpack` to make available the `jQuery` variable for other modules in the global namespace as shown in the answer of @galkowskit – MarcoL Oct 10 '16 at 09:38

5 Answers5

4

I've tried this answer and it worked.

// webpack.config.js
module.exports = {
    ...
    plugins: [
        new webpack.ProvidePlugin({
           $: "jquery",
           jQuery: "jquery"
       })
    ]
};
Community
  • 1
  • 1
dhqvinh
  • 337
  • 4
  • 9
  • This works really well! If you are interested how to achieve this in Angular 6 see these links: https://codeburst.io/customizing-angular-cli-6-build-an-alternative-to-ng-eject-a48304cd3b21 , https://github.com/sarbull/dapulse, Info and implementation. – Francisco Daniel Nov 03 '18 at 14:21
2

In general the destructuring you are doing in the import is not right, as the $ or jQuery object is the main one:

import $ from 'jquery';

// or
import jQuery from 'jquery'

In your case you are dealing with a module (boostrap-transition) which does want jQuery in the global scope to be used. I had a similar issue some time ago with the materialize module too on this thing.

If you are using webpack you can follow @galkowskit answer steps.
In case you are using browserify instead, what you need is a browserify transform as the follow:

"browser": {
  "jquery": "./node_modules/jquery/dist/jquery.js",
},
"browserify-shim": {
  "jquery": "$", // or change it to jQuery
},
"browserify": {
  "transform": [
    "browserify-shim"
  ]
}

You can put this inside your package.json file: when Gulp is going to call browserify it will read your package.json for configuration tips and execute this shim for jQuery.

MarcoL
  • 9,829
  • 3
  • 37
  • 50
  • thanks but i got an error. did i put it right? please see my edit 2. thanks. – Run Oct 10 '16 at 10:54
  • 1
    Remove the comment `// or change it to jQuery`. I've left it there as suggestion, but the JSON parser doesn't like it. – MarcoL Oct 10 '16 at 10:56
1

In Webpack I usually use (webpack.config.js):

externals: {
  jquery: "jQuery"
}

And then:

import jQuery from 'jQuery';

You could also try:

import * as jQuery from 'jQuery';
Tomasz Gałkowski
  • 1,841
  • 4
  • 24
  • 39
  • i don't use webpack. i use gulp to compress the files. – Run Oct 10 '16 at 09:48
  • What are you using as your module bundler? I think apart from minification with gulp you will need something that can make use of import/export syntax of ES6. Webpack, Browserify or System.js, etc. I don't think browsers suport ES6 modules just yet. – Tomasz Gałkowski Oct 10 '16 at 09:49
  • i use Browserify, gulp – Run Oct 10 '16 at 09:50
  • `import * as jQuery from 'jQuery';` still gives me the same error. – Run Oct 10 '16 at 09:50
  • I am using Webpack in Angular 4 project, tried this solution but it didn't work. – Sami-L Nov 17 '17 at 12:24
1

If you are using curley bracket in es6 you are saying you want only that segment from several segment this module returns. Jquery expose only one thing so you could do: import $ from 'jquery'; Or import jQuery from 'jquery'; It will always expose to one default variable

Adidi
  • 5,097
  • 4
  • 23
  • 30
0
import jQuery from 'jquery';

or

import $ from 'jquery';
Bamieh
  • 10,358
  • 4
  • 31
  • 52