stage 4 —— (1)模块化

在看内容之前,我们需要来了解一下目前前端的形式。很久之前在一份简历中,看到这样一句话“推崇前端模块化及组件化”。而目前前端的需求也正如次。如果你有了解vue,react等前端流行框架,那么无论是那一个,都是组件为主。个人感觉vue会更舒服,包含了 template、script、css 的 *.vue文件用起来得心应手。说远了,我们接下来了解前端模块化。
1.模块
我们先来看看什么是模块,谈起模块就要从最根本的作用域开始说起。js的作用域是“函数级作用域”

function fn1() {
    var num = 10;
}
function fn2() {
    var num = 20;
}
window.fn1();
window.fn2();

上面的代码可以理解为最基本的模块,当然,这样的代码是不行,毕竟太污染全局变量了。
那么如果修改呢?看下面代码

var myModule = {
    num:10,
    str:"iwen",
    fn1:function () {
        console.log(this.num);
    },
    fn2:function () {
        console.log(this.str);
    }
};
myModule.num = 20;
myModule.fn1();

将属于一个模块的内容放入到一个对象中,这样很好解决了污染问题。当大家看到

myModule.num = 20;

的时候,发现外部可以随意修改内部成员。所以这样写不太合适。
那么我们在看下面的代码:

var myModule = (function () {
    var num = 10;
    var str = "iwen";
    function fn1() {
        console.log(num);
    }
    function fn2() {
        console.log(str);
    }
    return{
        fn1:fn1,
        fn2:fn2
    }
})();
myModule.fn1();

看到这里,就解决了外部修改内部成员的问题。在进一步加强
看下面代码:(放大模式)

var module1 = (function () {
    var num =10;
    var str = "iwen";
    function getName() {
        return str;
    }
    return {
        getName:getName
    }
})();
var module2 = (function (module1) {
    module1.setName = function () {
    };
    return module1;
})(module1);
console.log(module2.getName());

这样的好处是每一个module只处理当前相关的内容,我们来在进一步
看下面代码:(宽放大模式)

var module1 = {
    num:10,
    str:"iwen",
    fn1:function () {
        console.log(this.num);
    },
    fn2:function () {
        console.log(this.str);
    }
};
module1 = null;
var module2 = (function (module1) {
    module1.getName = function () {
    };
    return module1;
})(window.module1 || {});
console.log(module2);

与放大模式相比,宽放大模式可以传入空对象。如果我们需要引入第三方相关类库怎慢呢?
看下面代码:

var module  = {
    num:10
};
var module1 = (function ($,module) {
    function getNum() {
        console.log(module.num);
    }
    function getJQ() {
        console.log($("div"));
    }
    return{
        getJQ:getJQ,
        getNum:getNum
    }
})(jQuery,module);
module1.getJQ();
module1.getNum();

下面我们在来研究一下私有与共有的问题:

var module1 = (function () {
    var num =10;
    var str = "iwen";
    function getName() {
        return str;
    }
    return {
        getName:getName
    }
})();
var module2 = (function (module1) {
    module1.setName = function () {
    };
    return module1;
})(module1);
console.log(module2);

上面的代码,大家好好思考一下。
2.接下来了解一下“模块化”
受到了NodeJS的Commonjs规范影响,在浏览器端也开始流行模块化,模块化单独说起来有点麻烦。我们还是来引入第三方吧,知名被常用到目前有一下
(1)require.js
(2)sea.js
首先我们来看一下Commonjs规范,具体代码看下面:
module.js:

function demo() {
    console.log("demo");
}
function demo2() {
    console.log("demo2");
}
module.exports = {
    demo:demo,
    demo2:demo2
}

demo.js

var module1 = require("./module1");
module1.demo();
module1.demo2();

以上代码,需要Node环境来进行执行。关于Node并非本章内容,在这里不过多说明。
接下来看一来require.js。
AMD 是 RequireJS 在推⼴过程中对模块定义的规范化的产出
requireJS主要解决问题:
(1)实现js⽂件的异步加载,避免⽹⻚失去响应
(2)管理模块之间的依赖性,便于代码的编写和维护
具体实现:
(1)引入

<script src="js/libs/require.js" data-main="js/main.js">

(2)编写主入口文件:main.js

//require的配置
require.config({
    //定义基础路径
    baseUrl:"js",
    //加载文件路径
    paths:{
        "jquery":"libs/jquery-3.2.1",
        "getName":"app/getName"
    }
});
require(["jquery","getName"],function ($,getName) {
});

(3)编写自己的模块

define(function () {
    function setDiv() {
        var div = document.getElementsByClassName("div").item(0);
        div.innerHTML = "嘿嘿";
    }
    setDiv();
});

以上为require.js基础内容,更多内容请参考官方API进行学习
具体实现效果可以参考这里,代码没有压缩,可直接看。如果有需要联系邮箱:iwen@iwens.org
接下来看一下sea.js,到现在,seajs已经不再开发及维护,只能为那些一直在使用sea.js的童鞋标示默哀了。
CMD:seajs在推广过程中对模块定义的规范化产出
(1)引入

<script src="js/sea.js">

(2)加载模块

seajs.config({
    base:"./js/",
    alias:{
        "getName":"getName",
        "jquery":"jquery-3.2.1"
    }
});
seajs.use("main");

(3)创建模块

define(function (require,exports,module) {
    //加载文件
    require.async(["jquery","getName","setName"],function ($,getName,setName) {
        console.log(setName.setName());
    })
});

接下来还是要说一下,总有一些面试官会问,你知道“CMD和AMD的区别么?”,脑子秀逗的人喜欢这么问。哈哈,原谅我吧,我的神。
4.AMD和CMD的区别
AMD推崇依赖前置,在定义模块的时候就要声明其依赖的模块
CMD推崇就近依赖,只有在⽤到某个模块的时候再去require
以上内容就是模块化的基本内容。本文为作者原创,转载请注明出处,谢谢。

发表回复

您的电子邮箱地址不会被公开。 必填项已用*标注