面向工程的移动 Web 开发模版 Qing
In 未分类 on 2013年11月28日 by view: 23,867
12
什么是 Qing?Qing 是一套基础开发模版,来源于我们在手机与 PC 端上的大量工程实践。Qing 所提供不是冷冰冰的文件,
而是一套 Web 前端解决方案,所以 Qing 不只是关注项目的初始状态,而是整体的工作流程,
这是 Qing 与现有开源的开发模版显著差异的一点。Qing 的体验必须是高效且愉悦的,拒绝繁琐与重复。
其足够的 Qing 量,只需 30 分钟内即可掌握最先进的 Web 开发技能。以下是 Qing 所基于的开发理念:

  1. 移动端优先,兼容 PC 端
  2. 向前看齐,基于 ES5 开发
  3. 模块化 Web 开发过程
  4. 自动构建与部署集成, 基于 Mod.js 工具

基于未来趋势的开发理念,Qing 旨在提供工程化方案。

平台与浏览器版本兼容:

  • iOS 4.0+
  • Android 2.2+
  • IE 6+
  • Chrome
  • Firefox
  • Safari

开始使用

可以通过以下任意一种方式开始使用 Qing 模版:

  1. 下载最新 Qing 模版包, 解压至目标目录
  2. 如果已安装 git,可使用 git clone 源码至目标目录:
  3. 如果已安装了 Mod.js, 推荐在目标目录执行:

    第一次使用 m download 命令,需要先安装 mod-tar 插件:

  4. 如果您是一位女开发,请忽略下文直接联系笔者,深圳优先。

模版结构

团队的协作离不开一些基本的约定,Qing 约定以下文件目录结构:

  • 目录 css 托管样式文件
  • 目录 img 托管图片文件
  • 目录 js 托管 JavaScript 文件
  • 目录 tpl 托管模版文件
  • .editorconfig 约定团队基础代码风格
  • index.html 是入口 HTML 文件
  • Modfile.js 是 Mod.js 配置文件

模块化编程指引

Qing 推荐模块化的开发过程,模块化开发后无论在代码可维护性与复用,还是团队协作上都将变的更加直观、轻松与高效。

CSS 模块化

通过原生 CSS 内置的 @import 机制管理 CSS 模块,在构建过程中会自动合并压缩(在下文的优化章节也有说明):

JS 模块化

约定引入 AMD 规范来管理 JS 模块,关于第一次接触 AMD 的读者,笔者推荐可以先 Google 了解后再进行下一步:

HTML 模块化

HTML 模块指代 HTML 模版文件,通过 requirejs-tmpl 插件将 HTML 分模块管理,requirejs-tmpl 没有默认打包在 Qing 模版中,可手动下载
requirejs-tmpl 插件至 js 目录,或通过执行 m download:tmpl
命令自动安装插件:

在 HTML 模版的引入是基于 requirejs 的插件机制,所以在具体路径前需加上 tmpl! 前缀,表示其是 HTML 模版,例如:tmpl!../tpl/headerTpl.html
引用的模版已通过插件自动编译,得到的函数如 headerTpl 直接传入需要绑定的数据即可:

自动化工具的环境安装

  1. 安装 Node.js
  2. 安装 Mod.js

Mod.js 是基于 Node.js 的工作流工具,安装 Node.js 环境后使用 NPM 安装 Mod.js:

一键构建

成功安装 Mod.js 后, 进入 Modfile 所在的项目根目录,只需执行 m 命令,一切如此简单,如假包换的一键构建:

执行完成后会在当前目录下生成 dist 目录输出构建后的结果。

性能优化

浏览器第一次请求服务器的过程至少需经过 3RTTs:DNS 域名解析 1RTT;TCP 连接建立 1RTT;HTTP 请求并且返回第一个比特的数据 1RTT。
而这在移动基站网络下请求则显得异常缓慢,在我们的监测中,在 2G 网络下仅 DNS 时间即可达到 200ms,性能不容乐观。
所以尽可能快的完成页面加载在移动端显得更加重要,而如何合理的减少页面初始资源请求数是加快页面加载最有效的方式:

合并 JS 模块

Qing 支持传统的手动模块加载管理与基于 AMD 的模块加载管理方式,同时我们推荐使用 Require.js 作为开发过程中的模块加载工具。

传统的手动添加模块会自动合并,其按照合并连续引入资源的规则进行,最终输出:

通过模块加载器方式,Qing 会自动移除模块加载器本身,其并不打包进最终输出的文件:

Qing 默认开启的是移除 define 生成模块管理器无依赖代码的 stripDefine 优化模式。stripDefine 优化模式的配置在 Modfile.js 的 build 任务中:

stripDefine 优化模式下,基于 AMD 规范文件:

编译后会在移除 define 的同时将模块代码转换为变量声明格式的代码:

合并 CSS @imports

