js模块化方案

245 阅读1分钟

将一个复杂的程序依据一定规则或者规范封装成几个文件并进行组合在一起块的内部数据的实现是私有的,只是向外暴露一些接口(方法与外部其他模块通信)

传统模块定义的方式

全局函数

function foo() {
    console.log("foo");
}

namespace模式:简单对象封装

var module = {
    msg:"hello world!"
    foo: function () {
        console.log("foo");
    }
}

IIFE模式:匿名函数

(function () {
    var _private = "private msg";

    function foo() {
        console.log(_private);
    }

    window.foo = foo;
})()

IIFE模式:增强模式

(function (window, $) {
    var _private = "_private";

    function foo() {
        console.log(_private);
    }

    window.foo = foo;
    
    $("body").css("backgroundColor","red");
})(window, jQuery)

CommonJS模块规范

适用于服务器端

定义模块

方式一:

module.exports = {
    foo() {
        console.log("module1");
    }
}

方式二:

module.exports = function() {
    console.log("module2");
}

方式三:

export.foo = function() {
    console.log("module3 foo");
}

export.bar = function() {
    console.log("module3 bar");
}

引用模块

var module1 = require('./module1')
var module2 = require('./module2')
var module3 = require('./module3')

module1.foo()

module2()

module3.foo()
module3.bar()

UMD通用模块定义

虽然 CommonJS 和 AMD 的风格大受欢迎,但是看起来似乎它们并没有达成共识。这样的局面也导致了一种能同时支持两种风格的需要出现,这带给了我们通用模块定义。

通用模块定义

下面这种模式,支持 AMD 和 CommonJS 和谐相处,还支持老式的 global 变量定义。

(function (root, factory) {
    if (typeof define === 'function' && define.amd) {
        // AMD
        define(['jquery'], factory);
    } else if (typeof exports === 'object') {
        // Node, CommonJS-like
        module.exports = factory(require('jquery'));
    } else {
        // Browser globals (root is window)
        root.returnExports = factory(root.jQuery);
    }
}(this, function ($) {
    //    methods
    function myFunc(){};

    //    exposed public method
    return myFunc;
}));

保持同样的模式实现更复杂的例子:

(function (root, factory) {
    if (typeof define === 'function' && define.amd) {
        // AMD
        define(['jquery', 'underscore'], factory);
    } else if (typeof exports === 'object') {
        // Node, CommonJS-like
            module.exports = factory(require('jquery'), require('underscore'));
    } else {
        // Browser globals (root is window)
        root.returnExports = factory(root.jQuery, root._);
    }
}(this, function ($, _) {
    // methods
    function a(){};    // private because it's not returned (see below)
    function b(){};    // public because it's returned
    function c(){};    // public because it's returned

    // exposed public methods
    return {
        b: b,
        c: c
    }
}));