前端模块化的演变

模块化可以说是目前前端最重要的开发范式之一,模块化是一种思想,这种思想,在不同的前端开发阶段,其实现的方式也各不相同

文件划分方式

起初前端通过文件划分的方式来实现模块化,如分别定义a.js文件和b.js文件,每个文件中有相关的逻辑的变量,然后在html中统一引入

这种方式有很大的缺陷

首先就是全局变量的问题,引入的各个文件都将把各自的变量挂载到全局,各个文件间的变量命名也可能会有冲突,而且各个文件之间可能会有依赖关系,难以管理。

命名空间方式

这种方式对文件划分的方式进行了改进,针对每一个文件,定义一个全局的类,所有的变量和函数均写在这个类里面,这样在引入的时候就可以解决各个模块之间命名冲突的问题。但是,可以看到,即使这样,依然可以从全局去访问或修改每个模块下的成员,模块的依赖关系也没有办法解决。

var moduleA = {
    name:'module-a',
    method1:function(){
        
    }
}

自执行函数的方式

自执行函数通过单个文件中定义自执行函数,然后运行函数将方法挂载到全局,这样实现私有变量的形式,使得全局无法直接访问到单个模块的变量,只能通过闭包的方式去方法,并且可以通过传参的形式,来解决模块间的依赖。

(function($){
    var modulea = 'module_a'
    function method1(){
        console.log(modulea)
    }
    function method2(){
        console.log('sx'+modulea)
    }
    window.moduleA = {
        method1:method1,
        method2:method2
    }
})(jQuery)

以上的方式是在前端构建工具,模块化范式没有出现之前的的模块化实现方式,这种方式的引入顺序依靠约定实现,且通过script标签方式引入,在后期代码维护方法会产生很大的干扰,后来,有人开始尝试利用js来实现一种模块化规范,因此实现模块的定义、引入。

commonjs规范

commonjs是node中提出的规范,其所规定有:

  • 一个文件就是一个模块
  • 每个模块都有单独的作用域
  • 通过module.exports导出成员
  • 通过require函数载入模块

但是这种规范并不适合浏览器端,因为commonjs是同步执行的,在node中只需在node启动的时候即可加载好所有模块,但是这种方式在浏览器端,则会产生很大的负担,在网页每次刷新的时候,浏览器都需要进行大量同步请求,对于其性能的影响很大。

AMD规范

为解决这种方式,浏览器端也产生了AMD规范,并产生了相关的库-require.js
这种方式通过定义模块和引入模块机制,内部自动生成script标签,引入相关的内容

//定义模块
// 参数:1.模块名,2.模块依赖项,3.自定义模块
define('module1',['jquery','./module2'],function($,module2){
    return {
        start:function(){
            $('body').animate({
                margin:'200px'
                module2()
            })
        }
    }
})

//载入模块
require(['module1'],function(module1){
    module1.start()
})

但是这种方式本质上也是通过动态创建script标签实现模块的引入,在实际代码中,需要频繁创建和引入模块的时候,对浏览器的开销很大。

esmodule

es6出现之后,在浏览器端总结之前的规范,设计了esmodule规范,且目前已被大多数浏览器兼容,目前,浏览器端基本由esmodule规范占据大半,而node端则是commonjs规范

你可能感兴趣的:(前端工程化,前端工程化)