React-IMVC 是 Isomorphic MVC 的 React 实现,它是一个 Web 框架。通过 React-IMVC,我们可以更便利地实现同构 Web 应用 的开发。
IMVC 的 "I" 是 Isomorphic 的缩写,意思是同构,在这里是指,一份 JavaScript 代码,既可以在 Node.js 里运行,也可以在 浏览器 里运行。
IMVC 的 "M" 是 Model 的缩写,意思是模型,在这里是指,状态及其状态变化函数的集合,由 initialState
状态和 actions
函数组成。
IMVC 的 "V" 是 View 的缩写,意思是视图,在这里是指 React 组件。
IMVC 的 "C" 是指 Controller 的缩写,意思是控制器,在这里是指,包含生命周期方法、事件处理器、同构工具方法以及负责同步 View 和 Model 的中间媒介。
React-IMVC 里的 MVC 三个部分都是 Isomorphic 的,所以它可以做到:只编写一份代码,在 NodeJS 里做 服务端渲染(Server-Side-Rendering,简称 SSR),在 浏览器 里做客户端渲染(Client-Side-Rendering)。
在 React-IMVC 的 Model 里, state 是 不可变数据(immutable data),action 是 纯函数(pure function),不建议包含 副作用(side effect)。
React-IMVC 的 View 是 React 组建,建议尽可能使用无状态函数组件(functional stateless component)写法,不建议包含副作用。
然而,副作用是跟外界交互的必然产物,只可能被隔离,不可能被消灭。所以,我们需要一个承担 副作用的对象,它就是 Controller。
生命周期函数(Life-Cycle method)是副作用来源,Ajax/Fetch 也是副作用来源,事件处理器(Event Handler)也是副作用来源,localStorage 也是副作用来源,它们都应该在 Controller 这个 class
中,用面向对象的方式来处理。
使用 React-IMVC 开发的应用,包含多个页面(page),每个页面都由 MVC 三个部分组成。
每个页面都对应一个文件夹,里面必须包含一个 Controller.ts
文件,作为该页面的入口文件。
// /my_page/Controller.js
// Controller 基类里实现了许多方法,子类 Controller 要避免使用同名方法
import Controller from 'react-imvc/controller'
export default class extends Controller {
// your code
}
React-IMVC 有一些优秀的特性,如下:
- 一条命令启动完整的开发环境。
- 一条命令编译和构建源代码。
- 一份代码,既可以在 Node.js 做服务端渲染(SSR),也可以在浏览器端复用后继续渲染(CSR & SPA)。
- 既是多页应用,也是 单页应用,还可以通过配置自由切换两种模式,用「同构应用」打破「单页 VS 多页」的两难抉择。
- 构建时可以生成一份 hash history 模式的静态文件,当做普通单页应用的入口文件(如示例所示)。
- 构建时可以根据路由切割代码,按需加载 JavaScript 文件。
- 支持在 IE9 及更高版本浏览器里,使用包括
async/await
在内的 ES2015+ 语言新特性。 - 丰富的生命周期,让业务代码有更清晰的功能划分。
- 内部自动解决在浏览器端复用服务端渲染的 HTML 和数据,无缝过渡。
- 好用的同构方法
fetch
、redirect
和cookie
等,贯通前后端的请求、重定向 和 cookie 等操作。
TIP
下面我们将主要使用 JavaScript 来展示,当提到类型时,会使用 TypeScript 来展示,请注意区分。