requirejs, require method conflict

If multiple requirejs scripts are loaded, each requirejs will determine whether the browser has implemented the require and define methods. If the browser already has its own require and define methods, or if a requirejs script has been executed before, the requirejs will stop executing immediately. So even if the requirejs script is loaded multiple times on the page there is no problem.

Configure Context

I call context a namespace because each context has a name, so that modules with the same name but different functions can be placed in different contexts to prevent conflicts.

If the developer does not configure the context, then requirejs will also generate a default context, the default context configuration is roughly as follows:

requirejs.config({

    context: "_",  // default context name

    baseUrl: "./",

    waitSeconds:7, // how long canloading last

    paths: {},

    bundles: {},

    pkgs: {},

    shim: {},

    config: {}

});

Note: Without specifying the context name , any configuration and invocation are modifications and invocations of the default context .

space name – context

If you customize the configuration context when requirejs is initialized, the name of the context created by default is "_". If you need to add a new context, just specify a new contextName. For example, the following call will create a new context:

requirejs({context:”new content name”});

There is only one context with the same name. Configuring a context with the same name is equivalent to modifying the properties of this context.

Load Timeout – waitSeconds

Each context is configured with a loading timeout time. If a module is not initialized and the loading time exceeds this time, it will be considered as a loading failure.

The loading timeout is for all modules in the entire context, not a single module. That is to say, the default 7 seconds means that all modules should be fully loaded within 7 seconds. After 7 seconds, if there are modules that are not loaded, an error will be thrown indicating which modules are not loaded. (requirejs makes a judgment every 50 milliseconds).

Base URL – baseUrl

The default value of the base URL for each context is "./".

Base URL of the first context

If the developer does not specify the context name, then the first context is the context generated by requirejs by default, otherwise it is the context defined by the developer himself. Under the premise of not specifying the base URL, the base URL setting of the first context is special. In addition to the standard setting method (refer to the standard setting method of the base URL below), the following two special methods can also be used:

The first: configure through requirejs or require object

Under the premise that no other requirejs has been executed before the requirejs script:

<script>requirejs={baseUrl: './'}</script>

<script data-main="scripts/app.js"src="../require.js"></script>

or

<script>require={baseUrl: './'}</script>

<script data-main="scripts/app.js"src="../require.js"></script>

Note: By setting the base URL in this way, the script file location specified by data-main will also become a path relative to the base URL, because the script specified by data-main itself is only one of the dependencies. Moreover, the script specified by data-main also belongs to the first context.

For example the following situation:

<script>requirejs={baseUrl: 'scripts/lib'}</script>

<script data-main="scripts/app.js"src="../require.js"></script>

The final path of the script module app.js becomes "scripts/lib/scripts/app.js", not the original "scripts/app.js", and its dependency name also becomes scripts/lib/scripts/app (requirejs will remove the last ".js" in the script path by default, unless the value of data-main starts with "/", or contains ":", or contains "?") .

The second: Calculated according to the script path specified by the data-main attribute of the script element

If baseUrl is not set, requirejs will calculate a base URL based on the JavaScript file path specified by the data-main attribute of the script element.

For example data-main="scripts/app.js", then baseUrl is "scripts/":

<script data-main="scripts/app.js"src="../require.js"></script>

Standard URL standard setting method

Except the first context can use the above method, other custom context configuration baseUrl can only use the following two methods. But these two methods can also be used to modify the properties of the first context. Without specifying the context name, it is actually modifying the first context .

Set via requirejs or the require method (these two are the same method themselves)

The following two are equivalent to setting the base URL of the default namespace to scripts/lib:

requirejs ({baseUrl: 'scripts/lib'});

require ({baseUrl: 'scripts/lib'});

Via the requirejs.config method

requirejs.config ({baseUrl: 'scripts/lib'});

require.config({baseUrl:'scripts/lib'});

In fact, the config method calls the requirejs method, so they are the same.

module dependencies – deps

Module dependency refers to the interdependence between modules. When the script is running, the current script will be executed only after all the dependent modules are loaded. This is the role of the dependency.

Dependencies are configured using an array, and the elements of the array are strings (ie, the names of modules), which are generally paths relative to baseUrl, but without a file suffix. Moreover, in order to obtain the module entry more conveniently, the module is generally defined by the define method. Because, the module defined by define can be directly obtained and used by the callback function behind the dependency array.

Taking jQuery as an example, there are generally two lines of code at the end of the jQuery script:

if(typeof define === "function"&& define.amd && define.amd.jQuery) {

    define("jquery", [], function () { return jQuery; } );

}

Taking underscore as an example, there are the following lines of code at the end of the script:

if (typeof define === 'function' && define.amd) {

  define('underscore', [],function() {

    return _;

  });

}

Modules and Module Locations

When using require to configure a dependent module, only the name of the module is declared, but the specific location of the module is not known. In the absence of a special declaration, requirejs considers the module name and file name to be the same, so as long as the two are consistent, requirejs can correctly find the script file. But if it is different, it needs to be configured by path:

requirejs.config({

    baseUrl:"scripts/lib",

    paths: {

        jquery:'jquery-1.7.2'

    }

});

