关于前端:前端模块化开发的价值

39次阅读

共计 4040 个字符,预计需要花费 11 分钟才能阅读完成。

随着互联网的飞速发展,前端开发越来越简单。本文将从理论我的项目中遇到的问题登程,讲述模块化能解决哪些问题,以及如何应用 Sea.js 进行前端的模块化开发。

宜人的命名抵触

咱们从一个简略的习惯登程。我做我的项目时,经常会将一些通用的、底层的性能形象进去,独立成一个个函数,比方

function each(arr) {
// 实现代码
}
function log(str) {
// 实现代码
}

并像模像样地把这些函数对立放在 util.js 里。须要用到时,引入该文件就行。这所有工作得很好,共事也很感谢我提供了这么便当的工具包。

直到团队越来越大,开始有人埋怨。

小杨:我想定义一个 each 办法遍历对象,但页头的 util.js 里曾经定义了一个,我的只能叫 eachObject 了,好无奈。

小高:我自定义了一个 log 办法,为什么小明写的代码就出问题了呢?谁来帮帮我。

埋怨越来越多。团队通过一番强烈的探讨,决定参照 Java 的形式,引入命名空间来解决。于是 util.js 里的代码变成了

var org = {};
org.CoolSite = {};
org.CoolSite.Utils = {};
org.CoolSite.Utils.each = function (arr) {
// 实现代码
};
org.CoolSite.Utils.log = function (str) {
// 实现代码
};

不要认为下面的代码是为了写这篇文章而成心捏造的。将命名空间的概念在前端中发扬光大,首推 Yahoo! 的 YUI2 我的项目。上面是一段实在代码,来自 Yahoo! 的一个开源我的项目。

if (org.cometd.Utils.isString(response)) {
return org.cometd.JSON.fromJSON(response);
}
if (org.cometd.Utils.isArray(response)) {
return response;
}

通过命名空间,确实能极大缓解抵触。但每每看到下面的代码,都忍不住充斥同情。为了调用一个简略的办法,须要记住如此长的命名空间,这减少了记忆负担,同时剥夺了不少编码的乐趣。

作为前端业界的标杆,YUI 团队下定决心解决这一问题。在 YUI3 我的项目中,引入了一种新的命名空间机制。

