JavaScript basic Discipline (4) Code deduction for--UMD Specification 1. UMD specification
Address: GITHUB.COM/UMDJS/UMD
UMD
Specification, is the most ugly one in all specifications, no one!!! It is designed to allow modules to be compatible AMD
and regulated, and is used by a CommonJs
number of third-party libraries that require both browser-side and server-side references. UMD
is the product of an era, and ES harmony
it will also exit the historical stage when the various environments finally achieve the unified norm.
UMD
The structure of the specification is very complex at first glance, mainly because it requires some basic knowledge to understand this paradigm javascript
, and its basic structure is this:
(function (root, factory) { if (typeof define === 'function' && define.amd) { // AMD define(['jquery', 'underscore'], factory); } else if (typeof exports === 'object') { // Node, CommonJS之类的 module.exports = factory(require('jquery'), require('underscore')); } else { // 浏览器全局变量(root 即 window) root.returnExports = factory(root.jQuery, root._); }}(this, function ($, _) { // 方法 function a(){}; // 私有方法,因为它没被返回 (见下面) function b(){}; // 公共方法,因为被返回了 function c(){}; // 公共方法,因为被返回了 // 暴露公共方法 return { b: b, c: c }}));
2. Source code Paradigm Deduction 2.1 Basic structure
First look at the outermost structure:
(function (){}());
Very simple, is a self-executing function. Since it is a modular standard, which means that the self-executing function can eventually export a module , there are actually two common implementations in terms of code:
- return returns a module;
- An argument is passed into an object, and the object's properties are hung on the inside of the function to generate the good things to be exported.
You can see that there is no return statement inside the function body above, then you can guess the UMD
second way to implement it. Since it UMD
is a modular specification, its function is to produce the module according to the requirements of the use, that is to say its responsibility is called the module factory , we can define a factory
method, each time the method is executed, return a module , so its basic structure becomes the following:
(function (factory){ //假设没有使用任何模块化方案,那么将工厂函数执行后返回的内容直接挂载到全局 window.Some_Attr = factory();}(function(){ //自定义模块主体的内容 /* var a,b,c function a1(){} function b1(){} function c1(){} return { a:a1, b:b1 } */}))
This means that we customize an anonymous function, and then pass it as an argument to the self-executing function, and then access it through the formal parameter inside the self-executing function 工厂方法
(or you'll be more familiar with it 回调函数
or callback
that), simply hang it on the global object, This completes the basic module export.
Sometimes we also want to be able to mount the module to a non-global environment, the dynamic introduction of Mount objects can make the code more flexible, here is a basic knowledge, is the browser environment in the global object owned parent
, top
self
three properties to track the page embedded <iframe>
After the introduction of the new Window object, the single page window.self is pointing to itself, and the code often identifies the global object by whether it contains self
attributes, so the wording here can be improved to be compatible:
(function(root,factory){ root.Some_Attr = factory();}(self !== undefined ? self : this, function(){ }));
2.2 Matching AMD
Then we first join AMD
the specification of the adaptation, canonical address: AMD Spec GitHub Address:
/** AMD规范的模块定义格式是define(id?, dependencies?, factory),factory就是实际的模块内容*/(function (factory){ //判断全局环境是否支持AMD标准 if(typeof define === 'function' && define.amd){ //定义一个AMD模块 define([/*denpendencies*/],factory); }}(function(/*formal parameters*/){ //自定义模块主体的内容 /* var a,b,c function a1(){} function b1(){} function c1(){} return { a:a1, b:b1 } */}))
2.3 Adapter Commonjs
And then we'll start by adding CommonJs
the specifications to fit:
/** CommonJs规范使用require('moduleName')的格式来引用模块,使用module.exports对象输出模块,所以只要把模块的输出内容挂载到module.exports上就完成了模块定义。*/(function (factory){ //判断全局环境是否支持CommonJs标准 if(typeof exports === 'object' && typeof define !== 'function'){ module.exports = factory(/*require(moduleA), require(moduleB)*/); }}(function(/*formal parameters*/){ //自定义模块主体的内容 /* var a,b,c function a1(){} function b1(){} function c1(){} return { a:a1, b:b1 } */}))
When you add a pair, the CommonJs
return content (usually an object) in the body of the function is mounted on it, and module.exports
if you write node.js
code, it is not unfamiliar.
Rub the above pieces into one piece, and you'll see what it UMD
looks like.
3. More targeted UMD paradigm
UMD
A more targeted paradigm is available on its GitHub home page, suitable for different scenarios where interested readers can see for themselves (addresses are given in the first section).
The
Paste a development paradigm that might be useful for most developers Jqueryplugin
, and if you understand the above analysis, the following code should not look ugly:
Uses CommonJS, AMD or browser globals to create a jQuery plugin. (function (Factory) {if (typeof define = = = ' function ' && define.amd) {//AMD. Register as an anonymous module. define ([' jquery '], factory); } else if (typeof module = = = ' object ' && module.exports) {//Node/commonjs Module.exports = Functio N (Root, jquery) {if (jquery = = = undefined) {//require (' jquery ') returns a factory that re Quires window to//build a JQuery instance, we normalize how do we use modules//that require This pattern and the window provided is a noop//if it's defined (how jquery works) if (t ypeof window!== ' undefined ') {jquery = require (' jquery '); } else {jquery = require (' jquery ') (root); }} factory (JQuery); return jQuery; }; } else {//Browser Globals Factory (jQuery); }} (function ($) {$.fn.jqueryplugin = function () {return true;}));
4. Modular development
The front-end modularity itself is a slightly confusing topic, the author's own original require( )
and require.js
silly points are not clear, but the module is the front-end development of a very important topic, if you do not want to spend a lifetime just write code in a page, this is bound to pass, Interested readers can learn by dividing blocks into the following basic categories.