This way, requirejs knows that the jquery module is located in the scripts/lib/jquery-1.7.2.js file.

Dependencies of the first context

<script>requirejs={deps: ['jquery']}</script>

<script data-main="scripts/app.js"src="../require.js"></script>

Dependencies of other contexts

In the same way as the base URL, it can be configured either through the requirejs method or through the requirejs.config method.

Module bundles - bundles

If there are multiple modules in a JS file, you can use the module bundle to declare:

requirejs.config({

    baseUrl:"scripts/lib",

    bundles: {

        jsUtil: ['MathUtil', 'DateUtil']

    }

});

The above example means that there are two submodules MathUtil and DateUtil in the scripts/lib/jsUtils.js file.

JS packages – packages

If there are multiple JS files in a folder, it will take a lot of lines of code to write them all by using the path method. At this time, if you use the package method to declare, you can save a lot of trouble:

requirejs.config({

    baseUrl:"scripts/lib",

    pkgs: [{name:'jqueryui',location: 'jqueryui/',main: 'core'}]

});

After this definition, all modules in the scripts/lib/jqueryui/ directory can be found correctly in this way:

require(['jqueryui/button', 'jqueryui/dialog']);

The above example is an example of getting scripts/lib/jqueryui/button.js and scripts/lib/jqueryui/dialog.js. In addition, because jqueryui is a directory and does not correspond to a JS file, it has a main attribute, which generally corresponds to the main program file in the JS package. In the above example, the main program of jqueryui is in scripts/lib/jqueryui/core.js.

wedge – shim

Not all JS modules will call the define method to define themselves like jquery and underscore, so requirejs does not know where the entry of your module is, and which object should be used to call this module, especially those earlier versions of JS modules, because That is, there is no concept of define and require.

requirejs.config({

    baseUrl:"scripts/lib",

    shim: {jquery: {deps:[],exportsFn: func, exports:'jQuery',init:func}}

});

Although the module does not use the define method to define itself, the developer should know how to obtain the module in the file. Therefore, requirejs provides two ways for developers to return the module object to requirejs management:

  • Set in the exportsFn or init method, and then as the return value;
  • Use the exports setting, such as "abc", then requirejs knows that it can be obtained through window.abc.

map – Map

Let’s look at the problem first: the dependencies of some third-party JS plugins are pre-set, and it is not easy to modify the name of the dependent module. If a module has multiple versions or other modules with the same name, use the above Neither configuration solves the problem. For example, path only solves the problem of module name to path, and this is the problem of switching module names. Therefore, requirejs proposes the concept of mapping, which dynamically modifies the ID of the dependent module according to the name of the current script, so that it points to the correct module.

If you have the following modules under your hard drive:

  • foo1.0.js
  • foo1.2.js
  • some/newmodule.js
  • some/oldmodule.js

There are require('foo') calls in both newmodule.js and oldmodule.js. To resolve the conflict, you only need to configure it like this:

requirejs.config({

    map: {

        'some/newmodule':{

            'foo': 'foo1.2'

        },

        'some/oldmodule':{

            'foo':'foo1.0'

        }

    }

});

Main program entry data-main

<script data-main="scripts/app.js"src="../require.js"></script>

No matter how many script elements on the page have the data-main attribute, requirejs only recognizes the data-main attribute of the last script element and ignores the data-main attribute of other script elements.

After Requirejs gets the data-main attribute, it does not immediately execute the script file specified by data-main (because this script file may also depend on other modules), but adds it to the first context as a dependent module in the dependency array. For example, the following situation is to add the scripts/app module to a context named linus:

<script type="text/javascript">

    requirejs={

        context: 'linus',

        baseUrl:"./",

        skipDataMain: false

    };

</script>

<script data-main="scripts/app.js"src="../require.js"></script>

Global configuration

Ignore data-main of script element

In browsers, there is an option called skipDataMain that makes requirejs ignore the data-main of the script element. By default, after requirejs is successfully loaded, it will immediately find all script elements on the page, and put the data-main of the last script element with the data-main attribute as the main program entry.

<script>requirejs={skipDataMain:true}</script>

<scriptdata-main="scripts/app.js"src="../require.js"></script>

Module Definition – define(name, deps, callback)

You will find that the define method does not specify the context name, this is because the define method is only called in the dependent module, and the require method has specified the context name for the dependent module, so, which context this module is required by, it belongs to that a context.

The parameter name is the name of the module, deps is the name of other modules that the module depends on, and callback generally returns the actual object that can be used by the module. For example, the jQuery module definition callback function returns the jQuery object.

Error

loadError

This kind of error is the Error object that comes with the browser, but requirejs adds other attributes to it.

  • The format of the message is: msg + '\nhttp://requirejs.org/docs/errors.html#' + id.
  • error.requireType is the id behind the message;
  • error.requireModules generally refers to the name of the module that needs to be loaded but has not been loaded successfully;
  • error.originalError refers to the original error object where another error occurred that caused the module to fail to load.

Guess you like

Origin http://10.200.1.11:23101/article/api/json?id=327069127&siteId=291194637