Recently I'm going to integrate some of the tools I wrote earlier into a JS library, but the libraries are both normal and not exposed to global variables in an AMD environment. It's a headache for a while. Then I refer to some of the current popular library source code. Learning to write a bit, it feels good.
Now that we want to support AMD, we need to choose an AMD module loader, where I use Requirejs.
As for the library I'm using a gadget library I wrote recently Mtools, GitHub address: Https://github.com/grARM/mTools. So let's get started.
I. Judging the environment
The effect I'm trying to achieve is to expose a global variable in a general environment that can be loaded as a module under AMD. If we want to discriminate, we must first judge the different environment. So what are the characteristics of the AMD environment?
Used Requirejs of the pot friends, must be very familiar with define (), we are using define () to define a module, so we have the first condition:
typeof Define = = = "function"
But just because define is a function, isn't it tight enough, if I also define a global function with the same name. We create a Requirejs project, in the console input DEFINE.AMD, the console will return an object, in fact, he is a property of define method, check the Requirejs's official website, found that this property is used to illustrate the current module loader is the AMD protocol, For example, in our require Project console input Define.cmd will return undefined that is to say we have a second condition:
if typeof Define = = = "function" && define.amd) {}
Second, separate treatment
My tool module, which can be understood as a function, will eventually return some of the properties that need to be accessed by the outside world. The return object is the variable that is exposed to the global variables in the normal module, and he is also the module return value in AMD. In other words, I just have to deal with the return value (or module function) based on the conditions above to achieve our purpose. So how do you deal with it?
For the general environment, we can directly assign the return value of the backend of the module function to a variable on the window.
For the AMD environment, we have just said that we need to use define to define the function. So we can deal with both of these situations:
1;(function(Factory) {2 if(typeofdefine = = = "function" &&define.amd) {3 4 //AMD. Register as an anonymous module.5 define (factory);6}Else {7 8 //Browser Globals9 //take my library as an example, return MtoolsTenWindow.mtools =Factory (); One } A})(function(){ - Our JS library - return { the //Module return value - } - -});
Note that we pass the JS library function as an immediate function parameter to our analysis function, which is factory (not executed), if the AMD environment is defined as an AMD module, and if it is a general environment, it is run directly to assign the value of the return value to Window.mtools
Then I tested it and actually exposed a global variable in the general environment, which can be loaded as a module under AMD (No global exposure).
Write your own JS library, how to support AMD