React 进阶

yiminghe@gmail.com

进阶

  • 生态圈
  • 开发工具
  • 如何开发一个组件
  • 如何开发项目

生态圈

安装 nodejs: 请使用 nvm 安装 4.0

tnpm

安装生态圈模块


npm install xx
tnpm install yy
tnpm install @your-company/xx
                

开发工具

组件开发:


                tnpm install yo generator-rc -g
            

项目开发:


                tnpm install antd-init -g
            

如何开发一个组件

初始化

开发调试

单元测试

发布

初始化

yo rc --author=chengyu@your-company.com
                    --pkg_name=@your-company/xx
                    --tnpm
                    --port=8000
                    --repo_url='http://gitlab.com/xx'

author: 作者邮箱

pkg_name: 包名,默认为 rc- 加目录名

tnpm: 是否发布到 tnpm

port: 调试端口

repo_url: 代码库地址

初始化目录结构

assets: 样式源码,less 语法

examples: 示例代码,页面为空,纯 react 渲染

src: 源码文件,es2015

tests: 单元测试,纯 js

package.json, README.md 按需修改

源码 src

es2015


import React from 'react';
const Menu = React.createClass({
    render(){}
});
export default Menu;
                

examples

纯 js,渲染示例到留空的 __react-content div


import React from 'react';
import Menu from '@your-company/biz-menu';
import '@your-company/biz-menu/assets/index.less';
React.render(<Menu />,
document.getElementById('__react-content'));
                

tests

使用 mocha/expect.js 编写 spec js 文件,可使用 React.addons.TestUtils 套件


import React from 'react';
import Menu from '@your-company/biz-menu';
import '@your-company/biz-menu/assets/index.less';
var TestUtils = React.addons.TestUtils;
describe('@your-company/biz-menu', () => {
    it('works', () => {
        var instance = TestUtils.renderIntoDocument(React.createElement(Menu));
        expect(TestUtils.scryRenderedDOMComponentsWithClass('.rc-menu-item')).to.be.ok();
    });
});
                

演示与测试


npm start // 启动调试服务器

http://localhost:8000/examples/ // demo 查看

http://localhost:8000/tests/runner.html // 测试用例

http://localhost:8000/node_modules/rc-server/node_modules/node-jscover/lib/front-end/jscoverage.html?
w=http://localhost:8000/tests/runner.html?coverage

npm run browser-test // phantomjs 运行测试用例

npm run browser-test-cover // phantomjs 运行测试覆盖率

npm run karma // 多浏览器测试
                

发布

npm run pub / npm run pub -- --tnpm

如何开发一个项目

  • 纯前端
  • chair

纯前端项目


                    antd-init
                

package.json


{
    "entry": {
        "index": "./index.js"
    },
    "dependencies": {
        "antd": "*",
        "antd-build": "0.4.x",
        "react": "~0.14.0",
        "react-dom": "~0.14.0"
    },
    "devDependencies": {
        "antd-bin": "0.x"
    },
    "scripts": {
        "start": "antd server",
        "build": "antd-build"
    }
}
                

entry: 入口文件集合

一个应用页面 index.html

入口文件

index.js: 引用依赖,渲染 react 组件到页面空位


import React from 'react';
import '../common/lib';
import Datepicker from 'antd/lib/datepicker';

class App {
    render(){
        return <Datepicker />;
    }
}

React.render(<App />, document.getElementById('react-content'));
                

按需加载

通过 AMD 的语法格式进行动态加载


require(['x','y'], function(X, Y){
// x y 模块进行了动态加载
});
                

调试开发


npm start
                

访问 http://localhost:8000/index.html

发布


npm run build
                

版本号目录


{
"build": "rm -rf dist && antd build && mkdir -p dist/${npm_package_name}/${npm_package_version} && mv dist/*.* dist/${npm_package_name}/${npm_package_version}/"
}
                

TODO: hash vm 映射

chair


tnpm install chair-init -g

chair init --type react test
                

入口文件约定

app/assets/entry/index.jsx


var React  = require('react');
var appData = require('appData'); // 服务器端数据
React.render(<div>
react {appData.fromServer}
</div>,document.getElementById('react-content'));
                

app/controllers/home.js 启动渲染


var render = require('../views/render');
this.body = render(this, {
    entry: 'index',
    appData: {fromServer: 'database'}
});
            

router

客户端路由

demo: http://yiminghe.me/learning-react/examples/react-router.html

react-router

将 url 嵌套同组件嵌套关联起来

/ -> App/Index

/state/x -> App/State

/x -> App/Index

react-router api

  • this.props.children: 嵌套组件
  • this.props.params: url 参数
  • this.props.query: url 请求参数

作业

search - list

Thanks