In RequireJS - there cannot be a jQuery name alias in the path

I require Noob. When I use "require.config" and include a jQuery path with a name other than jQuery, the results are not as expected.

Here is a very simple example to help explain my problem.

File structure

root β”œβ”€β”€ Index.htm └── scripts β”œβ”€β”€ libs β”‚  β”œβ”€β”€ jquery-1.7.1.js β”‚  └── require.js β”œβ”€β”€ main.js └── someModule.js 

index.htm

 <html> <head> <title>BackboneJS Modular app with RequireJS</title> <script data-main="scripts/main" src="scripts/libs/require.js"></script> </head> <body> <h3>BackboneJS is awesome</h3> </body> </html> 

Here links to script tags are required in / libs scripts. If necessary, the JavaScript file starts with the name main.js in the scripts directory.

main.js

 require.config({ "paths": { "mod1": "someModule" } }); require(["mod1"], function (sm) { console.log(sm.someValue); }); 

In my experience, β€œmod1” can be anything if it refers to the same thing in the require.config path and in the require method.

someModule.js

 define([], function () { console.log(); return { someValue: "abcd" }; }); 

For completeness only, I have included someModule.js

Perceived inconsistency occurs when I turn on jQuery.

In the next main.js, I added jQuery to the configuration and require method.

Main.js

 require.config({ "paths": { "jquery": "libs/jquery-1.7.1" ,"mod1": "someModule" } }); require(["mod1", "jquery"], function (sm, $) { console.log(sm.someValue); console.log($); }); 

With optional jQuery, everything seems to be still working. "Console.log ($)" writes a jQuery function.

Now the kicker. In the following code, I change "jquery" to "jqueryA" in both paths and require

 require.config({ "paths": { "jqueryA": "libs/jquery-1.7.1" ,"mod1": "someModule" } }); require(["mod1", "jqueryA"], function (sm, $) { console.log(sm.someValue); console.log($); }); 

Now "console.log ($)" writes null.

Should this be expected? Is there a reason why the name should be jquery, but for mod1 could it be anything?

I can get around this without a problem, but this problem seems strange. I know that I can use the combined RequireJS and jQuery file, but when jQuery has an update, I don’t want it to depend on RequireJS to include the new jQuery.

+6
source share
3 answers

In jQuery 1.7, they decided to support AMD loading. To do this, it defines a module called "jquery" that returns a reference to the jQuery object. When you define your jquery path with a different name (for example, "jqueryA"), it doesn't break as much as you think.

A jquery script always defines itself as a module named "jquery" that is registered with a requirement for your application. When you named your path the shortcut "jquery" and "jquery", it was loaded as a dependency. The requirement did refer to the jquery module defined by jquery-1.7.1.js, which returns the correct link. When you name the shortcut of your jqueryA module, you are now linking to the undefined link, because the jquery script itself does not return the link except through a module named "jquery". This is stupid, I know.

The jquery script defines the module as "jquery" and expects you to simply specify it as "jquery". If you want to refer to it as a different name (and as a bonus, so that it does not contradict other loaded jquery libraries), use this method:

Use requirejs and jquery without clobbering global jquery?

+9
source

Here's my implementation-based workaround, I read Require.JS 2.1.0:

 define.amd.jQuery = false; require.config({ ... shim: { "jQuery-1.8.2": { exports: "jQuery" } } ... }); 
+4
source

I believe that I have found the answer to my problem.

Optionally call AMD define () to register the module https://github.com/documentcloud/underscore/pull/338#issuecomment-3253751

Here is a quote from the previous link. Although this applies to underscores, I believe that this applies to jQuery as well.

all AMD loaders allow you to map the module identifier to a partial path, usually the configuration is called "paths", so do what you want:

requirejs.config ({paths: underscore: 'js / libs / underscore-1.2.3.min'}}); require (['underscore'], function () {}); Since underlining is used by other modules of a higher level, such as trunk, a common dependency name should be used to convey a general dependency on an underscore, and it makes sense to call this "underlining" dependencies. Path configuration provides a way to map to the specific URL that you want to use for this dependency.

It says here that the problem with AMD and named modules is described very well.

AMD Modules with Named Names. So much pain for what benefit? http://dvdotsenko.blogspot.com/2011/12/amd-modules-with-named-defines-so-much.html

Quote from the link above

If the only way to use the module correctly is to force end-Developer to hard-write its name in the configuration file, on (in this respect only) why time, effort and hard-writing the name in the module in the first place (not to mention the reason for grief those developers who need to download the module under a different name / from alternative sources)?

In this post, James Burk recommends not using the name module. https://github.com/jrburke/requirejs/wiki/Updating-existing-libraries#wiki-anon

Normally you should not register a named module, but instead register as an anonymous module:

This allows users of your code to rename your library with a name suitable for their project layout. It also allows you to map your module to a dependency name that other libraries use. For example, Zepto.js can be mapped to execute a module for the jquery module id.

There are some notable exceptions that are registered as named modules:

β€’ jQuery β€’ underline

Exception suck. Exceptions make it difficult for noobs to work.

+2
source

Source: https://habr.com/ru/post/905152/


All Articles