V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
V2EX 提问指南
datagrand
V2EX  ›  问与答

达观数据基于 RequireJS 的前端模块化怎样更好地设计?

  •  
  •   datagrand · 2016-03-20 14:33:18 +08:00 · 1185 次点击
    这是一个创建于 3174 天前的主题,其中的信息可能已经有所发展或是发生改变。

    基于 RequireJS 的前端模块化设计 伴随着互联网的飞速发展, web 中对于前端的要求越来越高,前端的代码的代码量、复杂度与日俱增,带来了诸如前端代码复用率低,难维护等问题。针对这些现有问题,达观科技采用了 requirejs 框架,用模块化的思想去解决这些问题。(达观数据 施列宇) 一、什么是模块化 模块化是一种将复杂系统拆分成一个个小的可管理的模块的方式。它可以把系统拆分为职责更单一,更独立的模块,也就是我们软件设计中常常提到的高内聚低耦合的模块。一般来说,前端模块化包含 javascript , css 以及 template 三个部分。 二、为什么要将前端内容模块化 简单来说,随着互联网的发展,前端的要求越来越高,导致了前端复杂度高,可维护性差,代码重复率高,命名冲突等问题。模块化正是解决这一问题的良药。 通过模块化,可以将代码中常用的内容封装起来,这样就做到了代码复用,便于维护。像前端中常用到的 jQuery 框架,就可以被视为一个公共模块, jQuery 封装并简化了一系列常用的 js 操作,轻量级,功能强大,而且不会污染全局变量(所有的方法都只能通过 jQuery 对象调用),可以说是一个非常优秀的模块。并且,项目中往往也会存在一些不具备复用价值,但过于冗长的代码。我们也是鼓励将这些代码拆分多个相独立的模块,由此来提升可维护性。除此之外,模块化还可以带来不污染全局变量的效果。 Web 页面不复杂的情况下,我们可以任性的在全局环境下定义变量和函数,但在前端日益复杂化的今天,全局变量污染往往会带来命名冲突的问题,项目持续时间越久,累计的问题就会越多,维护的成本也就越高。 三、 JS 模块化的发展史 最早的 js 模块化是通过创建对象的方式来达到效果的。

    通过 js 对象实现模块化效果 一个 js 对象即是一个模块,这样的好处是很直观易懂,并且的确解决了全局污染的问题。与此同时,这种方法的问题也比较突出,那就是 js 对象的封闭性并不好,重要信息很容易泄露,带来的安全问题难以解决。 针对 js 对象的安全性问题, js 的模块化就选择使用闭包的方式来解决。也就是我们熟知的 IIFE(immediately-invoked function expression)模式。

    通过封闭性良好的匿名闭包,很好的对模块内容实行了封装。这种做法,已经可以很有效的解决了模块化过程中所遇到的问题,即使在现如今,也有很多流行的前端框架,通过这种方式实现模块化。

    typescript 中的模块编译后生成的 javascript 代码符合 IIFE 模式 IIFE 模式是现代模块化工具的基石,其引入参数的过程,是实现现代 js 模块化依赖注入的基本方式。 随着 js 模块化发展的日益深远, js 逐渐形成了模块定义的两大标准:通用模块定义 ( Common Module Definition) 以及异步模块定义 ( Asynchronous Module Definition)。 CMD 是以 seajs 为代表的模块化标准,特点是依赖就近。

    CMD 模式下模块调用方式 进入模块时,模块自身并不知道依赖哪些模块,如图中所示,代码在执行到一定阶段后,通过 require()方法引入需要用的模块,通过该函数返回的对象,调用模块的方法。这种做法的好处是,随时都可以调用外部模块而不用预定义,简单方便。但与此同时,在代码执行期间,需要不断的遍历工程多次来查找 require 对应模块的位置,这对代码的整体性能有所牺牲。 AMD 是以 requirejs 为代表的模块化标准,其特点是推崇依赖前置

    AMD 模式下模块调用方式 如图,在进入模块时,模块已经知道了依赖关系,只有在所有的依赖项加载完成时,模块内部代码才会被执行。这种写法的优点是,性能相比 CMD 要好,在模块运行时已经知道需要加载哪些模块,不再需要对整段代码进行遍历查找依赖。 顺便一提,我们在 requirejs 的官方文档中也会发现和 CMD 用法相同的 API ,但 requirejs 官方还是推荐使用 AMD 的方式来建立依赖关系。 四、 requirejs 实战 作为初创公司,达观数据倾向于采用成熟的健壮的开发框架进行前端开发,完善的解决方案以及丰富的插件库可以帮助项目主体快速成型。目前,达观大数据前端部分采用的是 angularjs + requirejs + gruntjs +bowerjs 的框架来实现前端设计。其中就用到了 requirejs 作为前端代码依赖管理工具。 1.首先我们可以通过 bower 来在项目中安装 requirejs , 不熟悉 bower 的同学可以参考 https://github.com/bower/bower 。

    通过 bower 一键安装 requirejs 到项目中 2.编写 requirejs 的配置文件。通过 requirejs 提供的 config 方法,编写 requirejs 的配置文件。这里介绍一些比较常见的参数。

    requirejs 的 config 文件需自己定义 baseUrl: baseUrl 用于改变依赖基本路径。一般而言,配置文件中模块定义路径是根据配置文件的位置计算出来的相对位置,这种情况下可以不用设置 baseUrl 。但如果项目需要迁移,那就需要改变模块存放的整体位置,这种情况下将每个模块的相对路径都进行更改是一件非常痛苦的事情。 requirejs 提供的 baseUrl 可以很好的解决这个问题,只需要重新设置 baseUrl 就可以不用更改配置文件中的每一条 path 。 paths: paths 定义每个模块的路径。一个模块可以有多个路径,这样假使通过第一个路径加载失败,也可以从后面定义的路径中获得该模块。 shim: shim 定义的是模块之间的依赖关系。实际项目中常常会遇到没有定义依赖关系的模块,这时我们需要通过 shim 参数手动定义每个模块的依赖项,使项目能够正常运行。 这样一个项目中的依赖部分就算完成了,之后在每个模块定义的时候,只要遵循 requirejs 模块定义语法,就可以实现 web 前端的模块化加载。 3.在 html 中加入 requirejs 的引用,并通过属性 data-main 加载项目中的入口脚本。

    在 html 中引入 requirejs 一般而言,项目引用的脚本文件需要代码管理工具进行合并、压缩、混淆操作。达观科技使用的是 grunt 脚本管理工具进行相关操作,这里使用到 grunt 提供的相应的插件 grunt-contrib-requirejs 来自动完成任务。 插件和 grunt 的一样,都是通过 node.js 提供的 npm 方法安装。安装完成时,可以在配置文件 package.json 查看到该插件。

    package.json 中存在 grunt-contrib-copy 的依赖项 确认该插件安装完成后,就可以在 grunt 的配置文件 Gruntfile.js 编写该插件的配置信息了。

    grunt-contrib-requirejs 在 Gruntfile.js 中的配置信息 其中几个核心参数的含义如下: baseUrl: 类似于上一节中 requirejs 配置参数中的 baseUrl ,如果 requirejs config 中没有指明,需要写上 requirejs config 所在的路径。 mainConfigFile: 指向的 requirejs 的配置文件。 out: out 指的最终输出的结果,值的注意的是该输出结果的路径不是相对于 baseUrl 的地址,而是相对于 Gruntfile.js 文件的地址。 更多配置的介绍可以查阅 https://github.com/gruntjs/grunt-contrib-requirejs 。 通过以上一系列的部署, requirejs 已经可以在 web 项目中产生作用了。 五、结束语 本文主要阐述了我对于 web 前端模块化的一些理解。简要的分析了 web 前端的模块化的含义,必要性,并适当介绍了前端模块化的发展的一些历程,最终通过 require 实战的方式,向各位读者传述如何在 web 工程中加入模块化架构设计。模块化设计可以减少项目的复杂度,提升项目的可维护度,并对代码复用,减少代码量产生了一定的作用。在实际工作中,前端模块化的设计已不鲜见,目前前端可用于模块化的框架不下于 10 款,掌握了模块化设计的思路,对选择合适的模块化框架很有益处。在前端日新月异的今天,新框架总会源源不断的涌现,开发者往往苦恼于如何选择合适的框架,其实只要掌握了核心思想,正如本文所说的模块化思想,才可以很快的对比出各个框架的优缺点,才会在这些框架的选择中游刃有余。(达观数据 施列宇)

    airyland
        1
    airyland  
       2016-03-20 14:37:50 +08:00 via iPhone
    排版用点心?
    关于   ·   帮助文档   ·   博客   ·   API   ·   FAQ   ·   实用小工具   ·   2713 人在线   最高记录 6679   ·     Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 · 33ms · UTC 00:03 · PVG 08:03 · LAX 16:03 · JFK 19:03
    Developed with CodeLauncher
    ♥ Do have faith in what you're doing.