├── README.md └── chapter ├── build.md ├── directory.md ├── flow-spec.md ├── mock.md └── technology-stack.md /README.md: -------------------------------------------------------------------------------- 1 | # 前端工程指导 2 | 3 | 本书会展示前端工程从0到100的过程,并提供实现指导。各个团队负责人根据自己团队情况进行实现。并让项目开发人员阅读本项目,便于理解并遵守工程规范。 4 | 5 | > 如果你要实现适合自己团队的前端工程,请务必详细阅读每一个章节,和每一个章节中链接到的其他页面。 6 | 7 | ## 章节 8 | 9 | 1. [文件目录](./chapter/directory.md) 10 | 2. [构建系统](./chapter/build.md) 11 | 3. [技术选型](./chapter/technology-stack.md) 12 | 4. ~[数据模拟](./chapter/mock.md)~ 13 | 5. [流程规范](./chapter/flow-spec.md) 14 | 6. ~[通用代码](./chapter/base-code.md)~ 15 | 7. ~[组件生态](./chapter/components.md)~ 16 | -------------------------------------------------------------------------------- /chapter/build.md: -------------------------------------------------------------------------------- 1 | # 构建系统 2 | 3 | 上一章:[文件目录](./directory.md) 4 | 5 | --- 6 | 7 | ## 为什么需要构建系统 8 | 9 | 在上一章[文件目录](./directory.md)中的文件结构,存在一些未解决的问题。 10 | 11 | `/m/btn/index.less` 如果要在视图代码中使用,不使用构建系统分别可以通过以下3种方式使用。 12 | 13 | 1. 在 `/view/login/index.html` 中通过 `` 引用 14 | 2. 在 `/view/login/index.css` 中通过 `@import url(../../m/btn/index.css)`; 引用 15 | 3. 复制 `/m/btn/index.css` 文件内容到 `/view/login/index.css` 中 16 | 17 | 1和2两种方式都会增加一个新的HTTP请求数,页面需要加载 `/m/btn/index.css` 和 `/view/login/index.css`。第三种方式很傻不易于维护 btn 样式一旦修改就要手动同步到多个地方。 18 | 19 | 可能读者会有疑问: 20 | 21 | > 直接把 btn 代码写到 view/pc/index.css 然后在所有页面调用这个css文件就解决了资源重复加载和手动同步的问题。 22 | 23 | 但是 btn 模块的代码放在 `view/pc/index.css` 中,违反了[文件目录](./directory.md)中提到的**资源就近维护**的原则。 24 | 25 | 这时我们就要使用CSS预处理器来帮助我们解决这个问题。比如 [Less](http://less.bootcss.com/) [Sass](https://www.sass.hk/)。 26 | 27 | 比如在 Less 中可以通过 `@import (less) "../m/btn/index.css";` `@import "../m/btn/index.less";` 或 的方式引入 css 或 less 。 28 | 29 | ```less 30 | // view/login/index.less 31 | @import (less) "../m/btn/index.css"; 32 | .login-title { 33 | font-size:20px; 34 | } 35 | ``` 36 | 37 | 通过编译文件会变成 38 | 39 | ```css 40 | /* view/login/index.less */ 41 | .m-btn { 42 | border:1px solid #EEE; 43 | background-color: #fafafa; 44 | color:#333; 45 | box-sizing: border-box; 46 | } 47 | .m-btn--danger { 48 | color:pink; 49 | border-color:red; 50 | } 51 | .login-title { 52 | font-size:20px; 53 | } 54 | ``` 55 | 56 | 还需要让构建系统检测 `/m/btn/index.css` 和 `/view/login/index.less` 被修改时立即编译 less。 57 | 58 | 而 `/m/switchClass/index.js` 也会遇到跟 `/m/btn/index.css` 相同的问题,这在JS方面统一使用 webpack 解决。[webpack-book](https://github.com/onface/webpack-book) 59 | 60 | ## 构建系统不等于前端工程 61 | 62 | 本书的章节顺序是[文件目录](./directory.md)在**构建系统**的前面,是为了纠正一个问题。 63 | 64 | 一定要先知道问题是什么,然后用构建工具解决这个问题。而不是学会了构建工具的使用,就按照固定的使用方式解决问题。 65 | 66 | 构建工具教程的的使用示例都只是单一场景,因为它是教程所以没法做到覆盖所有项目情况。需要使用者自己根据项目情况深思熟虑后判断如何使用。 67 | 68 | ## 构建工具对源码的侵入越少越好 69 | 70 | **px to rem**(不要用这个方案) 71 | 72 | ```css 73 | /* 源码 */ 74 | body { 75 | border-top: 1px; 76 | border-bottom: 10px; 77 | padding: 10px; /* @norem */ 78 | background-size: 10px 10px; /* @rem */ 79 | } 80 | ``` 81 | 82 | ```css 83 | /* 输出 */ 84 | body { 85 | border-top: 1px; 86 | border-bottom: 0.5557rem; 87 | padding: 10px; 88 | background-size: 0.5557rem 0.5557rem; 89 | } 90 | ``` 91 | 92 | 直接阅读源码会认为 body的各项单位设置的就是px,会带来误导。而且 `/* @norem */` 的标记非常麻烦。 93 | 94 | **less function** 95 | 96 | 编译 rem 这种需求应该使用CSS预处理器的函数功能解决 97 | 98 | [less-rem](https://github.com/onface/less-rem) 99 | 100 | ```less 101 | // 源码 102 | @import "./rem"; 103 | .demo { 104 | width:rem(640); 105 | height:rem(100); 106 | box-shadow: rem(11) rem(22) rem(33) pink; 107 | background: #eee; 108 | } 109 | ``` 110 | 111 | ```less 112 | // rem.less 113 | .function { 114 | .rem(@size) { 115 | // 640 是设计稿宽度 116 | // 640 is psd width 117 | return: @size/(640/320*16)+0rem; 118 | } 119 | } 120 | ``` 121 | 122 | ```css 123 | /* 输出 */ 124 | .demo { 125 | width: 20rem; 126 | height: 3.125rem; 127 | box-shadow: 0.34375rem 0.6875rem 1.03125rem pink; 128 | background: #eee; 129 | } 130 | ``` 131 | 132 | 直接阅读源码可以追踪到 `rem.less` 就会明白这个项目的 rem 计算标准是什么 133 | 134 | 135 | ## 构建工具的选择 136 | 137 | **因为自己搭建前端工程的构建系统才需要看这一部分所以内容移动到了 [issues](https://github.com/onface/workflow/issues/1)**,各种坑都在 issues 中。 138 | 139 | ## 构建工具的组合 140 | 141 | gulp fis webpack 应该组合使用,因为: 142 | 143 | 1. gulp 虽然有 [gulp-webpack](https://www.npmjs.com/package/gulp-webpack) 但是构建速度完全比不上**单独启动一个服务器加上 [webpack-hot-middleware](https://www.npmjs.com/package/webpack-hot-middleware)** 。 144 | 2. fis3 虽然有 [fis3-parser-webpack](https://www.npmjs.com/package/fis3-parser-webpack) 但是做不到异步加载和热更新。 145 | 3. webpack 虽然能[提取单独样式文件](https://github.com/onface/webpack-book/tree/gh-pages/6-extract-text) 但是不可能用它提取所有文件。还是需要 fis3 或者 gulp 构建非JS文件。 146 | 147 | > 所以 `gulp-webpack` `fis3-parser-webpack` `webpack提取单独样式文件` 都不要用。 148 | 149 | 那么就要选择 gulp 或 fis3 作为构建工具。因为 [静态资源映射表](http://fis.baidu.com/fis3/docs/lv3.html#%E5%9F%BA%E4%BA%8E%E9%9D%99%E6%80%81%E8%B5%84%E6%BA%90%E7%9A%84%E6%A8%A1%E5%9D%97%E5%8C%96%E6%96%B9%E6%A1%88%E8%AE%BE%E8%AE%A1) 的原因,作者选择 fis3。当然你也可以选择 gulp ,毕竟可以改造它们以满足自己的需求。**只是时间成本和技术成本都很高,对两个构建工具做详细了解后选择改造工作量最小的**。时间充裕的情况下多花点时间了解(磨刀不误砍柴工)。 150 | 151 | 本地开发阶段:非 js 文件用 gulp fis3 构建,js文件使用 `webpack-dev-middleware` 和 `webpack-hot-middleware` 构建。因为 `webpack-dev-middleware` 速度非常快。 152 | 153 | > 如果选择 fis3 注意:最终构建时,先用fis3构建一遍所有文件,然后用webpack构建一遍js文件,都构建到同一个文件夹。然后再用fis3 构建一次生成文件指纹的文件(md5)。因为 js 交给 webpack 构建所以不能达到直接用fis3构建所有文件并加上文件指纹。 154 | 155 | ## 参考 156 | 157 | [onface/react-project](https://github.com/onface/react-project) 是基于 react 技术栈的前端工程解决方案 158 | 159 | ## markrun 160 | 161 | [markrun](https://github.com/markrun/markrun) 主要的功能是 162 | 163 | **源码** 164 | 165 | ````js 166 | document.title = "js - basic a 18" 167 | ```` 168 | 169 | **输出** 170 | 171 | ```html 172 |
173 |     document.title = "js - basic a 18"
174 | 
175 | 178 | ``` 179 | 180 | [![](https://github.com/markrun/markrun/raw/master/doc/media/preview.png)](https://markrun.github.io/markrun/) 181 | 182 | 利用 markrun 配合构建系统就能在 `/m/**/README.md` 中 编写一份代码,生成的html中出现 `pre` 和 `script/style/html` 183 | 184 | 单独列出 markrun 是因为提高了模块的文档编写速度开发人员就更愿意写文档,能在开发模块的同时完成简单的使用示例编写。 185 | 186 | --- 187 | 188 | 下一章:[技术选型](./technology-stack.md) 189 | -------------------------------------------------------------------------------- /chapter/directory.md: -------------------------------------------------------------------------------- 1 | ## 文件目录 2 | 3 | 项目代码可以分为两类 4 | 5 | 1. 模块代码 module 6 | 2. 视图代码 view 7 | 8 | > 注意是**视图代码**而不是*业务逻辑代码*,因为业务逻辑可以封装成模块。 9 | 10 | 当你刚入行开发一个企业站时,只需要写视图代码。比如 11 | 12 | ```js 13 | $(function () { 14 | $('.js-btn').on('click', function () { 15 | $('.js-text').toggleClass('light') 16 | }) 17 | }) 18 | ``` 19 | 随着技能的提升会将某些可复用的业务代码写成一个函数以便以重复使用。比如 20 | 21 | ```js 22 | function switchClass(element, target, className){ 23 | $(element).on('click', function () { 24 | $(target).toggleClass(className) 25 | }) 26 | } 27 | ``` 28 | 29 | > 实际工作中会对一些复杂的模块进行封装,不像 这里的 `switchClass()` 这么简单。 30 | 31 | 也会对某些CSS进行封装便于复用 32 | 33 | ```html 34 | 35 | 确认 36 | 删除 37 | ``` 38 | 39 | ```css 40 | /* btn.css */ 41 | .m-btn { 42 | border:1px solid #EEE; 43 | background-color: #fafafa; 44 | color:#333; 45 | box-sizing: border-box; 46 | } 47 | .m-btn--danger { 48 | color:pink; 49 | border-color:red; 50 | } 51 | ``` 52 | 53 | 很多项目的代码会根据文件类型的不同存放在不同的文件夹下 54 | 55 | ``` 56 | css/ 57 | - common.css # 将 btn 的样式写在 common.css 中 58 | img/ 59 | - logo.png 60 | js/ 61 | - common.js # 将 switchClass()写在 common.js 中 62 | - news.js 63 | - login.js 64 | - index.js 65 | html/ 66 | - news.html 67 | - login.html 68 | - index.html 69 | ``` 70 | 71 | 这种方式在页面越来越多时会难以维护,有时还需要在多个目录不停的切换。 72 | 73 | 为了便于检索,我们可以将模块代码和视图代码分别放在 `m` 和 `view` 文件夹下。 74 | 75 | **相关资源就近维护** 76 | 77 | ```shell 78 | m/ 79 | btn/ 80 | - loading.png 81 | - index.css 82 | - README.html # 编写 btn 的 html 示例 83 | switchClass/ 84 | - index.js 85 | - README.html # 编写 switchClass 的使用示例 86 | view/ # 调用模块代码和一些不需要封装的逻辑代码 87 | pc/ 88 | - base.js # 底层库(jQuery React Vue 等) 89 | - index.js # 公用界面代码(控制导航栏搜索展开,点击底部客服弹出窗口) — 单页应用则不需要 pc/index.js pc/index.css — 90 | - index.css # 存放 normalize.css 和少量公用样式,(不要使用 CSS Reset) 91 | login/ 92 | - index.js # 调用 m/swtich/index.js 提供的 swtich() 93 | - index.html # 引入 m/btn/index.css 和使用 确认 94 | - logo.png 95 | - index.css 96 | ``` 97 | 98 | 不命名为 `view/common` 而命名为 `view/pc` 是因为随着项目需求的变化,可能会出现 `view/mobile` 。 99 | 100 | 不只是相关资源就近维护了,还增加了 `/m/btn/README.html` 和 `/m/switch/README.html` 文件。 101 | 102 | README.html 的文件内容是: 103 | 104 | ```html 105 | 106 | 107 | 确认 108 | 删除 109 | ``` 110 | 111 | ```html 112 | 113 | 114 | Abcdef 115 | 116 | 117 | 120 | ``` 121 | 122 | 此处的两个 README.html 文件中编写当前模块的使用示例。这样其他同事想要使用这个模块时可以通过文档快速了解用哪些用法,不需要询问开发者。 123 | 124 | 继续维护这个模块时,我们会需要对已有的模块代码进行修改。不知道模块代码会被如何使用的情况下是不敢轻易修改的,但是参照着示例修改就能知道本次修改会不会影响到某一种示例。(复杂的模块最好写单元测试) 125 | 126 | **模块再小都要写示例,磨刀不误砍柴工。** 127 | 128 | ## 小结 129 | 130 | 1. 资源就近维护 131 | 2. 代码分为模块代码和视图代码 132 | 3. 模块一定要编写文档和示例 133 | 4. 使用 `/view/pc` 文件夹替代 `/common`,便于后续增加 `/view/mobile` 134 | 135 | ```shell 136 | m/ 137 | btn/ 138 | switchClass/ 139 | view 140 | pc/ 141 | - base.js 142 | - **.** 143 | login/ 144 | ``` 145 | 146 | --- 147 | 148 | 下一章:[构建](./build.md) 149 | -------------------------------------------------------------------------------- /chapter/flow-spec.md: -------------------------------------------------------------------------------- 1 | # 流程规范 2 | 3 | ## 开发规范 4 | 5 | ### 为什么需要开发规范 6 | 7 | 团队需要开发规范,每个人都按照开发规范编码便于协同开发。每一个人都是不同的个体,对于什么样的代码是优秀的代码都有自己的理解。开发规范能一定程度上**统一代码风格**,**避免写出不易于维护的代码**和提供一些**好的编程技巧**。 8 | 9 | 举个反例: 10 | 11 | 公司有四名前端,对于 class 命名他们的代码分别是 12 | 13 | ```html 14 | 15 |
16 |

标题

17 |
内容
18 |
19 | 20 | 21 |
22 |

标题

23 |
内容
24 |
25 | 26 | 27 |
28 |

标题

29 |
内容
30 |
31 | 32 | 33 |
34 |

标题

35 |
内容
36 |
37 | ``` 38 | 39 | 这四个人同时维护一个项目,他们对于 class 命名的方式都不相同。B维护C的代码非常别扭,因为B使用 `_` 连接单词,C是使用驼峰命名连接。B使用 `-` 分割词组,C使用 `_` 分割词组。完全相反。非常不利于协同开发。 40 | 41 | 如果开发规范统一采用 A 的命名方式,使用驼峰命名,使用 `-` 分割词组。`统一代码风格`大家就能更好的协同开发了。 42 | 43 | > 这个例子中 A B C 关于单词连接方式和分割词组方式只是风格不同,任选其一就可以了。 44 | 45 | 而 D 的代码有严重问题,按照 D 的命名方式写出的 CSS 是: 46 | 47 | ```css 48 | .articlebox { ... } 49 | .articlebox .title{ ... } 50 | .articlebox .cnt{ ... } 51 | ``` 52 | 53 | 如果在 `
` 又增加了一些 HTML 就会出现问题 54 | 55 | ```html 56 |
57 |

标题

58 |
59 |
60 | a 61 | b 62 |
1
63 |
2
64 |
65 |
66 |
67 | ``` 68 | 69 | ```css 70 | .articlebox { ... } 71 | .articlebox .title{ ... } 72 | .articlebox .cnt{ 73 | color: red; 74 | border: 1px solid skyblue 75 | } 76 | .tab .cnt { 77 | color: blue; 78 | } 79 | ``` 80 | 81 | 打开浏览器会看到 `.tab` 下面的 `.cnt` 也出现了 蓝色的边框,因为 `.articlebox .cnt{...}` 规则命中了 `
1
2
` 82 | 83 | 想要解决这个问题就需要改成 84 | 85 | ```css 86 | .articlebox>.cnt { 87 | color: red; 88 | border: 1px solid skyblue 89 | } 90 | ``` 91 | 92 | 但是随着层级越来越多,CSS权重就越来越高。权重越来越高以后会造成**用更高的权重覆盖其他规则的恶性循环**。 93 | 94 | 改为 A B C 所使用的结构命名法能`避免写出不易于维护的代码`。 95 | 96 | > 这里只是用 CSS 命名举例, JS不制订开发规范也会遇到类似问题。 97 | 98 | 扩展阅读:[Trees - 基于树结构的CSS命名规范](https://github.com/onface/trees) 99 | 100 | ### 如何制订适合自己团队的开发规范 101 | 102 | 以制订 CSS 命名规范为例,很多前端都去搜索引擎搜索过CSS命名规范。 103 | 104 | 会有一些看起来很有道理,**实际上解决不了根本问题的规范**。 105 | 106 | 比如: 107 | 108 | > CSS书写顺序:位置属性 -> 大小 -> 文字 -> 背景 -> 其他 109 | 110 | > 尽量使用CSS缩写属性 111 | 112 | > 16进制颜色代码缩写 113 | 114 | > CSS样式表文件命名:主要的 master.css - 模块 module.css - 基本共用 base.css - 布局、版面 layout.css - 主题 themes.css - 专栏 columns.css - 文字 font.css - 表单 forms.css - 补丁 mend.css - 打印 print.css 115 | 116 | 这些规范,你遵守或不遵守都对项目没什么太大影响。 117 | 118 | **开发规范需要自己根据团队实际情况去制订** 119 | 120 | 举几个例子 121 | 122 | 1、在[文件目录](./directory.md)章节所描述目录结构中。后期维护时在HTML中看到一个 `
` 代码。想要找到 `.some` 的样式在哪儿,却找不到。可以制订规范,所有 `m/` 文件夹下的 css 都要以 `.m-` 作为前缀。这样看到一个 class 如果是 `.m-box` 则直接去找 `m/box/index.css` ,看到 `.some` 则直接找HTML同级目录的 css 文件。 123 | 124 | 2、后期维护时样式总是CSS选择器权重过高无法通过新增 class 的方式覆盖样式,则约定完全不要使用ID选择器,class 选择器使用 `.m-box-hd-title {}` 这种结构命名法降低权重。保持大部分选择器权重都是 `0, 0, 1, 0` 125 | 126 | 3、有时删除了一个 class ,JS 绑定的事件就失效了,则可以将所有用于 JS 选择的 class 都以 `.js-` 作为前缀。例如: `.js-submit` `.js-list-remove` 127 | 128 | **先遇到问题,再制订能解决这个问题的规范** 129 | 130 | 131 | ### 新规范的试验期 132 | 133 | 当遇到一个新问题时,根据问题制订一个规范。当不是很确定这个规范能解决这个问题时。不要着急将新的规范加入开发规范文档。而是找一些经验丰富的同事先在一个项目中试验一次。项目结束后经过讨论觉得可行时再正式加入开发规范文档。**开发规范反复变更会增加一线开发人员学习和记忆成本**。 134 | 135 | 136 | ## 需求合理性 137 | 138 | 139 | 147 | -------------------------------------------------------------------------------- /chapter/mock.md: -------------------------------------------------------------------------------- 1 | # 数据模拟 2 | 3 | > 这一章会在 onface 团队的新版数据模拟服务器开发完成后撰写 4 | -------------------------------------------------------------------------------- /chapter/technology-stack.md: -------------------------------------------------------------------------------- 1 | # 技术选型 2 | 3 | 上一章:[构建系统](./build.md) 4 | 5 | --- 6 | 7 | 既然是技术选型自然要知道有哪些选项 8 | 9 | ## HTML模板引擎 10 | 11 | 你的项目会使用到 React/Vue/Angular 其中一个,则完全不需要HTML模板引擎。否则你可以选择 `ejs` `pug(jade)` `handlebars` 等模板引擎。团队负责人应根据项目情况去选择,而不是个人喜好。*了解主流模板引擎的不同点不会花很多时间,磨刀不误砍柴工。* 12 | 13 | 14 | ## CSS 预处理器 15 | 16 | 主流的有 `less` `sass` `stylus` 17 | 18 | 预处理不像HTML模板引擎那样,不同的模板引擎有很大差异。CSS 预处理器选择最契合团队环境的就可以。*作者推荐less,原因是安装快* 19 | 20 | > 不推荐 CSS in JS解决样式冲突,推荐使用 [CSS modules](http://www.ruanyifeng.com/blog/2016/06/css_modules.html) 21 | 22 | ## CSS框架 23 | 24 | 最为出名的CSS框架就是 Bootstrap,但是**项目中还是尽可能的不使用第三方CSS框架**。而是根据项目情况自主开发,或者沿用团队自主开发的框架。 25 | 26 | 比如 [Alice](http://aliceui.github.io/) 是支付宝的样式解决方案,其实它只适合直接用在支付宝。而不适合直接在自己项目中用。 27 | 28 | 如果一个项目只有[原型](http://www.woshipm.com/pd/144880.html)没有设计稿,就可以选择一个符合原型的CSS框架,减少开发工作量。 29 | 30 | **应该学习一个CSS框架的设计思想和代码分类方式,而不是复制粘贴硬生生的加到项目中** 31 | 32 | ## JS框架 33 | 34 | 这个是重头戏,前端社区不断的有人在讨论JS框架的技术选型。目前主流无非就以下几个选择 35 | 36 | `jQuery` `React` `Vue` `Angular` 37 | 38 | ### 不同框架适合不同业务场景 39 | 40 | 页面交互少,功能简单的用 jQuery 绰绰有余。 41 | 42 | 页面关联操作特别多,功能复杂的,必然要用 React/Vue/Angular。这种情况下**需要团队负责人根据项目业务场景和团队人员对框架的熟悉程度进行评估**,选择一个最可行的方案。 43 | 44 | 比如一个项目非常非常适合使用 React 开发,但是团队成员对 Angular 非常喜爱,也有了足够的积累。对 React 的了解程度只是 *单向数据流、JSX* 并且没有任何 React 方面的积累,构建系统都没搭建过。那么立即要开始的项目还是应该用 Angular 。后续再对团队成员进行引导,慢慢了解和熟悉 React。 45 | 46 | 当然有些团队很强悍,团队成员对主流框架都用的得心应手。完全可以根据项目业务场景选择最适合的框架。但是大部分的团队还是没那么强悍的。 47 | 48 | 框架没有高低之分,只有是否适合。 49 | 50 | 51 | 延伸阅读:[Vue 对比其他框架](https://cn.vuejs.org/v2/guide/comparison.html) 52 | 53 | ## ES6 和 JavaScript 超集 54 | 55 | ES6 指的是 [ECMAScript6](http://es6.ruanyifeng.com/) JavaScript 超集指的是 [CoffeeScript](http://coffee-script.org/) 和 [TypeScript](https://www.tslang.cn/) 56 | 57 | ### ES6 58 | 59 | 构建系统应当支持ES6,团队成员也必须学习ES6。因为它是标准。 60 | 61 | ### JavaScript 超集 62 | 63 | 这个也是**需要团队负责人根据项目业务场景和团队人员对框架的熟悉程度进行评估**。超集会增加团队学习成本、招聘成本和新人的培训成本,如果超集确实能提高开发效率和提高项目稳定性还是应该推行使用的。 64 | 65 | 66 | ## 字体图标平台 67 | 68 | [iconfont](http://iconfont.cn/) [fontawesome](http://fontawesome.io/) 等平台都会提供一些字体图标,建议团队使用 [iconfont](http://iconfont.cn/) 由设计师创建和维护图标项目的内容。由前端维护图标的 class 和尺寸的调整。 69 | 70 | 扩展阅读: [iconfont - Font class 是否可以提供 less 文件](https://github.com/thx/iconfont-plus/issues/390) 71 | 72 | 73 | ## 兼容性 74 | 75 | > 因为兼容性限制了技术选型所以专门提一下 76 | 77 | 技术负责人一定要**在商业需求和开发成本中达到一个平衡,服务好客户让公司赚到钱是第一位。** 78 | 79 | 这个很重要,主要决定权不在技术团队,而是在于需求方。 80 | 81 | 如果要兼容IE8只能使用 jQuery 1.x 和 React 0.14.x ,要兼容 IE6 IE7 就老老实实的用 jQuery 1.x [regularjs](http://regularjs.github.io/guide/zh/index.html) [Avalon](http://avalonjs.coding.me/home.html) 82 | 83 | 因为要兼容低版本浏览器,构建系统也需要做一些兼容处理 [support-ie8](https://github.com/onface/support-ie8) 84 | 85 | > 吐槽:要知道有些单元测试框架都不支持IE8了,写个代码不容易。 86 | --------------------------------------------------------------------------------