An important update of this version is to fully implement amd specifications. The entire framework is rewritten based on this new loader, so it is convenient to call the JS library written by foreigners using amd specifications.
- You can set $. Core. Level to exclude unimportant log printing.
- Add the config method to set some important information about the framework or alias the module.
- Implement smart prompts in the vs series.
For more information about how to use this module to load the system, see the tutorial here. the new loader supports both AMD and yuber's seajs cmd. if the callback in the module definition contains either of the "require", "Exports", and "modules", the loader is treated as cmd. however, AMD and CMD are ignored. In the function, require, modules, and exports are all available and can be like node. JS loads modules like this.
For the module ID of the require method, see here
For more information about how to use amd to manage our scripts, I think people who have done some big projects should be aware that this is not a replacement for merging JavaScript. For details, see this article.
The following describes the operating mechanism of my loader. Let's start with a module without dependency. For example:
$. Require ("$ lang_fix", function () {console. Log ("xxxxxxxxxxxxxx ")})
Needless to say, go to $. Require (I hope you can check the source code when you look at it .)
String (list). Replace ($. rword, function (EL) {}) El = "$ lang_fix"
Enter module. _ resolvefilename
Url = $. Core. Base + EL + ". js"
For the first time loading, it is certainly not registered in modules. The modules [url] is undefined
Enter loadjs (URL, ID );
- Create an IFRAME,
- On the first Script node, use Nick, NS, and Nick to save the URL, $, and innerdefine respectively.
- Use the URL to load the target node on the Second Script node
The second node is bound to onreadystatechange, onload, and onerror respectively based on different situations.
It is worth noting that when we register the module, the State is still undefined, and it will modify the state in innerdefine.
Then we load the module through the script in IFRAME, and the module is generally in this format
Define ("lang_fix", function () {// ========================= })
The define here is essentially innerdefine
Innerdefine has done a few important things (now we only need to check first and second)
- The first thing is to replace the first parameter lang_fix with Nick. Nick is the SRC of the script that loads it.
- The second thing is to change the status of the corresponding module to 1, which is also modules [url]. State = 1.
- The third thing is that $, exports, require, module, and other objects are forced into the module factory.
- The fourth thing is to forward the real $. Define for processing.
In the second case, we changed the module status, so when the node executes onreadystatechange/onload
If (/loaded | complete | undefined/I. Test (this. readystate)} {ns. _ checkdeps (); ns._checkfail(self.doc ument, Nick );}
NS. _ checkfail
_ Checkfail: function (Doc, ID, error) {Doc & (Doc. OK = 1); If (error |! Modules [ID]. State) {This. Log ("failed to load [[" + ID + "]" + modules [ID]. State );}},
If it is a dead chain, the define function cannot be called, and innerdefine cannot be called, And the status is undefine.
! Modules [ID]. State = trueSo I printed the error log. Of course, we will discuss whether the throw should be used.
If it is in the old-style opera, it will not be able to access any callback of onreadystatechange, onload, and onerror.
In _ checkfail, we will fix Doc. OK = 1. When we detect that Doc. OK is not equal to 1 in onload of IFRAME,
Input the third parameter true in _ checkfail to print the error log.
In ff, chrome, and ie9, they will enter the onerror callback, where the callCodeMedium
Ns._checkfail(self.doc ument, Nick, true)
Therefore, dead links are also detected.
If loading fails, we immediately remove the corresponding IFRAME from the DOM tree!
Well, if the load is successful, we will reach $. Define through innerdefine, and also remove the corresponding IFRAME from the DOM tree.
$. Define does the following:
- The first thing is to check whether the second parameter is boolean. It indicates that it is a patch module. If the Boolean value is true, it indicates that the patch module is useless to the browser and returns directly, the module factory that does not execute it. If this parameter is set to false, for example, IE6, the patch module is always useful to it. Remove this parameter and continue to execute it.
- The second thing is to check the number of parameters. If there are only two parameters, it indicates that only the module name and the module callback are available (or it may not be the callback). Then we insert an empty array as the dependency list.
- The third is to check whether the third parameter is a function, not a function. For example, if it is an object, we need to insert it into a function.
For example
Define ({AAA: 2 })
After the previous conversions
Define ("http: // xxxxxxx/AA. JS ", {AAA: 2}); // ----> define (" http: // xxxxxxx/AA. JS ", [], {AAA: 2}); // ----> define (" http: // xxxxxxx/AA. JS ", [], function () {return {AAA: 2 }}); // ----> $. require ([], function () {return {AAA: 2}), "http: // xxxxxxx/AA. JS ")
Finally, we rearrange the order of parameters and call $. Require again.
// 0, 1, 2 --> 1, 2, 0 this. Require (ARGs [1], argS [2], parent );
Because lang_fix is not dependent, so DN = Cn is equivalent to 0 = 0, execute install (ID, argS, factory );
In short, install runs the module factory and changes the state to 2.
Note that the _ checkdeps method is executed every time we call $. Require or load a script.
When the lang_fix status changes to 2
$. Require ("$ lang_fix", function () {console. Log ("xxxxxxxxxxxxxx ")})
This callback will also be executed!
Console print xxxxxxxxxxxxxxxx
Source code is located here