Create React App 详解
常见的初始化 React App 的方式:
- 单个 HTML 页面引入 React App;
- 使用 Webpack 手动构建 React App;
- 使用 Create React App 一站式构建 React App;
一、Create React App 的设计
Create React App 适用于中小型 React 项目。
1、设计哲学
- 尽管 Create React App 使用了 Webpack,Babel,ESLint 等各种出色的项目,但只需要 Create React App 一种依赖;从 Create React App 生成项目的 package.json 中也可以看到并没有 Webpack、Babel 的痕迹。
- 无需配置。无需进行任何额外配置便可以直接运行代码,专注业务开发;同时 Create React App 还提供了开发和生产版本的合理配置。
- 非锁定配置。只需要运行一个命令,所有的配置项和构建依赖项都将直接“弹出”到项目中,交由我们来修改。
2、预设功能
Create React App 具有构建现代单页 React 应用所需的一切:
- React、JSX、ES6+、TypeScript 和 Flow 语法支持;
- CSS 自动添加前缀(-webkit-等前缀)的支持;
- 快速的交互式单元测试运行程序,内置对覆盖率报告的支持;
- 实时开发服务器,警告常见错误;
- 一个构建脚本,用于将 JS,CSS 和图像与哈希和源映射捆绑在一起进行生产;
- 满足所有渐进式 Web 应用程序标准的 ServiceWorker 和 Web 应用程序清单;
- 单一依赖项即可轻松更新上述工具。
3、核心库
create-react-app
:全局命令,用于创建初始化的 React 项目;react-scripts
:所生成的项目中的开发依赖项,包括运行项目、测试项目、打包项目等多种命令。
二、Create React App 的使用
1、创建项目
1-1、创建通用项目
Create React App 不需要安装/配置 Webpack 或 Babel 等工具。它们是预先配置和隐藏的,以便可以专注于代码。
- npx
npx create-react-app my-app
- npm
npm init react-app my-app
- yarn
yarn create react-app my-app
创建完项目的结构如下:
my-app
├── .git // 隐藏文件夹,会初始化第一个 Commit 记录
├── README.md
├── node_modules
├── package.json // 依赖配置文件
├── .gitignore
├── [floder_name] // 根目录下可以建立其他文件夹,但不会被用在生产环境中
├── public // 只有 public 下的文件才能被 public/index.html 使用
│ ├── favicon.ico
│ ├── index.html // 项目入口文件,在这可引用第三方类库、CDN 等,其中 <div id="root"></div> 是项目的总容器,有且只能有一个
│ └── manifest.json
└── src // 只有 src 下的文件才会被 Webpack 处理,新增的 JS 和 CSS 等文件需要放在 src 文件夹下
├── App.css
├── App.js
├── App.test.js
├── [floder_name] // 可以建立其他文件夹,以被 Webpack 成功导入
├── index.css
├── index.js // JS 打包入口文件,是和 index.html 进行关联文件的唯一接口。默认用 ReactDOM.render() 将 <App/> 的内容渲染到根 root 中去
├── logo.svg
└── serviceWorker.js // 提供渐进式 Web 应用的核心功能,不论网络状况如何都能立即加载,并且在离线时也能展示 UI
用 create-react-app 搭建起来的项目里没有 webpack 的配置文件,可以使用 yarn eject
命令把配置文件展示出来。运行后项目下多了两个目录,其中就有 webpack.config.js。
1-2、创建 TypeScript 项目
- npx
npx create-react-app my-app --template typescript
- yarn
yarn create react-app my-app --template typescript
2、项目启动、测试和打包
2-1、启动
npm start
# 或
yarn start
2-2、测试
npm test
# 或
yarn test
2-3、打包
npm run build
# 或
yarn build
2-4、弹出配置
npm run eject
# 或
yarn eject
3、配置生态
3-1、添加 TypeScript
- npm
npm install --save typescript @types/node @types/react @types/react-dom @types/jest
- yarn
yarn add typescript @types/node @types/react @types/react-dom @types/jest
3-2、添加 Sass / Less
- Sass
npm install sass-loader node-sass --save-dev
- Less
npm install less-loader less --save-dev
4、在已有项目中引入/升级 CRA
# 卸载 CRA 本身已经提供的依赖
sudo npm uninstall --save webpack webpack-cli webpack-dev-server
sudo npm uninstall --save-dev @babel/cli @babel-core @babel/preset-env @babel/preset-react
sudo npm uninstall --save-dev babel-loader babel-plugin-module-resolver html-webpack-plugin
# 删除 CRA 不需要使用的文件
rm webpack.config.js .babelrc
# 删除 node_modules
rm -rf node_modules
# 手动安装 React Script
sudo npm install --save react-scripts@latest
# 由于 CRA 默认规则,将 src/index.html 移至 public/index.html
mkdir public
mv src/index.html public
# 在 package.json 中添加 React Script 启动命令
vim package.json
package.json 中添加/覆盖如下指令:
"scripts": {
"start": "react-scripts start",
"build": "react-scripts build",
"test": "react-scripts test",
"eject": "react-scripts eject",
5、使用 React App Rewired 注入新配置
Create React App 官方并不推荐使用 npm run eject
弹出配置,这会增加更多的 Webpack 维护工作。对于实在想改的 Webpack 配置来说,可以使用 React App Rewired 库进行配置注入,这个工具可以在不 eject
也不创建额外 react-scripts 的情况下修改 create-react-app 内置的 webpack 配置,并拥有 create-react-app 的一切特性,可以根据需要去配置 webpack 的 plugins, loaders 等。
首先安装依赖并进行基础配置:
# 安装依赖
sudo npm install --save-dev react-app-rewired customize-cra
# 根目录建立 config-overrides.js
touch config-overrides.js
# 修改 package.json
vim package.json
# 运行项目
npm start
其中,config-overrides.js 的初始代码为:
/* config-overrides.js */
module.exports = function override(config, env) {
//do stuff with the webpack config...
return config;
}
package.json 的修改如下:
"scripts": {
"start": "react-scripts start",
"start": "react-app-rewired start",
"build": "react-scripts build",
"build": "react-app-rewired build",
"test": "react-scripts test --env=jsdom",
"test": "react-app-rewired test --env=jsdom",
"eject": "react-scripts eject"
}
然后编写配置,进行代理:
# 新增配置文件
mkdir config
touch config/proxy.js
# 修改 config-overrides.js
vim config-overrides.js
其中 config/proxy.js 源码是:
module.exports = {
'/api/**': {
target: 'http://110.114.120.120:8080',
secure: false,
changeOrigin: false
}
}
config-overrides.js 修改为:
const { overrideDevServer } = require('customize-cra')
const proxy = require('./config/proxy')
module.exports = {
devServer: overrideDevServer((config) => {
config.proxy = proxy
return config
})
}
此时,本地的所有 api 开头的接口请求都会被转发到 http://110.114.120.120:8080
的模拟后端 IP 上。