I have been given a template to work from by a client that has some 28 different jquery plugins that the client wants to use (e.g. ditching them not an option).
However I really want to use browserify to modularise my code, but short of trying to shim all 28 plugin and thir dependancy I can't work out how I would do that and not have to load JQuery for browserify and globally.
I tried doing this:
window.JQuery = require('jquery')
window.$ = window.JQuery
And this:
var globals = function(){
window.JQuery = require('jquery')
window.$ = window.JQuery
}
globals();
But neither seem to work and all the plugins throw an error. Does anyone now how I might make it work?
This is a pretty good way to do it, I think.
npm install jquery
npm install browserify-shim
Put this line in your package.json:
browserify-shim" : {
"./node_modules/jquery/dist/jquery.js" : "$"
}
So on the server, your usual require('jquery') will point to the node_modules spot. When you run browserify, it will set window.$ to the same code (you could also use jQuery). Also, if you did want to shim those plugins, just add them like this:
"browserify-shim" : {
"./node_modules/jquery/dist/jquery.js" : "jQuery",
"./plugins/bs_modal.js" : {
"depends": [ "./node_modules/jquery/dist/jquery.js" ]
}
}
or, cleaner:
"browser" : {"jquery": "./node_modules/jquery/dist/jquery.js"},
"browserify-shim" : {
"jquery" : "jQuery",
"./plugins/bs_modal.js" : {
"depends": [ "jquery" ]
}
}
I have been using the line below, to get bootstrap and jquery to be browserified:
window.$ = window.jQuery = require('jquery');
Related
I'm attempting to run Jest tests for a JS file that includes some jQuery. The jQuery code is unrelated and not being tested, but cannot be removed for other reasons. However my test suite will not run because of the jQuery $. I've been attempting various efforts to either mock or include jQuery somehow in the Jest environment. I'm using webpack's ProvidePlugin to make jQuery available to all modules in my app and I'm not sure if this is causing issues with $ potentially.
I have the following (psuedo) JS code in myfile.js:
export const myFunc = () => {
return 'things';
}
// legacy jQuery code which can't be removed
$('.some-element').on('click', doSomethingUnrelated);
I'm intending to test myFunc() in myfile.test.js like so:
import { myFunc } from './myfile';
describe('my file', () => {
it('returns things', () => {
// some assertions
})
})
webpack.common.js:
new webpack.ProvidePlugin({
$: 'jQuery',
jQuery: 'jquery',
...
})
When i run the jest test like this, it fails with the message: $ is not defined, which seems fair. Taking some ideas from this Jest issue here: https://github.com/facebook/jest/issues/708 I've tried:
jest.config.js:
module.exports = {
setupFiles: ['./src/jest-setup-before.js'],
...
}
jest-setup-before.js:
// window.$ = require('jquery');
//
// import $ from 'jquery'
// global.$ = global.jQuery = $;
//
// global.jQuery = require('jquery');
// global.$ = global.jQuery;
console.log($) // {}
I've also tried the above using setupFilesAfterEnv instead of setupFiles to see if installing jquery before tests run would help, but it didn't. These attempts all result in TypeError: $ is not a function.
I've also tried mocking jquery according to the docs: https://jestjs.io/docs/en/manual-mocks#mocking-node-modules by creating a __mocks__ directory adjacent to node_modules and creating an empty jquery.js file. I've also tried in jquery.js: jest.mock('jquery') although according to the docs I shouldn't have to.
Just seems like one of those scenarios I'm throwing anything I can at this problem without understanding fully, I'm still pretty new to Jest so any help is greatly appreciated here. Thanks!
I'm stuck trying to call the bootstrap's jQuery plugins, like popover, tooltip, modals, ...
I'm using webpack and this is my ES6 javascript:
import $ from 'jquery';
//import Bootstrap from 'bootstrap-sass';
//import Bootstrap from 'bootstrap-loader';
import Bootstrap from '../vendor/bootstrap.min.js';
class Test {
constructor () {
$('[data-toggle="tooltip"]').tooltip({ html: true });
}
}
I've tried to install bootstrap with npm, but after that i wasn't sure which one node-modules i had to import (like you can see in commented lines in the imports). So, i thought to import directly the bootstrap.min.js.
The fact is that i still have an error (independently if i try with popover/modals/tooltip) like this in my app.js that is my javascript generated from the webpack:
Uncaught TypeError: (0 , _jquery2.default)(...).tooltip is not a function
Like i say, i'm stuck here.
Last thing, the boostrap CSS works correctly thanks to this:
gulp.task('bootstrap-fonts', function() {
return gulp.src('node_modules/bootstrap-sass/assets/fonts/bootstrap/*')
.pipe(gulp.dest('./app/assets/fonts/bootstrap'));
});
gulp.task('dev', ['css', 'bootstrap-fonts', 'browser-sync', 'webpack'], function () {
gulp.watch('src/scss/**/*.scss', ['css']);
gulp.watch('src/js/**/*.js', ['webpack']);
gulp.watch('app/*.html', ['bs-reload']);
});
Because the bootstrap library depends on jQuery,
you should try to add the following plugin to the 'plugins' array in your webpack.config.js so that the bootstrap module will use the jQuery global object:
new webpack.ProvidePlugin({
$: "jquery",
jQuery: "jquery",
"window.jQuery": 'jquery'
}),
This plugin will actually injects the 'jquery' module in any other module that ask for him (means, every module that use the objects jQuery or $ or window.jQuery), and bootstrap is one of them.
I'm trying to get some jQuery plugins to work with browserify. I have my package.json setup like this:
"browser": {
"jquery": "./client/js/vendors/jquery-2.2.2.min.js",
"jquery-validation": "./client/js/vendors/jquery.validate.js"
},
"browserify-shim": {
"jquery": "global:$"
},
However, when I require('jquery-validation'), I get cannot read property fn of undefined as it relates to this plugin. I'm trying to also have it so that $ will be global as it's used all over, without having to require it.
I've seen so many different articles and configs for this, but nothing seems to work.
Any suggestions or clarity would be greatly appreciated.
EDIT:
I also sometimes get Uncaught Error: Cannot find module 'jquery'
You don't need to shim jquery, it's conpatible with node yoo can simply install it with npm install jquery --save and make var $= require("jquery") in your code.
Yo do need to shim jquery.validate.
package.json:
{
"browser":{
"jquery-validation":"./node_modules/jquery-validation/dist/jquery.validate.js"
},
"browserify-shim":{
"jquery-validation":{
"depends":[
"jquery:jQuery"
]
}
},
"browserify":{
"transform":[
"browserify-shim"
]
},
"dependencies":{
"jquery":"^2.0.0",
"jquery-validation":"^1.15.1"
}
}
Note: jquery.validate depend on jQuery version 2.0^ ( you can see in the package.json file of the jquery-validation's npm package ) so you have to set dependency on jquery ^2.0 in your project otherwise jquery-validation will load he's own version of jQuery and integration will not work.
It seems like you have typo, you should call require('jquery-validation') instead of require('jquery-validate')
I am trying to use a plugin that is in /js/lib/stellar.jquery.js:
var $ = require('jquery');
require('./lib/stellar.jquery')
$(function(){
$.stellar();
});
When I run this though I get jQuery is not defined. I think the stellar jQuery plugin is loading before the jq library. At the bottom of the stellar plugin there's this code:
...
// Expose the plugin class so it can be modified
window.Stellar = Plugin;
}(jQuery, this, document));
Changing "jQuery" to "$" does not work either, gives "$ is not defined"
There is not any need to specify order for dependencies.
Because neither jQuery nor your plugin support CommonJS modules, you need to shim them to make them compatible with the browserify modules concept.
npm install browserify-shim --save-dev
add alias for jQuery and your plugin to your package.json (optional, but recommended)
"browser":{
"customPlugin": "path/to/custom/plugin",
"jquery": "./node_modules/jquery/dist/jquery.js"
}
add browserify shim transformation to enable shimming by adding to your package.json
"browserify": {
"transform": [
"browserify-shim"
]
}
configure shims
"browserify-shim": {
"jquery" : "jQuery",
"customPlugin" : { "depends": [ "jquery:jQuery" ] },
}
Consider, in dependencies configuration before colon you should specify file name, NOT SHIMMED MODULE NAME!!!
after colon you should specify identifier, which is expected by your module in global namespace.
Then, require your plugin to initialize it's code before usage
'use strict';
require('customPlugin');
var $ = require('jQuery');
$('.some-class-selector').myCustomPlugin();
Seems like another solution is to add :
global.jQuery = require("jquery")
So I know how to manually fix this but it's annoying!
I included bootstrap dropdown.js and at the end of the function is
}(jQuery);
Inside my shim I set jquery as a dependency
'bootstrap': {
"exports": 'bootstrap',
"depends": {
"jquery": '$'
}
},
It seems like this is the only way to use $, but since the dropdown has jQuery at the end the console shows
ReferenceError: jQuery is not defined
}(jQuery);
Changing it to }($); works.
So my question is does anyone have any idea to better do this without manually doing it, or is manually editing the script the best?
You can use global.jQuery = require("jquery")
This is my shim :
},
"plugin": {
"exports": "plugin",
"depends": [
"jquery: $",
"bootstrap: bootstrap"
]
}
and inside of plugin.js :
var $ = require('jquery')(window);
global.jQuery = require("jquery");
var bootstrap = require('bootstrap');
var plugin = require('plugin');
plugin();
it solve my problem. Hope it helps. :)
Shim
"./node_modules/jquery/dist/jquery.js": {
"exports": "$"
}
requiring
var jQuery = $ = require('$');
This should cover both plugins that use
(function($){
$.fn.function_name = function(x){};
})($);
as well as
(function($){
$.fn.function_name = function(x){};
})(jQuery);
I don't think my solution is anywhere near optimal or ideal and it doesn't answer my question but if anyone has this issue just do it this way, you can get it working possibly as a temporary solution to get things going without stagnating on your project.
Most if not all jQuery plugins are written with a self invoking function like this.
(function($){
$.fn.function_name = function(x){};
})(jQuery);
I simply went into the plugin itself and changed (jQuery) to ($)
(function($){
$.fn.function_name = function(x){};
})($);
If you're still having problems, make sure you have a shim defined in your package.json file and you are including the jQuery plugin with a require statement.