Create React App 概览

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。

  1. 执行 npm install --save flow-bin (或者 yarn add flow-bin).
  2. 添加 "flow": "flow" to the scripts section of your package.json.
  3. 执行 npm run flow init (or yarn flow init) to create a .flowconfig file in the root directory.
  4. 添加 // @flow to any files you want to type check (for example, to src/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服务器,等等。。。

参考资料:

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 204,590评论 6 478
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 86,808评论 2 381
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 151,151评论 0 337
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 54,779评论 1 277
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 63,773评论 5 367
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 48,656评论 1 281
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 38,022评论 3 398
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,678评论 0 258
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 41,038评论 1 299
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,659评论 2 321
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,756评论 1 330
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,411评论 4 321
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 39,005评论 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 29,973评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,203评论 1 260
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 45,053评论 2 350
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,495评论 2 343

推荐阅读更多精彩内容