来豚厂还不满半年就又一次被 “拥抱变化”。

不过,无论是之前的无线 H5 团队,还是现在的机票 H5 团队。始终维持着一个创业型团队的规模 (一只手数得清)。

新老板提到:机票 H5 team 作为一个小团队,会类似“小白鼠”的角色,需要快速迭代、敏捷开发,作为创新项目的试验田。

对于我个人来讲,最深刻的,其实是无尽的危机感。

跟在阿里的师兄从 React 的易用性,讨论到前端新技术技术迭代升级的意义,最后总结到到一切技术都是辣鸡,升级说的直白一点就是换一种砖继续搬。深感无奈~

一线的开发是资源、是螺丝钉,没毛病。

先做一颗万能螺丝钉行不行?

抑或说,假如现在有机会让我一个初创公司的技术 leader, 我应该做到什么呢?

想太多不幸福,不如直接干~

THE WAY TO FULL STACK

SPA 项目全家桶新鲜出炉: Node + Koa + React View on github

后端框架 Koa

由 Express 原班人马打造的 koa,仅提供了一个轻量优雅的函数库,使得编写 Web 应用变得得心应手。

  • 使用Koa 框架搭建后端服务,作为 SPA 的入口和容器。

  • 使用单一职责的 Koa-Router,配合前端 React-router。处理外部直接 Landing、原地重刷新以及区分 404 页面:

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
28
var ThrowToHomePage = async function (ctx, next) {
console.log('EVR in router:',process.env.NODE_ENV);
ctx.state = {
env: process.env.NODE_ENV,
cdnUrl: CDN_URL
};
await ctx.render('index', { //去前端根路由
});
};
var ThrowToErroPage = async function (ctx, next) {
console.log('EVR in router:',process.env.NODE_ENV);
ctx.state = {
env: process.env.NODE_ENV,
cdnUrl: CDN_URL,
message: 'error',
error: {status:404,stack:'stack:'}
};
await ctx.render('error', { //去 404
});
};
router.get('/', ThrowToHomePage);
router.get('flight', ThrowToHomePage);
router.get('hotel', ThrowToHomePage);
router.get('train', ThrowToHomePage);
router.get('*', ThrowToErroPage);
  • 使用 ejs 模版引擎作为主应用的后端唯一 View:
1
2
3
4
5
6
<%- include('header') -%>
<div id='app'></div>
<%- include('footer') -%>

前端相关技术架构

  • 使用日趋成熟的 JS 语言标准 ES6, 使用 Less 预处理语言: 示例代码
  • 使用 React + ReactDOM 进行框架前端组件化开发
  • React-Router:SPA 的核心,与后端路由配合完成应用 Router
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
<Router key={Math.random()} history={browserHistory} >
<Route path="/" component={App}>
<IndexRoute component={Home}/>
<Route path="flight" component={Flight}>
</Route>
<Route path="flight/:citys" component={FlightList}>
</Route>
<Route path="train" component={Train}>
</Route>
<Route path="hotel" component={Hotel}>
</Route>
</Route>
</Router>
  • 模块化:ES6 module
  • 转场过渡效果:React-router-transition,作为一个 SPA,就是要做到如丝般顺滑~
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
var App = function ({ children, location }) { //children = React.children
styles = location.action === 'POP'? presets.slideRight: presets.slideLeft;
return (
<div>
<Header />
<RouteTransition
className="transition-wrapper"
pathname={location.pathname}
runOnMount={false}
{...styles}>
{children}
</RouteTransition>
</div>
)
}

编译构建:Webpack + Babel

Webpack 简直就是为了 SPA 和 ES6 量身打造的打包工具 !!!
对于 webpack.config.js 的配置:

  • 库文件 external
1
2
3
4
5
externals: {
'zepto': 'window.$',
'react':'window.React',
'react-dom':'window.ReactDOM'
},

像是 Jquery、zepto、React 这种官方已有编译好库文件的,直接挂载到全局对象引用即可。没有必要再通过 webpack 的流程在编译一次。

  • 公共组件 CommonsChunkPlugin
1
2
3
4
5
6
entry: {
router: ['react-router'] // CommonsChunkPlugin
},
plugins: [
new webpack.optimize.CommonsChunkPlugin('router','[name].bundle.js')// CommonsChunk
]

对于 React-router 这种非官方的插件,最好还是下载 stable 版本的源码,自行编译。

  • 样式文件单独打包
1
new ExtractTextPlugin("./css/IBU.H5.flight.css")
  • Hot Module Replacement

狂!!! 拽!!! 酷炫!!! 吊炸天!!! 的新功能,详情请戳 –>tutorial

据说可以在生产环境中使用,但是官方承认还不稳定. 耿直!请戳戳

官方的才是可信赖的,嗯。

结束也不是结束

写到这里,总觉得还少点什么?

这样就可以开始全栈开发 SPA 了?

前端有了,后端也有了。数据呢?

刀耕火种之 Node 直接查 DB

真正成为一个专业的后端乃至全栈开发人员,任重而道远。