什么是前端模块化?前端模块化开发到底有无必要

 
 

所谓前端开发,就是前台,常见的包括几个端:PC、pad、手机、其他智能设备,可以跑浏览器的地方就是我们前端人大施拳脚的乐土。自从node的问世,现在不光可以在浏览上了,疆土可以扩展到服务端即后台。这样一来JavaScript又牛了一级有着前后台通吃的能力,当然操作太底层的东西还需要Java等传统后台语言。随着电脑手机等智能设备性能配置、网络带宽、技术等提升,我们可以把网页做的更炫酷,更复杂、交互更加人性化也不会卡顿。但是这么搞下去,大量的js脚本代码略显其不好管理维护及团队配合开发,有些杂牌军的感觉。于是模块化开发应运而生。

模块化

ES5及之前是如何实现模块化的

通过RequireJS实现:

一提到模块化,常说到CommonJS和AMD。这俩主要是个什么东西呢,记住是模块化的标准规范即可。而RequireJS就是AMD规范的最好实现。就像ECMAScript和JavaScript的关系是,前者是后者的规格,后者是前者的一种实现。我们只需要知道,实现CommonJS规范的API是同步加载模块的,而实现AMD规范的API是则是异步加载模块,异步加载即非阻塞加载,更加适合浏览器端。官方文档对RequireJS的描述:

RequireJS 是一个JavaScript模块加载器。它非常适合在浏览器中使用,但它也可以用在其他脚本环境, 就像 Rhino and Node.使用RequireJS加载模块化脚本将提高代码的加载速度和质量。

RequireJS优点:

  1. 异步“加载”。我们知道,通常网站都会把script脚本的放在html的最后,这样就可以避免浏览器执行js带来的页面阻塞。使用RequireJS,会在相关的js加载后执行回调函数,这个过程是异步的,所以它不会阻塞页面。

  2. 按需加载。通过RequireJS,你可以在需要加载js逻辑的时候再加载对应 的js模块,这样避免了在初始化网页的时候发生大量的请求和数据传输,或许对于一些人来说,某些模块可能他根本就不需要,那就显得没有必要。

  3. 更加方便的模块依赖管理。相信你曾经一定遇到过因为script标签顺序问题而导致依赖关系发生错误,这个函数未定义,那个变量undefine之类的。通过RequireJS的机制,你能确保在所有的依赖模块都加载以后再执行相关的文件,所以可以起到依赖管理的作用。

  4. 更加高效的版本管理。想一想,如果你还是用的script脚本引入的方式来引入一个jQuery2.x的文件,然后你有200个页面都是这么引用的,那当你想换成jQuery3.x,那你就不得不去改这200个页面。但是如果你的requireJS有在config中做jQuery的path映射,那你只需要改一处地方即可。

RequireJS 使用

需要在页面中引入的文件

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

使用RequireJS,你只需要引入一个require.js即可。你的页面上只需要通过\<script\>标签引入这一个js即可。然后这个页面的所有业务逻辑只需要在main.js里面写.

ps:标签中有一个data-main属性,你现在只需要了解require.js会在加载完成以后通过回调方法去加载这个data-main里面的js文件,所以这个js文件被加载的时候,RequireJS已经加载执行完毕。

整个RequireJS2000来行源码,暴露出来供我们使用的就那么几个,主要有导入模块,定义模块。(requirejs,require,define),其中:requirejs和require的关系如同:jQuery和$的关系。说道这里:前端的人想必都懂了。

ES6是如何实现模块化的

通过自带的实现:

es6原生支持模块化了,通过import导入模块,export导出模块。这两个单词一直作为保留字,如今赋予它应有的身份出现了,丰富了js语言功能。传统的模块模式基于闭包,返回的“公有API”。这个“公有API”带有对内部变量和功能拥有闭包的方法。它经常这样表达:

模块greetingfn的定义:外边套一层父函数
function myName(name) {
//父函数myName
    function greetingfn() {
    //子函数greetingfn
        console.log( "myName " + name + "!" );
    }

    // 公有API---返回父函数里包裹的方法的指针。
    return {
        greetingfn: greeting
    };
}
使用:
var me = myName( "macrolam" );
me.greetingfn();            // myName macrolam!

ps:使用时注意:import和export都必须总是出现在它们分别被使用之处的顶层作用域。例如,你不能把import或export放在一个if条件内部;它们必须出现在所有块儿和函数的外部。

export的使用

export关键字要么放在一个变量或函数声明的前面,要么就对象形式导出,代码如下:
方式1:

export function fn() {
 // 导出函数
}

export var num = 42;
 // 导出变量
var arr = [1,2,3];

export { arr };

方式2:

function fn() {

}

 var num = 42;

 var arr = [1,2,3];
//统一导出
export {fn,num,arr};

import使用

要导入一个模块,你将不出意料地使用import语句。就像export有几种微妙的变化一样,import也有,所以你要花相当多的时间来考虑下面的问题,并试验你的选择。

如果你想要导入一个模块的API中的特定命名成员到你的顶层作用域,使用这种语法:

import { foo, bar, baz } from "foo";

ps: 这里的{ .. }语法可能看起来像一个对象字面量,甚至是像一个对象解构语法。但是,它的形式仅对模块而言是特殊的,所以不要将它与其他地方的{ .. }模式搞混了。

被罗列的标识符foo,bar和baz必须匹配在模块的API上的命名导出(这里将会发生静态分析和错误断言)。它们在你当前的作用域中被绑定为顶层标识符。

import { foo } from "foo";
foo();

你可以重命名被导入的绑定标识符,就像:

import { foo as theFooFunc } from "foo";
theFooFunc();

小结:

对于一个小项目,没有多少页面(十几个)的PC端站点,没必要进行前端模块化开发;但是从维护性角度来说还是采用模块化好些。对于一个大项目,数据交互功能性动画频发的站点js代码大量涌现还是模块化更优。



作者:麦壳儿UIandFE2
链接:http://www.jianshu.com/p/e422c28e2471
來源:简书
著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。
  • 0
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值