1. Quick OverView
1.1 环境依赖:
npm 5.2+ and higher,
Node >= 6
不需要安装 Webpack or Babel等工具. 他们已经预配置好并且隐藏起来了,你可以专注在你的代码上
1.2 初始化&本地启动命令:
初始化项目的三种方式:
npx create-react-app my-app (npm 5.2+)
npm init react-app my-app (npm 6+)
yarn create react-app my-app (yarn 0.25+)
运行:
cd my-app
npm start
访问 localhost:3000,就能看到新创建的app页面了。
你还可以 set HTTPS=true&&npm start
来让他通过HTTPS运行,但是是自己的证书,浏览器一般不认
1.3 单元测试
npm test
or yarn test
执行单元测试,会自动在目录下寻找文件:
./__tests__/**.js
**.test.js
**.spec.js
1.4 构建与部署
构建: npm run build
or yarn build
: 构建app到 /build
目录下,以部署到prod
部署: 如果你的环境已经安装了node,那么当你build完之后,最简单的部署方式使用static server, 如下:
npm install -g serve
serve -s build
默认会启动在5000端口。可以使用-p参数修改端口
1.5 优势
Create React 几乎有你所需要的,搭建React单页面应用的一切:
- 支持React, JSX, ES6, and Flow语法, 也支持部分ES6外的语法特性,比如“object spread operator”。
- 不需要css前缀
- 自带单元测试工具,以及覆盖率报告
- 通过一个单独的依赖集成 Webpack, Babel, ESLint, 等等优秀的项目,减少依赖更新的麻烦
- 框架把配置都写好了,包括dev跟prod两个环境。你可以专注在业务代码上;但是也可以自定义配置,
npm run eject
(这个过程是不可逆的,不要随意手贱。。)
2. 初始结构
2.1 初始目录结构
my-app/
README.md
node_modules/
package.json
public/
index.html
favicon.ico
src/
App.css
App.js
App.test.js
index.css
index.js
logo.svg
重要的不可重命名的基础文件
public/index.html
:主页面模板
src/index.js
: 主js的入口
需要注意的文件夹
/src
: webpack默认的识别目录,所有的项目js, css代码都得放这里,不然生产环境打包时候打不进去
2.2 工具本身package
Create React App分为两个package:
-
create-react-app
是一个全局的命令行组件,用于创建一个app -
react-scripts
是项目的开发依赖
3. 如何开发你的APP
3.1 安装依赖
npm: npm install --save react-router-dom
yarn: yarn add react-router-dom
3.2 加载模块
推荐操作:import
export
。 export 有 named 与default 的方式,只有一个时候建议用default。
import React, { Component } from 'react';
class Button extends Component {
render() {
// ...
}
}
export default Button;
不推荐操作: require()
和 module.exports
。
- require/exports 属于非官方的规范,属于广泛流传的野生规则,比如CommonJS、AMD、CMD。早在2010年就出现;
- import/export 则是ES6的官方标准中,明确包含进来的。但是出现较晚,2015年才出来
- 但是CommonJS 又是 Node.js 的规范,npm 上 CommonJS 的类库众多,以及 CommonJS 和 ES6 之间的差异,Node.js 无法直接兼容 ES6。
- 神babel出现了,最早叫6to5。能够将ES6 Module 编译为 ES5 的 CommonJS —— 也就是 require/exports 这种写法
3.3 使用环境变量
如何添加?:
- REACT_APP_SECRET_CODE=abcdef npm start
- 使用 .env 文件。
.env: 默认文件
.env.local: 本地 overrides. 除了Test之外的所有环境
.env.development, .env.test, .env.production
.env.development.local, .env.test.local, .env.production.local
加载优先级,从左到右:
npm start: .env.development.local, .env.development, .env.local, .env
npm run build: .env.production.local, .env.production, .env.local, .env
npm test: .env.test.local, .env.test, .env (note .env.local is missing) - 一些扩展的写法:
REACT_APP_VERSION=$npm_package_version
# also works:
# REACT_APP_VERSION=${npm_package_version}
DOMAIN=www.example.com
REACT_APP_FOO=$DOMAIN/foo
REACT_APP_BAR=$DOMAIN/bar
如何使用?:
- JS: process.env.NODE_ENV
- HTML: %NODE_ENV%
限制?:
- 默认有NODE_ENV的三个环境,不可覆盖
- 自己设定的只能以REACT_APP开头,防止误导入
- env在build的时候引入并且生效。build完的就是替换完的结果
3.4 offline/cache-first选项
- 基于workbox-webpack-plugin实现,create react app中默认带有这个东西,只是默认关闭。
- 如何开启?
/src/index.js
中的serviceWorker.unregister();
改成register()
即可 - 为什么需要这个?好处:页面加载变快;坏处:debug变的麻烦,以及一些支持上的坑
4. 推荐开发实践 && 常用工具
4.1 独立的组件开发,Storybook
理念:
- React 中的 UI 以组件的形式存在,每个组件是一个独立的单元,具有自己的各种样式与属性。
- 通常只有在App 中看到组件的各种状态,不方便,并且不独立。
工具:
Storybook。让你能够独立的开发你的组件并且查看它的状态。
使用:
npm install -g @storybook/cli
getstorybook
# 启动 storybook 在端口:9009 :
yarn run storybook
# 启动 前端 页面 在端口:3000:
yarn start
配置:
.storybook/config.js
默认情况下, Storybook 会查找故事/stories目录; 本教程使用类似于.test.js的命名方案, 这个命令是 CRA 赞成的用于自动化测试的方案.
import { configure } from '@storybook/react';
import '../src/index.css';
const req = require.context('../src', true, /.stories.js$/);
function loadStories() {
req.keys().forEach(filename => req(filename));
}
configure(loadStories, module);
按照组件驱动开发(CDD)的方法论构造UI:
- 新建任务组件
src/components/Task.js
及其附带的故事组件src/components/Task.stories.js
。 - 任务组件中写实现,故事组件中写类似于测试的story
export default function Task({ task: { id, title, state }, onArchiveTask, onPinTask }) {
return (
<div className="list-item">
<input type="text" value={title} readOnly={true} />
</div>
);
}
import React from 'react';
import { storiesOf } from '@storybook/react';
import { action } from '@storybook/addon-actions';
import Task from './Task';
export const task = {
id: '1',
title: 'Test Task',
state: 'TASK_INBOX',
updatedAt: new Date(2018, 0, 1, 9, 0),
};
export const actions = {
onPinTask: action('onPinTask'),
onArchiveTask: action('onArchiveTask'),
};
storiesOf('Task', module)
.add('default', () => <Task task={task} {...actions} />)
.add('pinned', () => <Task task={{ ...task, state: 'TASK_PINNED' }} {...actions} />)
.add('archived', () => <Task task={{ ...task, state: 'TASK_ARCHIVED' }} {...actions} />);
重新启动 Storybook服务器 应该会产生 三个任务状态的测试用例,之后修改组件以匹配期望的测试用例。
4.2 分析Js bundle
yarn add source-map-explorer
"scripts": {
+ "analyze": "source-map-explorer build/static/js/main.*",
"start": "react-scripts start",
"build": "react-scripts build",
"test": "react-scripts test",
npm run build
npm run analyze
4.3 使用Bootstrap样式
yarn add bootstrap@4 reactstrap
import 'bootstrap/dist/css/bootstrap.css';
4.4 使用静态类型检测工具Flow
静态类型可以有效的减少代码bug。
- 执行
npm install --save flow-bin
(或者yarn add flow-bin
). - 添加
"flow": "flow"
to thescripts
section of yourpackage.json
. - 执行
npm run flow init
(oryarn flow init
) to create a.flowconfig
file in the root directory. - 添加
// @flow
to any files you want to type check (for example, tosrc/App.js
).
检查类型错误: npm run flow (or yarn flow)
4.5 添加router
最流行的react路由工具。
npm install --save react-router-dom
4.6 Relay
building data-driven React applications, by GraphQL
属于React中的数据流管理的工具,Redux的竞品。
yarn upgrade babel-plugin-relay@dev
import graphql from 'babel-plugin-relay/macro';
// instead of:
// import { graphql } from "babel-plugin-relay"
graphql`
query UserQuery {
viewer {
id
}
}
`;
4.7 手动配置代理http-proxy-middleware
用于集成后端
$ npm install http-proxy-middleware --save
$ # or
$ yarn add http-proxy-middleware
创建src/setupProxy.js
:
const proxy = require('http-proxy-middleware');
module.exports = function(app) {
app.use(proxy('/api', { target: 'http://localhost:5000/' }));
};
4.8 页面调试工具React devTools
Chrome中添加React调试工具,方便调试。
5. 单元测试
- 基于Jest的单元测试, Jest是一个node-based的工具,速度比较快,不能覆盖End to End的内容
- 默认只会执行上次commit完,改动的代码影响的测试,测试效率高,可以在测试窗口press a来强行run所有的测试
- 测试文件规则:
Files with .js suffix in__tests__
folders.
Files with .test.js suffix.
Files with .spec.js suffix. - 建议把测试文件或者
__test__
目录放在待测试代码旁边 - npm test -- --coverage, 查看测试覆盖率
6. 部署
6.1 static server
npm install -g serve
serve -s build
6.2 Node Express dynamic one
const express = require('express');
const path = require('path');
const app = express();
app.use(express.static(path.join(__dirname, 'build')));
app.get('/*', function(req, res) {
res.sendFile(path.join(__dirname, 'build', 'index.html'));
});
app.listen(9000);
此外还可以有其他的,比如Apache服务器,等等。。。
参考资料: