I have a file called "lib.jquery.js" (all libraries are starting with "lib." and not reusable application modules are starting with "app.") in my baseUrl directory, and a module definition:
define([
"lib.jquery"
],
function(
jQuery
){
console.log(jQuery) // undefined
})
But jQuery here is undefined because jQuery module name is hardcoded inside it as "jquery" but not "lib.jquery". How do I configurate RequireJS correctly to make all loading modules check "lib.jquery" file when requesting "jquery" or force jQuery module to be named "lib.jquery"?
The jquery script defines the module as 'jquery' and expects that you will simply reference it as 'jquery'. This is done because one should not load 2 jquery files of different versions.
Workaround would be put the lib.*.js files into a separate directory called lib.
define(['lib/jquery'], function (jQuery) {
});
I have found the solution here: Use requirejs and jquery, without clobbering global jquery?
Renamed file lib.jquery.js to lib.jquery-core.js
Created file lib.jquery.js with "jquery loader module":
define(['lib.jquery-core'], function () {
return jQuery.noConflict(true);
});
Now it's working as intended to. Hardcoding names is evil.
Related
I'm using Webpack 4 in a Codeigniter project. A lot of my Javascript code still depends on jQuery (installed through npm), so I have this Webpack configuration:
plugins: [
new webpack.ProvidePlugin({
$: 'jquery',
jQuery: 'jquery',
'window.jQuery': 'jquery',
}),
It works, but I'm planning to ditch jQuery, or at least to depend less on it, so instead of importing it globally, I would like to import it only in the modules where it's needed.
I tried removing the above config and added it in a module:
import { $, jQuery } from 'jquery';
import Dropzone from 'dropzone';
When loading the page I receive this error in the console:
myDropzone.js:95 Uncaught TypeError: Object(...) is not a function
at Object.<anonymous> (myDropzone.js:95)
at r (bootstrap:76)
at t (bootstrap:43)
at bootstrap:134
at bootstrap:134
The code causing the error:
$('.dropzone').each(function () { // <--- this line
$(this).dropzone(config);
});
In the console I tried checking for $ and jQuery and the first one works fine, but with jQuery I get an error saying that it's not defined
Ok, I am pretty sure the following happens:
You are loading the jQuery dropzone plugin somewhere high up in the dependencies tree, probably loaded by some other package. The plugin expects to find the jQuery object in the global scope, in order to attach itself to it (hence giving you access to the $().dropzone method, see here ). By using the ProvidePlugin when the dropzone plugin tries to attach itself onto the jQuery object, there is no problem
However since you are now removing the ProvidePlugin the dropzone plugin never manages to attach itself and so there is no $().dropzone method available for use, so you get that error
Long story short, as long as you are depending on external code that assumes that jQuery is loaded in the global scope, you cannot truly eliminate the usage of webpack.ProvidePlugin, unless of course you directly modify the source code of those dependencies.
Try using
import $ from 'jquery';
window.jQuery = $;
window.$ = $;
Not sure if this has been asked already but I am just wondering if importing a dependency using RequireJS to one file and then importing that file to another means the second file has to import the same dependency as the first file.
example -
file A
define([
'jquery'
],function($) {
//jquery thing here
}
File B
define([
'A'
],function(A) {
// do some jquery thing here
}
or
define([
'jquery','A'
],function($,A) {
// do some jquery thing here
}
It is good modularization practice to have each module list its own dependencies explicitly rather than silently depend on a module being loaded through an intermediary. So your module B should take the second form you suggested for it: define(['jquery', 'A'], function ($, A) {....
Now, strictly speaking, you could have B only require A and you would be able to use jQuery in B without B having an explicitly dependency on jQuery. This is doable because jQuery, even when it is loaded as an AMD module, by default leaks $ and jQuery into the global space just like it does when it is loaded outside RequireJS. However, it is not good practice. You should not rely on this though unless you have a substantial reason to do so and document it very verbosely.
You will have to use the third option, because otherwise $ will be undefined in the module B. But this doesn't mean RequireJS will import jQuery twice internally, it will just pass you the $ variable.
define([
'jquery','A'
],function($,A) {
// $ was passed as a function argument.
}
I'm getting this error when I browse my webapp for the first time (usually in a browser with disabled cache).
Error: Mismatched anonymous define() module: function (require) {
HTML:
<html>
.
.
.
<script src="//ajax.googleapis.com/ajax/libs/jquery/1.8.0/jquery.min.js"></script>
<script> var require = { urlArgs: "v=0.4.1.32" }; </script>
<script data-main="assets/js/main" src="assets/js/libs/require.js"></script>
<script src="assets/js/ace/ace.js?v=0.4.1.32"></script>
</body>
</html>
JS:
$(function () {
define(function (require) {
// do something
});
});
Anyone know exactly what this error means and why its happening?
source file, a short discussion about it in the github issues page
Like AlienWebguy said, per the docs, require.js can blow up if
You have an anonymous define ("modules that call define() with no string ID") in its own script tag (I assume actually they mean anywhere in global scope)
You have modules that have conflicting names
You use loader plugins or anonymous modules but don't use require.js's optimizer to bundle them
I had this problem while including bundles built with browserify alongside require.js modules. The solution was to either:
A. load the non-require.js standalone bundles in script tags before require.js is loaded, or
B. load them using require.js (instead of a script tag)
In getting started with require.js I ran into the issue and as a beginner the docs may as well been written in greek.
The issue I ran into was that most of the beginner examples use "anonymous defines" when you should be using a "string id".
anonymous defines
define(function() {
return { helloWorld: function() { console.log('hello world!') } };
})
define(function() {
return { helloWorld2: function() { console.log('hello world again!') } };
})
define with string id
define('moduleOne',function() {
return { helloWorld: function() { console.log('hello world!') } };
})
define('moduleTwo', function() {
return { helloWorld2: function() { console.log('hello world again!') } };
})
When you use define with a string id then you will avoid this error when you try to use the modules like so:
require([ "moduleOne", "moduleTwo" ], function(moduleOne, moduleTwo) {
moduleOne.helloWorld();
moduleTwo.helloWorld2();
});
I had this error because I included the requirejs file along with other librairies included directly in a script tag. Those librairies (like lodash) used a define function that was conflicting with require's define. The requirejs file was loading asynchronously so I suspect that the require's define was defined after the other libraries define, hence the conflict.
To get rid of the error, include all your other js files by using requirejs.
Per the docs:
If you manually code a script tag in HTML to load a script with an
anonymous define() call, this error can occur.
Also seen if you
manually code a script tag in HTML to load a script that has a few
named modules, but then try to load an anonymous module that ends up
having the same name as one of the named modules in the script loaded
by the manually coded script tag.
Finally, if you use the loader
plugins or anonymous modules (modules that call define() with no
string ID) but do not use the RequireJS optimizer to combine files
together, this error can occur. The optimizer knows how to name
anonymous modules correctly so that they can be combined with other
modules in an optimized file.
To avoid the error:
Be sure to load all scripts that call define() via the RequireJS API.
Do not manually code script tags in HTML to load scripts that have
define() calls in them.
If you manually code an HTML script tag, be
sure it only includes named modules, and that an anonymous module that
will have the same name as one of the modules in that file is not
loaded.
If the problem is the use of loader plugins or anonymous
modules but the RequireJS optimizer is not used for file bundling, use
the RequireJS optimizer.
The existing answers explain the problem well but if including your script files using or before requireJS is not an easy option due to legacy code a slightly hacky workaround is to remove require from the window scope before your script tag and then reinstate it afterwords. In our project this is wrapped behind a server-side function call but effectively the browser sees the following:
<script>
window.__define = window.define;
window.__require = window.require;
window.define = undefined;
window.require = undefined;
</script>
<script src="your-script-file.js"></script>
<script>
window.define = window.__define;
window.require = window.__require;
window.__define = undefined;
window.__require = undefined;
</script>
Not the neatest but seems to work and has saved a lot of refractoring.
Be aware that some browser extensions can add code to the pages.
In my case I had an "Emmet in all textareas" plugin that messed up with my requireJs.
Make sure that no extra code is beign added to your document by inspecting it in the browser.
Or you can use this approach.
Add require.js in your code base
then load your script through that code
<script data-main="js/app.js" src="js/require.js"></script>
What it will do it will load your script after loading require.js.
I was also seeing the same error on browser console for a project based out of require.js. As stated under MISMATCHED ANONYMOUS DEFINE() MODULES at https://requirejs.org/docs/errors.html, this error has multiple causes, the interesting one in my case being: If the problem is the use of loader plugins or anonymous modules but the RequireJS optimizer is not used for file bundling, use the RequireJS optimizer. As it turns out, Google Closure compiler was getting used to merge/minify the Javascript code during build. Solution was to remove the Google closure compiler, and instead use require.js's optimizer (r.js) to merge the js files.
I am trying to use bootbox (http://bootboxjs.com) with requirejs.
main.html
<script>
var require = {
baseUrl: 'js',
paths: {
"jquery" :['jquery-1.11.0.min'],
"bootbox" :['bootbox.min'],
"bootstrap" :['//netdna.bootstrapcdn.com/bootstrap/3.1.1/js/bootstrap.min']
},
shim:
'bootstrap' :{deps:['jquery']},
'bootbox' :{deps:['bootstrap'],exports: 'bootbox'}
}
}
</script>
<script src="require.min.js"></script>
<script src="myscript1.js"></script>
main.js
define(['bootbox'],function(bootbox){
bootbox.alert("Hello world!"); // working properly
});
myscript1.js
require(['main'],function(){
bootbox.alert("Hello world!"); // not functioning (bootbox is not defined)
});
Normally once bootbox plugin is loaded, we can use bootbox anywhere on the page with this: bootbox.alert("Hello world!"); When using requirejs, I have to pass the bootbox variable and define it everytime when using requirejs in order to use bootbox. I have tried with "exports", but it doesn't seem help.
How can we have the bootbox variable available globally once it is loaded?
Thank you.
Here's the deal. Bootbox detects whether it is running in an AMD loader in place (like RequireJS). If so, it won't export anything into the global space but will instead define itself as an AMD module, to be loaded by an AMD loader.
Tidoo's suggestion of loading Bootbox with a script tag works, if you do it carefully. You'd have to load Bootbox before you load RequireJS, for one thing. Otherwise, it would detect that RequireJS is loaded, determine that it is running with an AMD loader, and define itself as an AMD module. This would cause a mismatched anonymous module error from RequireJS. Another thing is that you'd have to load jQuery outside RequireJS and load it before Bootbox. So that's another script tag.
I'd suggest avoiding that solution by simply modifying your code to add the required dependency:
require(['bootbox', 'main'],function(bootbox){
bootbox.alert("Hello world!");
});
Also, you must not use a shim configuration for Bootbox because it detects whether there is an AMD loader around and calls define by itself if it detects one. A shim configuration is needed only for code that does not call define.
If you want Bootbox to be available globally you should include it manually with a script tag. RequireJS doesn't expose it.
However, I highly recommend against this. The whole idea of dependency frameworks such as RequireJS is that you don't define anything on global scope, but to make your dependencies explicit. This not only allows you to lazy load scripts, but it also makes it possible to later replace dependencies, e.g. for unit testing.
EDIT:
As Louis correctly mentioned Bootbox already has AMD support. If it detects RequireJS (or any other AMD loader) it doesn't expose anything to the global scope, but since it has AMD support you also don't need to shim it.
I am attempting to load jQuery.jstree through RequireJS. You can see the exact source of the plugin here: https://gist.github.com/MeoMix/7882144
As I understand it, jQuery.jstree has three dependecies: jQuery, jQuery UI, and jQuery.cookie.
I begin with by loading my RequireJS shim config and then call an initial 'require' to kick things off:
require.config({
// Set the base URL to the Scripts directory of CSWeb
baseUrl: '/csweb/Scripts/',
shim: {
'jquery-ui': ['jquery'],
'jquery.jstree': ['jquery', 'jquery-ui', 'jquery.cookie'],
'jquery.cookie': ['jquery']
}
});
Here, I define my base URL relative to the root of my JavaScript files. The file jquery.js is located at the baseUrl. I also define dependencies for both plugins. Note: I have tried playing around with more explicit shim declarations including defining exports. I noticed no difference in effect.
After defining my config, I call:
require([
'jquery',
'jquery-ui',
'jquery.cookie',
'jstree/jquery.jstree'
], function () {
'use strict';
});
Doing so yields an error intermittently. Clearly an async-loading issue. The error reads:
Uncaught ReferenceError: jQuery is not defined jquery.jstree.js:978
Line 978 of jquery.jstree is simply where jQuery is passed into the closure to begin initialization of the plugin:
// 978 jquery.jstree.js: })(jQuery);
What am I not understanding here? I don't seem to experience this issue with most of my plugins. Is there something especially crappy about how this jstree plugin was written such that it is giving RequireJS fits? Or am I not understanding a core mechanic of RequireJS shim configuration?
UPDATE 1: It appears that it is something to do with the fact that I load jquery.jstree from a path. If I load another, empty file (jstree/jquery.test) -- I am able to replace the issue. However, if I then move test up a directory such that it is level with the other plugins -- it all loads fine.
The whole path you give to the shim configuration has to match the whole path of the module you require.
You name the shim jquery.jstree but you require it as jstree/jquery.jstree, so RequireJS does not use the shim and thus does not know that the plugin depends on jquery, etc. and so you get intermittent errors.
For things like plugins that I might want to use globally, I prefer to give them a well-known name that I can use throughout my application without worrying about paths. So in your case, I'd fix the problem by adding this to my config:
paths: {
"jquery.jstree": "jstree/jquery.jstree"
}
and I would then require it jquery.jstree.