在页面中引入了样式文件 css/main.css

css/main.css 中使用了 CSS@import 机制来引入其他模块的样式文件:

使用 CSS 原生 @import 机制模块化开发 CSS 是 Qing 推荐的方式,然不做优化直接发布到线上必然有性能问题,这是绝不允许的。

Qing 在构建的时候会自动侦测所有引入的样式文件是否使用了 @import,并进行合并优化。

合并连续引入资源

当页面中引入了多个样式文件或脚本文件:

构建程序会将多个连续的静态资源文件进行合并:

data-rev 配置

Qing 会自动给所有优化后的静态资源加上类似 89ef9b6e. 的指纹标示前缀来区分版本,此行为是默认打开,
可以通过 data-no-rev 声明来关闭,也可以 data-rev 声明开启。

如上通过在 HTML 标签中<html data-no-rev> 设置全局的策略,同时可在具体的标签上覆盖全局设置,如上构建后的结果:

data-stand-alone 配置

有时要求某个基础库文件如 jQuery 能被不同页面复用引入,而不是分别被打包在页面级别的资源包内,
如此利用浏览器天然的缓存机制使无需重新请求相同的资源内容,
Qing 在默认构建约定的基础上同时提供了基于 DOM 的 data-stand-alone 配置。

构建结果:

data-group 配置

如何重复利用浏览器的并发请求数但同时考虑不至于有过多请求数上的负载,在不同场景下优化策略会有不同:
当需兼容 IE 老版本的情况下,初始并发请求数不推荐超过 2 个,但同时我们推荐单个资源包的大小 Gzip 前不超过 200k,
所以通常如何来控制打包粒度是需要监控数据来支撑的。Qing 在构建中提供了 data-group 分组参数来辅助打包粒度的控制:

构建结果:

data-url-prepend 配置

资源 CDN 化是基本的优化策略,

构建结果:

内嵌静态资源

所谓减少请求数最优的目标就是没有请求,Qing 提供了基于 QueryString 的 embed 配置使支持在构建时将静态资源内嵌于 HTML 中,
如此便可优化至最理想的情况:只需下载必不可少的 HTML 资源文件。

内嵌样式

构建结果:

内嵌脚本

构建结果:

内嵌图片
内嵌 CSS 里

构建结果:

内嵌 HTML 里

构建结果:

基础库

Qing 总是想法设法的让开发过程更自动更流畅,在 Qing 模版的 Modfile.js 中提供了以下第三方库的下载配置:

  • FastClick
  • Spin.js
  • Zepto
  • jQuery 1.x
  • jQuery 2.x
  • require.js 2.1.9
  • requirejs-tmpl

截取 Modfile.js 中关于第三方库的配置,src 表示源地址,dest 表示下载目录,
除了 tmpl 插件下载至 js/目录其他所有第三方库都默认下载至 js/vendor/目录:

下载全部库至本地方式非常简单,只需在根目录下执行:

如只需下载 Zepto:

社区

需求、改进与建议,可在 Github issues 提单,会一一解答。同时 Qing 是面向社区的开源项目,
邀请社区朋友共同参与贡献,如你觉得 Qing 很棒很酷,也可以帮助我们在微博与博客中推广与传播。

原创文章转载请注明:

转载自AlloyTeam:http://www.alloyteam.com/2013/11/mobile-web-project-template-qing/

  1. 幸运儿 2015 年 7 月 31 日

    请问 现在还有项目用这个吗?求实例

  2. 海宝 2014 年 12 月 1 日

    “如果您是一位女开发,请忽略下文直接联系笔者,深圳优先。” 哈哈

  3. 苦逼前端 2014 年 5 月 14 日

    女开发表示。。。真的看不懂

  4. sallon 2014 年 2 月 24 日

    你好,我给个建议,对于一个开源的 webUI 框架来讲的话,我还是比较喜欢一个能够看到现成实例的理解的更为透彻些。有一个 UI 框架可以参考下 Jingle ui===========http://vycool.com/Jingle/

  5. 哈哈MX 2014 年 1 月 2 日

    我只是进来看下的

  6. 天满流云 2013 年 12 月 16 日

    所有图片都内嵌?是否耗内存?

  7. 赵鹏超 2013 年 12 月 2 日

    你好笔者, 我是男的在深圳我可以先排队领个号吗?

  8. sheranli 2013 年 11 月 29 日

    笔者你好,我在深圳,你懂的~

  9. jon 2013 年 11 月 29 日

    模块化的写法很像 seaJs,都是 AMD 规范的

  10. scgy5555 2013 年 11 月 29 日

    能做 mobile 的根本不需要,需要做 mobile 的根本不会用

  11. 于江水 2013 年 11 月 28 日

    “如果您是一位女开发,请忽略下文直接联系笔者,深圳优先。” 哈哈

发表评论到 jon