而是一套 Web 前端解决方案,所以 Qing 不只是关注项目的初始状态,而是整体的工作流程,
这是 Qing 与现有开源的开发模版显著差异的一点。Qing 的体验必须是高效且愉悦的,拒绝繁琐与重复。
其足够的 Qing 量,只需 30 分钟内即可掌握最先进的 Web 开发技能。以下是 Qing 所基于的开发理念:
- 移动端优先,兼容 PC 端
- 向前看齐,基于 ES5 开发
- 模块化 Web 开发过程
- 自动构建与部署集成, 基于 Mod.js 工具
基于未来趋势的开发理念,Qing 旨在提供工程化方案。
平台与浏览器版本兼容:
- iOS 4.0+
- Android 2.2+
- IE 6+
- Chrome
- Firefox
- Safari
开始使用
可以通过以下任意一种方式开始使用 Qing 模版:
- 下载最新 Qing 模版包, 解压至目标目录
- 如果已安装 git,可使用 git clone 源码至目标目录:
1<span class="nv">$ </span>git clone https://github.com/AlloyTeam/Qing.git
- 如果已安装了 Mod.js, 推荐在目标目录执行:
1<span class="nv">$ </span>m download AlloyTeam/Qing
第一次使用
m download
命令,需要先安装mod-tar
插件:1<span class="nv">$ </span>npm install mod-tar -g - 如果您是一位女开发,请忽略下文直接联系笔者,深圳优先。
模版结构
团队的协作离不开一些基本的约定,Qing 约定以下文件目录结构:
1 2 3 4 5 6 7 8 9 10 11 12 13 |
. ├── css │ ├── main.css │ └── normalize.css ├── img ├── js │ ├── main.js │ └── vendor ├── tpl ├── .editorconfig ├── index.html └── Modfile.js |
- 目录
css
托管样式文件 - 目录
img
托管图片文件 - 目录
js
托管 JavaScript 文件 - 目录
tpl
托管模版文件 .editorconfig
约定团队基础代码风格index.html
是入口 HTML 文件Modfile.js
是 Mod.js 配置文件
模块化编程指引
Qing 推荐模块化的开发过程,模块化开发后无论在代码可维护性与复用,还是团队协作上都将变的更加直观、轻松与高效。
CSS 模块化
通过原生 CSS 内置的 @import 机制管理 CSS 模块,在构建过程中会自动合并压缩(在下文的优化章节也有说明):
1 2 3 4 |
<span class="k">@import</span> <span class="s2">"normalize.css"</span><span class="p">;</span> <span class="k">@import</span> <span class="s2">"widget1.css"</span><span class="p">;</span> <span class="k">@import</span> <span class="s2">"widget2.css"</span><span class="p">;</span> <span class="k">@import</span> <span class="s2">"widget3.css"</span><span class="p">;</span> |
JS 模块化
约定引入 AMD 规范来管理 JS 模块,关于第一次接触 AMD 的读者,笔者推荐可以先 Google 了解后再进行下一步:
1 2 3 4 |
<span class="c1">// main.js</span> <span class="nx">define</span><span class="p">([</span><span class="s2">"./app"</span><span class="p">],</span> <span class="kd">function</span><span class="p">(</span><span class="nx">app</span><span class="p">){</span> <span class="nx">app</span><span class="p">.</span><span class="nx">init</span><span class="p">()</span> <span class="p">})</span> |
1 2 3 4 5 6 |
<span class="c1">// app.js</span> <span class="nx">define</span><span class="p">(</span><span class="kd">function</span><span class="p">(){</span> <span class="k">return</span> <span class="p">{</span> <span class="nx">init</span><span class="o">:</span> <span class="kd">function</span><span class="p">(){}</span> <span class="p">}</span> <span class="p">})</span> |
HTML 模块化
HTML 模块指代 HTML 模版文件,通过 requirejs-tmpl
插件将 HTML 分模块管理,requirejs-tmpl
没有默认打包在 Qing 模版中,可手动下载
requirejs-tmpl 插件至 js 目录,或通过执行 m download:tmpl
命令自动安装插件:
1 2 3 4 |
<span class="c"><!-- tpl/headerTpl.html --></span> <span class="nt"><header></span><span class="err"><</span>%= title %><span class="nt"></header></span> <span class="c"><!-- HTMl模版可依赖其他HTML模块 --></span> <span class="err"><</span>%@ ./navTpl.html %> |
1 2 |
<span class="c"><!-- tpl/navTpl.html --></span> <span class="nt"><a</span> <span class="na">href=</span><span class="s">"<%= url %>"</span><span class="nt">></span>View On Github<span class="nt"></a></span> |
1 2 |
<span class="c"><!-- tpl/footerTpl.html --></span> <span class="nt"><footer></span><span class="err"><</span>%= copyright %><span class="nt"></header></span> |
在 HTML 模版的引入是基于 requirejs
的插件机制,所以在具体路径前需加上 tmpl!
前缀,表示其是 HTML 模版,例如:tmpl!../tpl/headerTpl.html
。
引用的模版已通过插件自动编译,得到的函数如 headerTpl
直接传入需要绑定的数据即可:
1 2 3 4 5 6 |
<span class="c1">// js/app.js</span> <span class="nx">define</span><span class="p">([</span><span class="s2">"tmpl!../tpl/headerTpl.html"</span><span class="p">,</span> <span class="s2">"tmpl!../tpl/footerTpl.html"</span><span class="p">],</span> <span class="kd">function</span><span class="p">(</span><span class="nx">headerTpl</span><span class="p">,</span> <span class="nx">footerTpl</span><span class="p">){</span> <span class="kd">var</span> <span class="nx">html1</span> <span class="o">=</span> <span class="nx">headerTpl</span><span class="p">({</span><span class="nx">title</span><span class="o">:</span> <span class="s2">"Hello Qing"</span><span class="p">,</span> <span class="nx">url</span><span class="o">:</span> <span class="s2">"http://github.com/AlloyTeam/Qing"</span><span class="p">})</span> <span class="kd">var</span> <span class="nx">html2</span> <span class="o">=</span> <span class="nx">footerTpl</span><span class="p">({</span><span class="nx">copyright</span><span class="o">:</span> <span class="s2">"AlloyTeam"</span><span class="p">})</span> <span class="c1">// balabala</span> <span class="p">})</span> |
自动化工具的环境安装
Mod.js 是基于 Node.js 的工作流工具,安装 Node.js 环境后使用 NPM 安装 Mod.js:
1 |
<span class="nv">$ </span>npm install modjs -g |
一键构建
成功安装 Mod.js 后, 进入 Modfile 所在的项目根目录,只需执行 m
命令,一切如此简单,如假包换的一键构建:
1 |
<span class="nv">$ </span>m |
执行完成后会在当前目录下生成 dist
目录输出构建后的结果。
性能优化
浏览器第一次请求服务器的过程至少需经过 3RTTs:DNS 域名解析 1RTT;TCP 连接建立 1RTT;HTTP 请求并且返回第一个比特的数据 1RTT。
而这在移动基站网络下请求则显得异常缓慢,在我们的监测中,在 2G 网络下仅 DNS 时间即可达到 200ms,性能不容乐观。
所以尽可能快的完成页面加载在移动端显得更加重要,而如何合理的减少页面初始资源请求数是加快页面加载最有效的方式:
合并 JS 模块
Qing 支持传统的手动模块加载管理与基于 AMD 的模块加载管理方式,同时我们推荐使用 Require.js 作为开发过程中的模块加载工具。
1 2 3 4 |
<span class="c"><!-- JS模块模块手动管理 --></span> <span class="nt"><script </span><span class="na">src=</span><span class="s">"js/fastclick.js"</span><span class="nt">></script></span> <span class="nt"><script </span><span class="na">src=</span><span class="s">"js/spin.js"</span><span class="nt">></script></span> <span class="nt"><script </span><span class="na">src=</span><span class="s">"js/main.js"</span><span class="nt">></script></span> |
传统的手动添加模块会自动合并,其按照合并连续引入资源的规则进行,最终输出:
1 |
<span class="nt"><script </span><span class="na">src=</span><span class="s">"js/89ef9b6e.fastclick_main_3_520.js"</span><span class="nt">></script></span> |
1 2 |
<span class="c"><!-- data-main属性值为执行入口JS文件地址 --></span> <span class="nt"><script </span><span class="na">data-main=</span><span class="s">"js/main"</span> <span class="na">src=</span><span class="s">"http://requirejs.org/docs/release/2.1.6/minified/require.js"</span><span class="nt">></script></span> |
通过模块加载器方式,Qing 会自动移除模块加载器本身,其并不打包进最终输出的文件:
1 |
<span class="nt"><script </span><span class="na">src=</span><span class="s">"js/89ef9b6e.main.js"</span><span class="nt">></script></span> |
Qing 默认开启的是移除 define
生成模块管理器无依赖代码的 stripDefine
优化模式。stripDefine
优化模式的配置在 Modfile.js
的 build 任务中:
1 2 3 4 |
<span class="nx">build</span><span class="o">:</span> <span class="p">{</span> <span class="nx">src</span><span class="o">:</span> <span class="s2">"./index.html"</span><span class="p">,</span> <span class="nx">stripDefine</span><span class="o">:</span> <span class="kc">true</span> <span class="p">}</span> |
在 stripDefine
优化模式下,基于 AMD 规范文件:
1 2 3 4 5 6 |
<span class="c1">// base/clone.js</span> <span class="nx">define</span><span class="p">(</span><span class="kd">function</span><span class="p">(){</span> <span class="k">return</span> <span class="kd">function</span><span class="p">(</span><span class="nx">obj</span><span class="p">){</span> <span class="k">return</span> <span class="nb">Object</span><span class="p">.</span><span class="nx">create</span><span class="p">(</span><span class="nx">obj</span><span class="p">)</span> <span class="p">}</span> <span class="p">})</span> |
1 2 3 4 |
<span class="c1">// foo.js</span> <span class="nx">define</span><span class="p">([</span><span class="s1">'./base/clone'</span><span class="p">],</span> <span class="kd">function</span><span class="p">(</span><span class="nx">clone</span><span class="p">){</span> <span class="k">return</span> <span class="nx">clone</span><span class="p">({</span><span class="nx">foo</span><span class="o">:</span><span class="mi">1</span><span class="p">})</span> <span class="p">})</span> |
1 2 3 4 |
<span class="c1">// bar.js</span> <span class="nx">define</span><span class="p">([</span><span class="s1">'./base/clone'</span><span class="p">],</span> <span class="kd">function</span><span class="p">(</span><span class="nx">clone</span><span class="p">){</span> <span class="k">return</span> <span class="nx">clone</span><span class="p">({</span><span class="nx">bar</span><span class="o">:</span><span class="mi">2</span><span class="p">})</span> <span class="p">})</span> |
1 2 3 4 5 |
<span class="c1">// main.js</span> <span class="nx">define</span><span class="p">(</span><span class="s1">'./foo'</span><span class="p">,</span> <span class="s1">'./bar'</span><span class="p">],</span> <span class="kd">function</span><span class="p">(</span><span class="nx">foo</span><span class="p">,</span> <span class="nx">bar</span><span class="p">){</span> <span class="nx">foo</span><span class="p">.</span><span class="nx">bar</span> <span class="o">=</span> <span class="mi">2</span><span class="p">;</span> <span class="nx">bar</span><span class="p">.</span><span class="nx">foo</span> <span class="o">=</span> <span class="mi">1</span><span class="p">;</span> <span class="p">})</span> |
编译后会在移除 define 的同时将模块代码转换为变量声明格式的代码:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 |
<span class="p">(</span><span class="kd">function</span><span class="p">(</span><span class="nb">window</span><span class="p">,</span> <span class="kc">undefined</span><span class="p">){</span> <span class="kd">var</span> <span class="nx">base_clone</span> <span class="o">=</span> <span class="p">(</span><span class="kd">function</span><span class="p">(){</span> <span class="k">return</span> <span class="kd">function</span><span class="p">(</span><span class="nx">obj</span><span class="p">){</span> <span class="k">return</span> <span class="nb">Object</span><span class="p">.</span><span class="nx">create</span><span class="p">(</span><span class="nx">obj</span><span class="p">)</span> <span class="p">}</span> <span class="p">})();</span> <span class="kd">var</span> <span class="nx">foo</span> <span class="o">=</span> <span class="p">(</span><span class="kd">function</span><span class="p">(</span><span class="nx">clone</span><span class="p">){</span> <span class="k">return</span> <span class="nx">clone</span><span class="p">({</span><span class="nx">bar</span><span class="o">:</span><span class="mi">2</span><span class="p">})</span> <span class="p">})(</span><span class="nx">base_clone</span><span class="p">);</span> <span class="kd">var</span> <span class="nx">foo</span> <span class="o">=</span> <span class="p">(</span><span class="kd">function</span><span class="p">(</span><span class="nx">clone</span><span class="p">){</span> <span class="k">return</span> <span class="nx">clone</span><span class="p">({</span><span class="nx">foo</span><span class="o">:</span><span class="mi">1</span><span class="p">})</span> <span class="p">})(</span><span class="nx">base_clone</span><span class="p">);</span> <span class="kd">var</span> <span class="nx">main</span> <span class="o">=</span> <span class="p">(</span><span class="kd">function</span><span class="p">(</span><span class="nx">foo</span><span class="p">,</span> <span class="nx">bar</span><span class="p">){</span> <span class="nx">foo</span><span class="p">.</span><span class="nx">bar</span> <span class="o">=</span> <span class="mi">2</span><span class="p">;</span> <span class="nx">bar</span><span class="p">.</span><span class="nx">foo</span> <span class="o">=</span> <span class="mi">1</span><span class="p">;</span> <span class="p">})(</span><span class="nx">foo</span><span class="p">,</span> <span class="nx">bar</span><span class="p">);</span> <span class="p">})(</span><span class="k">this</span><span class="p">)</span> |
合并 CSS @imports
在页面中引入了样式文件 css/main.css
:
1 |
<span class="nt"><link</span> <span class="na">rel=</span><span class="s">"stylesheet"</span> <span class="na">href=</span><span class="s">"css/main.css"</span><span class="nt">></span> |
而 css/main.css
中使用了 CSS@import
机制来引入其他模块的样式文件:
1 2 3 |
<span class="k">@import</span> <span class="s2">"foo.css"</span><span class="p">;</span> <span class="k">@import</span> <span class="s2">"bar.css"</span><span class="p">;</span> <span class="k">@import</span> <span class="s2">"baz.css"</span><span class="p">;</span> |
使用 CSS 原生 @import
机制模块化开发 CSS 是 Qing 推荐的方式,然不做优化直接发布到线上必然有性能问题,这是绝不允许的。
Qing 在构建的时候会自动侦测所有引入的样式文件是否使用了 @import
,并进行合并优化。
合并连续引入资源
当页面中引入了多个样式文件或脚本文件:
1 2 3 4 5 6 7 |
<span class="nt"><link</span> <span class="na">rel=</span><span class="s">"stylesheet"</span> <span class="na">href=</span><span class="s">"css/base.css"</span><span class="nt">></span> <span class="nt"><link</span> <span class="na">rel=</span><span class="s">"stylesheet"</span> <span class="na">href=</span><span class="s">"css/typo.css"</span><span class="nt">></span> <span class="nt"><link</span> <span class="na">rel=</span><span class="s">"stylesheet"</span> <span class="na">href=</span><span class="s">"css/main.css"</span><span class="nt">></span> <span class="nt"><script </span><span class="na">src=</span><span class="s">"js/fastclick.js"</span><span class="nt">></script></span> <span class="nt"><script </span><span class="na">src=</span><span class="s">"js/spin.js"</span><span class="nt">></script></span> <span class="nt"><script </span><span class="na">src=</span><span class="s">"js/main.js"</span><span class="nt">></script></span> |
构建程序会将多个连续的静态资源文件进行合并:
1 2 3 |
<span class="nt"><link</span> <span class="na">rel=</span><span class="s">"stylesheet"</span> <span class="na">href=</span><span class="s">"css/89ef9b6e.base_main_3_630.css"</span><span class="nt">></span> <span class="nt"><script </span><span class="na">src=</span><span class="s">"js/89ef9b6e.fastclick_main_3_520.js"</span><span class="nt">></script></span> |
data-rev 配置
Qing 会自动给所有优化后的静态资源加上类似 89ef9b6e.
的指纹标示前缀来区分版本,此行为是默认打开,
可以通过 data-no-rev
声明来关闭,也可以 data-rev
声明开启。
1 2 3 4 |
<span class="nt"><html</span> <span class="na">data-no-rev</span><span class="nt">></span> <span class="nt"><link</span> <span class="na">rel=</span><span class="s">"stylesheet"</span> <span class="na">href=</span><span class="s">"css/main.css"</span><span class="nt">></span> <span class="nt"><script </span><span class="na">data-rev</span> <span class="na">src=</span><span class="s">"js/main.js"</span><span class="nt">></script></span> <span class="nt"><img</span> <span class="na">src=</span><span class="s">"img/foo.png"</span><span class="nt">></span> |
如上通过在 HTML 标签中<html data-no-rev>
设置全局的策略,同时可在具体的标签上覆盖全局设置,如上构建后的结果:
1 2 3 4 |
<span class="nt"><html></span> <span class="nt"><link</span> <span class="na">rel=</span><span class="s">"stylesheet"</span> <span class="na">href=</span><span class="s">"css/main.css"</span><span class="nt">></span> <span class="nt"><script </span><span class="na">src=</span><span class="s">"js/89ef9b6e.main.js"</span><span class="nt">></script></span> <span class="nt"><img</span> <span class="na">src=</span><span class="s">"img/foo.png"</span><span class="nt">></span> |
data-stand-alone 配置
有时要求某个基础库文件如 jQuery 能被不同页面复用引入,而不是分别被打包在页面级别的资源包内,
如此利用浏览器天然的缓存机制使无需重新请求相同的资源内容,
Qing 在默认构建约定的基础上同时提供了基于 DOM 的 data-stand-alone
配置。
1 2 3 4 |
<span class="nt"><script </span><span class="na">data-stand-alone</span> <span class="na">src=</span><span class="s">"vendor/jquery-2.0.3.js"</span><span class="nt">></script></span> <span class="nt"><script </span><span class="na">src=</span><span class="s">"js/foo.js"</span><span class="nt">></script></span> <span class="nt"><script </span><span class="na">src=</span><span class="s">"js/bar.js"</span><span class="nt">></script></span> <span class="nt"><script </span><span class="na">src=</span><span class="s">"js/baz.js"</span><span class="nt">></script></span> |
构建结果:
1 2 |
<span class="nt"><script </span><span class="na">data-stand-alone</span> <span class="na">src=</span><span class="s">"vendor/92cf6237.jquery-2.0.3.js"</span><span class="nt">></script></span> <span class="nt"><script </span><span class="na">src=</span><span class="s">"js/92cf6237.foo_baz_3_168.js"</span><span class="nt">></script></span> |
data-group 配置
如何重复利用浏览器的并发请求数但同时考虑不至于有过多请求数上的负载,在不同场景下优化策略会有不同:
当需兼容 IE 老版本的情况下,初始并发请求数不推荐超过 2 个,但同时我们推荐单个资源包的大小 Gzip 前不超过 200k,
所以通常如何来控制打包粒度是需要监控数据来支撑的。Qing 在构建中提供了 data-group
分组参数来辅助打包粒度的控制:
1 2 3 4 5 6 |
<span class="nt"><script </span><span class="na">data-group=</span><span class="s">1</span> <span class="na">src=</span><span class="s">"js/foo.js"</span><span class="nt">></script></span> <span class="nt"><script </span><span class="na">data-group=</span><span class="s">1</span> <span class="na">src=</span><span class="s">"js/bar.js"</span><span class="nt">></script></span> <span class="nt"><script </span><span class="na">data-group=</span><span class="s">1</span> <span class="na">src=</span><span class="s">"js/baz.js"</span><span class="nt">></script></span> <span class="nt"><script </span><span class="na">data-group=</span><span class="s">2</span> <span class="na">src=</span><span class="s">"js/qux.js"</span><span class="nt">></script></span> <span class="nt"><script </span><span class="na">data-group=</span><span class="s">2</span> <span class="na">src=</span><span class="s">"js/quux.js"</span><span class="nt">></script></span> <span class="nt"><script </span><span class="na">data-group=</span><span class="s">2</span> <span class="na">src=</span><span class="s">"js/corge.js"</span><span class="nt">></script></span> |
构建结果:
1 2 |
<span class="nt"><script </span><span class="na">data-group=</span><span class="s">1</span> <span class="na">src=</span><span class="s">"js/92cf6237.foo_baz_3_168.js"</span><span class="nt">></script></span> <span class="nt"><script </span><span class="na">data-group=</span><span class="s">2</span> <span class="na">src=</span><span class="s">"js/090430cf.qux_corge_3_171.js"</span><span class="nt">></script></span> |
data-url-prepend 配置
资源 CDN 化是基本的优化策略,
1 2 3 4 5 6 7 |
<span class="nt"><html</span> <span class="na">data-url-prepend=</span><span class="s">"http://cdn1.qq.com/"</span><span class="nt">></span> <span class="nt"><script </span><span class="na">data-group=</span><span class="s">1</span> <span class="na">src=</span><span class="s">"js/foo.js"</span><span class="nt">></script></span> <span class="nt"><script </span><span class="na">data-group=</span><span class="s">1</span> <span class="na">src=</span><span class="s">"js/bar.js"</span><span class="nt">></script></span> <span class="nt"><script </span><span class="na">data-group=</span><span class="s">1</span> <span class="na">src=</span><span class="s">"js/baz.js"</span><span class="nt">></script></span> <span class="nt"><script </span><span class="na">data-group=</span><span class="s">2</span> <span class="na">data-url-prepend=</span><span class="s">"http://cdn2.qq.com/"</span> <span class="na">src=</span><span class="s">"js/qux.js"</span><span class="nt">></script></span> <span class="nt"><script </span><span class="na">data-group=</span><span class="s">2</span> <span class="na">src=</span><span class="s">"js/quux.js"</span><span class="nt">></script></span> <span class="nt"><script </span><span class="na">data-group=</span><span class="s">2</span> <span class="na">src=</span><span class="s">"js/corge.js"</span><span class="nt">></script></span> |
构建结果:
1 2 3 4 |
<html> <script data-group=1 src="http://cdn1.qq.com/js/92cf6237.foo_baz_3_168.js"></script> <script data-group=2 src="http://cdn2.qq.com/js/090430cf.qux_corge_3_171.js"></script> |
内嵌静态资源
所谓减少请求数最优的目标就是没有请求,Qing 提供了基于 QueryString 的 embed
配置使支持在构建时将静态资源内嵌于 HTML 中,
如此便可优化至最理想的情况:只需下载必不可少的 HTML 资源文件。
内嵌样式
1 2 3 |
<span class="nt"><link</span> <span class="na">rel=</span><span class="s">"stylesheet"</span> <span class="na">href=</span><span class="s">"css/base.css?embed"</span><span class="nt">></span> <span class="nt"><link</span> <span class="na">rel=</span><span class="s">"stylesheet"</span> <span class="na">href=</span><span class="s">"css/typo.css"</span><span class="nt">></span> <span class="nt"><link</span> <span class="na">rel=</span><span class="s">"stylesheet"</span> <span class="na">href=</span><span class="s">"css/main.css"</span><span class="nt">></span> |
构建结果:
1 2 3 4 5 |
<span class="nt"><style></span> <span class="nt">css</span><span class="o">/</span><span class="nt">base</span><span class="nc">.css</span><span class="o">...</span> <span class="nt">css</span><span class="o">/</span><span class="nt">typo</span><span class="nc">.css</span><span class="o">...</span> <span class="nt">css</span><span class="o">/</span><span class="nt">main</span><span class="nc">.css</span><span class="o">...</span> <span class="nt"></style></span> |
内嵌脚本
1 2 3 |
<span class="nt"><script </span><span class="na">src=</span><span class="s">"js/fastclick.js?embed"</span><span class="nt">></script></span> <span class="nt"><script </span><span class="na">src=</span><span class="s">"js/spin.js"</span><span class="nt">></script></span> <span class="nt"><script </span><span class="na">src=</span><span class="s">"js/main.js"</span><span class="nt">></script></span> |
构建结果:
1 2 3 4 5 |
<span class="nt"><script></span> <span class="nx">js</span><span class="o">/</span><span class="nx">fastclick</span><span class="p">.</span><span class="nx">js</span><span class="p">...</span> <span class="nx">js</span><span class="o">/</span><span class="nx">spin</span><span class="p">.</span><span class="nx">js</span><span class="p">...</span> <span class="nx">js</span><span class="o">/</span><span class="nx">main</span><span class="p">.</span><span class="nx">js</span><span class="p">...</span> <span class="nt"></script></span> |
内嵌图片
内嵌 CSS 里
1 2 3 4 5 |
<span class="nf">#foo</span> <span class="p">{</span> <span class="k">background</span><span class="o">:</span> <span class="sx">url('../img/icon.png?embed')</span> <span class="k">no-repeat</span><span class="p">;</span> <span class="k">height</span><span class="o">:</span> <span class="m">24px</span><span class="p">;</span> <span class="k">width</span><span class="o">:</span> <span class="m">24px</span> <span class="p">}</span> |
构建结果:
1 2 3 4 5 |
<span class="nf">#foo</span> <span class="p">{</span> <span class="k">background</span><span class="o">:</span> <span class="sx">url(data:image/png;base64,iVBORw0...)</span> <span class="k">no-repeat</span><span class="p">;</span> <span class="k">height</span><span class="o">:</span> <span class="m">24px</span><span class="p">;</span> <span class="k">width</span><span class="o">:</span> <span class="m">24px</span> <span class="p">}</span> |
内嵌 HTML 里
1 |
<span class="nt"><img</span> <span class="na">src=</span><span class="s">"./img/icon.png?embed"</span><span class="nt">></span> |
构建结果:
1 |
<span class="nt"><img</span> <span class="na">src=</span><span class="s">"data:image/png;base64,iVBORw0..."</span><span class="nt">></span> |
基础库
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/
目录:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 |
<span class="p">{</span> <span class="nx">options</span><span class="o">:</span> <span class="p">{</span> <span class="nx">dest</span><span class="o">:</span> <span class="s2">"js/vendor/"</span> <span class="p">},</span> <span class="nx">fastclick</span><span class="o">:</span> <span class="p">{</span> <span class="nx">src</span><span class="o">:</span> <span class="s2">"https://raw.github.com/ftlabs/fastclick/master/lib/fastclick.js"</span> <span class="p">},</span> <span class="nx">spin</span><span class="o">:</span> <span class="p">{</span> <span class="nx">src</span><span class="o">:</span> <span class="s2">"https://raw.github.com/fgnass/spin.js/gh-pages/dist/spin.js"</span> <span class="p">},</span> <span class="nx">zepto</span><span class="o">:</span> <span class="p">{</span> <span class="nx">src</span><span class="o">:</span> <span class="s2">"http://zeptojs.com/zepto.js"</span> <span class="p">},</span> <span class="nx">jquery1</span><span class="o">:</span> <span class="p">{</span> <span class="nx">src</span><span class="o">:</span> <span class="s2">"http://code.jquery.com/jquery-1.10.2.js"</span> <span class="p">},</span> <span class="nx">jquery2</span><span class="o">:</span> <span class="p">{</span> <span class="nx">src</span><span class="o">:</span> <span class="s2">"http://code.jquery.com/jquery-2.0.3.js"</span> <span class="p">},</span> <span class="nx">requirejs</span><span class="o">:</span> <span class="p">{</span> <span class="nx">src</span><span class="o">:</span> <span class="s2">"http://requirejs.org/docs/release/2.1.9/comments/require.js"</span> <span class="p">},</span> <span class="nx">tmpl</span><span class="o">:</span> <span class="p">{</span> <span class="nx">dest</span><span class="o">:</span> <span class="s1">'js/'</span><span class="p">,</span> <span class="nx">src</span><span class="o">:</span> <span class="s2">"https://raw.github.com/modulejs/requirejs-tmpl/master/tmpl.js"</span> <span class="p">}</span> <span class="p">}</span> |
下载全部库至本地方式非常简单,只需在根目录下执行:
1 |
<span class="nv">$ </span>m vendor |
如只需下载 Zepto:
1 |
<span class="nv">$ </span>m download:zepto |
社区
需求、改进与建议,可在 Github issues 提单,会一一解答。同时 Qing 是面向社区的开源项目,
邀请社区朋友共同参与贡献,如你觉得 Qing 很棒很酷,也可以帮助我们在微博与博客中推广与传播。
幸运儿 2015 年 7 月 31 日
请问 现在还有项目用这个吗?求实例
海宝 2014 年 12 月 1 日
“如果您是一位女开发,请忽略下文直接联系笔者,深圳优先。” 哈哈
苦逼前端 2014 年 5 月 14 日
女开发表示。。。真的看不懂
sallon 2014 年 2 月 24 日
你好,我给个建议,对于一个开源的 webUI 框架来讲的话,我还是比较喜欢一个能够看到现成实例的理解的更为透彻些。有一个 UI 框架可以参考下 Jingle ui===========http://vycool.com/Jingle/
哈哈MX 2014 年 1 月 2 日
我只是进来看下的
天满流云 2013 年 12 月 16 日
所有图片都内嵌?是否耗内存?
赵鹏超 2013 年 12 月 2 日
你好笔者, 我是男的在深圳我可以先排队领个号吗?
61 2013 年 11 月 30 日
git clone https://github.com/AlloyTeam/Qing.git 下来,在当前目录执行 m, 然后打开 dist 目录里的 index.html 会报错 define is not defined
sheranli 2013 年 11 月 29 日
笔者你好,我在深圳,你懂的~
jon 2013 年 11 月 29 日
模块化的写法很像 seaJs,都是 AMD 规范的
scgy5555 2013 年 11 月 29 日
能做 mobile 的根本不需要,需要做 mobile 的根本不会用
于江水 2013 年 11 月 28 日
“如果您是一位女开发,请忽略下文直接联系笔者,深圳优先。” 哈哈