美文网首页
javascrip中UMD规范的详细介绍

javascrip中UMD规范的详细介绍

作者: 高阳刘 | 来源:发表于2021-01-13 16:29 被阅读0次

    一、UMD规范

    UMD规范,就是多有规范里面长得最丑的那个,没有之一!!!他是为了让模块同时兼容AMD和CommonJS规范而出现的,多被一些需要同时支持浏览器端和服务端引用的第三方库所使用,UMD是一个时代的产物,当各个环境最终实现ES harmony的统一的规范后,它也将退出历史舞台。

    UMD规范的结构乍一看非常复杂,主要是因为想看懂这段范式需要一些JavaScript基础知识,它的基本机构是这样的:

    (function(root, factory) {
      if(typeof define === 'function' && define.amd) {
        // AMD
        define(['jquery', 'underscore'], factory);
      } else if (typeof exports === 'object') {
        // Node, CommomJs之类的
        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
      }
    })
    

    二、源码范式推演

    1、基本机构

    先来看最外层结构:

    (function(){}())
    

    非常简单,就是一个自执行函数,既然它是一个模块化的标准,也就意味着这个自执行函数最终可以导出一个模块,那么从大码的角度讲实际上有两种常见的实现方式:
    a.return 返回一个模块;
    b.实参传入一个对象,把函数内部生成好的需要导出的东西挂载这个对象的属性上;

    可以看到上面的函数体内部是没有return语句的,那么可以猜测UMD在实现时是采用了第二种方式,既然UMD是一种模块化的规范,那么他的功能就是根据使用要求生产模块,也就是说他的职责定位叫做模块工厂,我们可以顶一个factory方法,每当执行该方法时,就返回一个模块,所以他的基本机构就变成了如下的样子:

    (function(factory){
      // 假设没有使用任何模块化方案,那么将工厂函数执行后返回的内容直接挂载到全局
      window.Some_Attr = factory();
    }(function(){
      // 自定义模块主题的内容
      /*
        var a,b ,c;
        function a1(){};
        function b1(){};
        function c1(){};
        return {
          a:a1,
          b:b1
        }
      */
    }))
    

    也就是说我们自顶一个匿名函数,然后把它当做实参传给自执行函数,然后在自执行函数内部通过形参来访问这个工厂的方法(或者你回更熟悉回调函数或callback这样的叫法),把它简单的挂载到全局对象上没这样就完成了基本的模块导出。

    有的回收我们也希望可以将模块挂载到非全局的环境,将挂载对象动态传入可以让代码变得更加灵活,此处涉及到一个基础知识,就是浏览器环境中的全局对象拥有parent,top,self三个属性来追踪页面中嵌入<iframe>后引入的新的Window对象的,单页面Window.self是指向自己的,代码中常通过是否包含self属性来鉴别全局对象,所以此处的写法可以改进为兼容:

    (function(root, factory){
      root.Some_Attr = factory();
    }(self !== undefined ? self : this, function(){
    }))
    
    2适配AMD

    接着我们来加入AMD的规范适配,规范地址:AMD规范git湖北地址:

    // AMD规范的模块定义格式是define(id?, dependencies?, factory),factory就是实际的模块内容
    (function(factory){
      // 判断全局环境是否支持AMD标准
      if(typeof define === 'function' && define.amd){
        // 定义一个AMD模块
        define([dependencies*/], factory);
      }
    }(function(){
      // 自定义模块主题内容
      /* 
        var a,b,a;
        function a1(){};
        function b1(){};
        function c1(){};
        return {
          a: a1,
          b: b1
        }
      */
    }))
    
    3适配CommonJs

    接着我们先加入CommomJS的规范的适配:

    (function(factory){
      // 判断全局环境是否支持CommonJS标准
      if(typeof exports === 'object' && typeof define !== 'function'){
        module.eports = factory(/*require(moduleA),require(mouleB)*/);
      }
    }(function(){
      // 自定义模块主题内容
      /* 
        var a,b,a;
        function a1(){};
        function b1(){};
        function c1(){};
        return {
          a: a1,
          b: b1
        }
      */
    }))
    

    加入CommonJs的适配后,函数主体的return的内容(一般是一个对象)就被挂载到了module.exports上,如果你编写过node.js代码,对此一定不会陌生。

    把上面的片段揉到一块,你也就看懂UMD的样子了。

    三、更具针对性的UMD范式

    UMD在其GitHub主页上提供了更具针对性的范式,使用不同的场景,感情去的读者可以自行查看
    地址:https://github.com/umdjs/umd

    在此帖一个可能对大多数开发者比较有用的jQueryPlugin的开发范式,如果你看懂了上面的分析,那么下面的代码应该不难看懂:

    // Uses CommonJS,AMD or browser globals to create a jQuery plugin.
    (fuction (factory){
      if(typeof define === 'funtion' && define.amd){
        // AMD Register as an anonymous module.
        define(['jquery'], factory);
      } else if (typeof module === 'object' && module.exports){
        // Node/ComonJS
        module.exports = function(root, jQuery){
          if(jQuery === undefined) {
            if(typeof window !== 'undefined'){
              jQuery = require('jquery');
            } esle {
               jQuery = require('jquery')(root);
            }
          }
          factory(jQuery);
          return jQuery;
        }
      } esle {
        // Browser globals
        factory(jQuery);
      }
    }(fuction($){
      $.fn.jqueryPlugin = function(){ return true}
    }))
    

    原文 : https://www.php.cn/js-tutorial-410584.html

    相关文章

      网友评论

          本文标题:javascrip中UMD规范的详细介绍

          本文链接:https://www.haomeiwen.com/subject/qkteaktx.html