YUI().use(‘node’, function (Y) {
// Node 模块已加载好
// 上面能够通过 Y 来调用
var foo = Y.one(‘#foo’);
});

YUI3 通过沙箱机制,很好的解决了命名空间过长的问题。然而,也带来了新问题。

看似简略的命名抵触,理论解决起来并不简略。如何更优雅地解决?咱们按下暂且不表,先来看另一个常见问题。

繁缛的文件依赖

持续下面的故事。基于 util.js,我开始开发 UI 层通用组件,这样项目组共事就不必反复造轮子了。

其中有一个最被大家喜爱的组件是 dialog.js,应用形式很简略。

<script src=”util.js”></script>
<script src=”dialog.js”></script>
<script>
org.CoolSite.Dialog.init({/ 传入配置 / });
</script>

可是无论我怎么写文档,以及如许郑重地发邮件宣告,时不时总会有共事来询问为什么 dialog.js 有问题。通过一番排查,发现导致谬误的起因常常是

<script src=”dialog.js”></script>
<script>
org.CoolSite.Dialog.init({/ 传入配置 / });
</script>

在 dialog.js 前没有引入 util.js,因而 dialog.js 无奈失常工作。同样不要认为我下面的故事是虚构的,在我待过的公司里,至今仍旧有相似的脚本报错,特地是在各种疾速制作的营销页面中。

下面的文件依赖还在可控范畴内。当我的项目越来越简单,泛滥文件之间的依赖常常会让人抓狂。上面这些问题,我置信每天都在实在地产生着。

通用组更新了前端根底类库,却很难推动全站降级。业务组想用某个新的通用组件,但发现无奈简略通过几行代码搞定。一个老产品要上新性能,最初评估只能基于老的类库持续开发。公司整合业务,某两个产品线要合并。后果发现前端代码抵触。…… 以上很多问题都是因为文件依赖没有很好的治理起来。在前端页面里,大部分脚本的依赖目前仍旧是通过人肉的形式保障。当团队比拟小时,这不会有什么问题。当团队越来越大,公司业务越来越简单后,依赖问题如果不解决,就会成为大问题。

文件的依赖,目前在绝大部分类库框架里,比方国外的 YUI3 框架、国内的 KISSY 等类库,目前是通过配置的形式来解决。

YUI.add(‘my-module’, function (Y) {
// …
}, ‘0.0.1’, {
requires: [‘node’, ‘event’]
});

下面的代码,通过 requires 等形式来指定以后模块的依赖。这很大水平上能够解决依赖问题,但不够优雅。当模块很多,依赖很简单时,繁缛的配置会带来不少隐患。

命名抵触和文件依赖,是前端开发过程中的两个经典问题。下来咱们看如何通过模块化开发来解决。为了不便形容,咱们应用 Sea.js 来作为模块化开发框架。

应用 Sea.js 来解决

Sea.js 是一个成熟的开源我的项目,外围指标是给前端开发提供简略、极致的模块化开发体验。这里不多做介绍,有趣味的能够拜访 seajs.org 查看官网文档。

应用 Sea.js,在书写文件时,须要恪守 CMD(Common Module Definition)模块定义标准。一个文件就是一个模块。后面例子中的 util.js 变成

define(function(require, exports) {
exports.each = function (arr) {
// 实现代码
};
exports.log = function (str) {
// 实现代码
};
});

通过 exports 就能够向外提供接口。这样,dialog.js 的代码变成

define(function(require, exports) {
var util = require(‘./util.js’);
exports.init = function() {
// 实现代码
};
});

要害局部到了!咱们通过 require(‘./util.js’) 就能够拿到 util.js 中通过 exports 裸露的接口。这里的 require 能够认为是 Sea.js 给 JavaScript 网站监控语言减少的一个 语法关键字,通过 require 能够获取其余模块提供的接口。

这其实一点也不神奇。作为前端工程师,对 CSS 代码肯定也不生疏。

@import url(“base.css”);

id {…}

.class {…}

Sea.js 减少的 require 语法关键字,就如 CSS 文件中的 @import 一样,给咱们的源码赋予了依赖引入性能。

如果你是后端开发工程师,更不会生疏。Java、Python、C# 等等语言,都有 include、import 等性能。JavaScript 语言自身也有相似性能,但目前还处于草案阶段,须要等到 ES6 规范失去支流浏览器反对后能力应用。

这样,在页面中应用 dialog.js 将变得非常简单。

<script src=”sea.js”></script>
<script>
seajs.use(‘dialog’, function(Dialog) {
Dialog.init(/ 传入配置 /);
});
</script>

首先要在页面中引入 sea.js 文件,这个别通过页头全局把控,也不便更新保护。想在页面中应用某个组件时,只有通过 seajs.use 办法调用。

好好推敲以上代码,我置信你曾经看到了 Sea.js 带来的两大益处:

通过 exports 裸露接口。这意味着不须要命名空间了,更不须要全局变量。这是一种彻底的命名抵触解决方案。通过 require 引入依赖。这能够让依赖内置,开发者只需关怀以后模块的依赖,其余事件 Sea.js 都会主动解决好。对模块开发者来说,这是一种很好的 关注度拆散,能让程序员更多地享受编码的乐趣。

小结

除了解决命名抵触和依赖治理,应用 Sea.js 进行模块化开发还能够带来很多益处:

模块的版本治理。通过别名等配置,配合构建工具,能够比拟轻松地实现模块的版本治理。进步可维护性。模块化能够让每个文件的职责繁多,十分有利于代码的保护。Sea.js 还提供了 nocache、debug 等插件,领有在线调试等性能,能比拟显著地晋升效率。前端性能优化。Sea.js 通过异步加载模块,这对页面性能十分无益。Sea.js 还提供了 combo、flush 等插件,配合服务端,能够很好地对页面性能进行调优。跨环境共享模块。CMD 模块定义标准与 Node.js 的模块标准十分相近。通过 Sea.js 的 Node.js 版本,能够很不便实现模块的跨服务器和浏览器共享。模块化开发并不是陈腐事物,但在 Web 畛域,前端开发是新生岗位,始终处于比拟原始的刀耕火种时代。直到最近两三年,随着 Dojo、YUI3、Node.js 等社区的推广和风行,前端的模块化开发理念才逐渐深入人心。

前端的模块化构建可分为两大类。一类是以 Dojo、YUI3、国内的 KISSY 等类库为代表的大教堂模式。在大教堂模式下,所有组件都是颗粒化、模块化的,各组件之间层层分级、环环相扣。另一类是以 jQuery、RequireJS、国内的 Sea.js、OzJS 等类库为根底的集市模式。在集市模式下,所有组件彼此独立、职责繁多,各组件通过组合松耦合在一起,协同实现开发。

这两类模块化构建形式各有利用场景。从久远来看,小而美更具备宽容性和竞争力,更能造成有生机的生态圈。

总之,模块化能给前端开发带来很多益处。如果你还没有尝试,无妨从试用 Sea.js 开始。

正文完
 0