React提高08 Create React App
一个由Facebook官方出品的React脚手架工具,无需额外配置,迅速搭建React应用脚手架。
这里只对它进行简单的尝试和入门,如果需要进一步的学习,官网在这里,文档在这里,也可以参考这篇文章进行更高阶更深入的配置和学习。
使用Create React App开发React应用不必再安装Webpack或者Babel,它们已经被内置在脚手架中了
它提供的功能:
- 开箱即用的React支持
- 开发模式和生产模式的编译
- 开发模式的热更新
- 提供了单元测试测试的接口支持
- 其他配置工具的默认配置(亦可以个性化配置)
快速开始
1 | npx create-react-app my-app |
React应用会运行在http://localhost:3000/
,开发完成后使用npm run build
打包
安装
安装需要Node的版本在8.10.0以上
1 | # 使用npx |
运行
1 | npm start |
在http://localhost:3000
以开发模式运行React应用,页面提供了热跟新功能,在控制台会显示错误和警告。
单元测试
基本使用
1 | npm test |
使用Jest运行单元测试,默认情况下会运行从上次提交commit后有改动的文件的单元测试。
需要react-scripts@0.3.0
及更高版本,老项目开启单元测试看这里。
Jest是基于Node的运行期,速度很快,并且动过jsdom提供了浏览器的全局变量,比如window
,但Jest对于DOM的测试是不准确的,它的目的是对逻辑和组件进行单元测试,而非测试DOM
在运行时Jest会自动寻找以test.js
/spec.js
或者__tests__
文件夹下以.js
结尾的文件,==这些文件可以位于src
目录下任意深度的文件夹内==。
建议将测试文件(或__test__
文件夹)和北侧文件放在一起,有两个好处:
- 便于管理,一眼就能看到文件的单元测试文件
- 引入组件的时候更简洁, 例如
import App from './App'
命令行接口
使用npm test
时,Jest会以watch
模式运行,每次更改文件都会重新运行测试文件
这个模式下的命令行接口提供了各种能力,可以一直开着这个窗口进行快速的重复测试
版本管理接口
使用npm test
默认情况下会运行从上次提交commit后有改动的文件的单元测试。可以在watch
模式下按a
来要求Jest执行全部的测试
如果当前的工程没有使用版本管理,那么Jest会默认运行全部的测试
测试组件
关于Jest的使用,以前学习在Vue中使用Jest时总结过,Jest的基本用法是相同的,在测试组件时有所区别,Vue测试组件使用的将组件和Jest进行连接的工具是Vue-test-utils,而React则是Enzyme(更准确些,jest-enzyme更接近于Vue-test-utils,封装了很多方便的API)
内容比较多,这里不展开,文档在这里,慢慢单独学习。
构建生产文件
1 | npm run build |
打包出的文件是经过压缩的,文件名带有Hash值
个性化配置
因为Create-React-App将Webpack、Babel、ESLit的配置隐藏起来,简化了用户的配置操作,可以快速开始开发。
但是这只适用于一些小型的、没有特殊需求的应用的开发,如果构建大型应用还需要对上面这些工具进行个性化的配置:
1 | npm run eject |
运行后,Create-React-App会将上面工具的配置文件复制到项目中,以后对配置文件进行修改后,项目式中会采用项目中复制修改后的配置文件
要注意,这个操作是不可逆的。
CSS-Loader
在新版本的Create React App中增加了对CSS Modules的支持,要求react-scripts
版本高级2.0.0。
CSS文件的命名形式为[name].module.css
,对应的类名会通过添加后缀的形式来实现局部作用域,类名的格式是[filename]\_[classname]\_\_[hash]
详情参考文档。
如果需要在老版本的Create React App中增加了对CSS Modules的支持,则首先需要先通过eject
命令暴露配置文件,参考这篇文章。
ESLint
由于Create React App将默认的构建配置封装了起来,而ESLint仅仅开启了最基本的规则,更重要的是默认情况下,ESLint仅仅会在IDE中对违反规则的情况进行提示,并不会在构建时在终端的输出进行终端和提示。
如果这种情况可以满足需要,而只需要开启更多的规则,那么就可以在根目录下新建一个文件.eslintrc.json
,然后添加:
1 | { |
但是如果要起到更强制性的提示作用(中断构建、终端提示),Create React App建议使用Prettier代替ESLint。如果要使用ESLint,那么就需要使用npm run eject
,将配置文件吐出,按照AlloyTeam的提示进行配置即可,参考这篇笔记。
Ant Design按需引入
安装antd:
1 | npm install antd -S |
然后进行按需引入分为两种情况:
(1)未eject出所有配置:
参考antd的文档,
安装react-app-rewired和customize-cra(CRA)。
1 | npm install react-app-rewired customize-cra -D |
然后修改package.json
文件的启动命令:
1 | "scripts": { |
1 | npm install babel-plugin-import -D |
然后在根目录下创建config-overrides.js
,用来修改默认配置:
1 | const { override, fixBabelImports } = require('customize-cra'); |
然后按按照下面的格式按需引入模块:
1 | import { Button } from 'antd'; |
(2)已经eject出所有配置文件:
这个时候直接按照babel-plugin-import文档的说明配置即可。
安装babel-plugin-import
:
1 | npm install babel-plugin-import -D |
然后在package.json
中找到babel
选项,修改为:
1 | "babel": { |
引入方式与上面相同:
1 | import { Button } from 'antd'; |
配置Less
首先安装less
和less-loader
:
1 | npm install less less-loader -D |
然后同样分为是否eject配置两种情况:
(1)未eject出所有配置,仍遵循上面的步骤,安装react-app-rewired
和customize-cra
,修改package.json
中的启动脚本。
然后修改config-overrides.js
文件:
1 | const { override, fixBabelImports, addLessLoader } = require('customize-cra'); |
这里利用了less-loader
的modifyVars
来进行主题配置,变量和其他配置方式可以参考配置主题文档。
(2)已经eject出所有配置的情况,参考这篇文章:
在config
目录下的webpack.config.js
文件,找到// style files regexes
注释位置,添加:
1 | // 添加 less 解析规则 |
然后找到rules
属性,在其中添加less解析配置:
1 | // Less 解析配置 |
要注意的是,新添加的less-loader
必须在file-loader
的前面才能生效,因为Webpack在解析Loader是从右至左进行的(从下到上),只有先经过file-loader
对文件路径的处理,less
文件才能够被正确引入。
配置Alias
在Vue中习惯了使用@
来代替一连串的..
表示的相对地址,这个功能是webpack提供的,需要在webpack中进行配置
现在使用了React,也同样希望能够配置Alias来实现路径的更优雅的表示。如果已经eject处所有配置的情况下,直接在webpackd的配置文件下添加相关的代码即可:
1 | module.exports = { |
但是如果在未eject的情况下,同样需要借助上面使用的react-app-rewired
实现,首先在根目录建立一个alias.js
文件,在这个文件中编写Alias的配置代码:react-app-rewired
1 | const path = require('path'); |
然后在config-overrides.js
文件中引入并进行配置:
1 | const { override, addWebpackAlias } = require('customize-cra'); |
重新编译后@
就生效了。
这时有两个问题要解决
(1)IDE的点击跳转失效了
Webstorm是可以识别webpack的配置文件,对Alias进行相应的处理,但是这里并没有eject出Webpack的配置文件,但是我们的alias.js
文件就是按照Webpack的配置模块的格式来编写的,所以可以将alias.js
作为配置文件,传递给Webstorm,这样IDE的文件跳转就正常了
(2)ESLint的导入导出规则报错
这是因为ESLint不能识别我们的Alias,这需要安装eslint-import-resolver-webpack
这个插件,让ESLint使用Webpack的解析规则。
首先安装
1 | yarn add eslint-import-resolver-webpack -D |
然后在.eslintrc.js
中添加如下的配置:
1 | module.exports = { |
同样使用alias.js
来代替Webpack的配置文件,配置完之后ESLint也就能正常工作了。
配置webpack-bundle-analyzer
首先需要安装:
1 | # NPM |
在未eject的情况下,同样可以使用customize-cra
来添加webpack-bundle-analyzer的配置,在cvonfig-overrides.js
中,引入addBundleVisualizer
,进行配置:
1 | const { override, addBundleVisualizer } = require('customize-cra'); |
addBundleVisualizer接受两个参数,第一个对象是webpack-bundle-analyzer
的配置项,可以参考文档。第二个选项用来配置自动开启,设置为ture
就不需要在每次build
时传入--analyze
来开启分析了
在已经eject了的情况下,在webpack.config.js
做进行配置,将webpack-bundle-analyzer
作为插件进行引入
1 | const BundleAnalyzerPlugin = require('webpack-bundle-analyzer').BundleAnalyzerPlugin; |
环境变量
环境变量在构建期间嵌入。
可以使用process.env.NODE_ENV
来读取内置的环境变量,当运行npm start
时,它等于development
,当运行npm test
时,它等于test
,当运行npm run build
时它等于production
。不能手动覆盖NODE_ENV
,这可以防止开发人员意外地将开发环境部署到生产环境中
除了process.env.NODE_ENV
之外也可以使用自定义的环境变量,自定义的环境变量必须以REACT_APP_
开头。
添加环境变量有两种方式:
(1)在Shell中添加临时环境变量。
操作系统不同,在Shell中定义环境变量的方法也不相同:
1 | # Windows (cmd.exe) |
为了统一在不同的操作系统中的设置方法,可以使用cross-env
这个库
安装:
1 | npm install cross-env --save-dev |
使用时只需要在原来的脚本前面加上cross-env
就可以了
1 | cross-env NODE_ENV=development nodemon ./index.js |
(2)在.env
中添加开发环境变量
在项目根目录中创建名为.env
的文件,在文件创建以REACT_APP_
开头的自定义环境变量。除了NODE_ENV
之外的任何其他变量都将被会略
==实际上,NODE_ENV
是不能被覆盖的,也就意味着在.env
中定义NODE_ENV
也是同样被忽略的,在默认配置条件下,脚手架中的NODE_ENV
是无法更改的。==
.env
文件应该提交到git进行管理(除了.env&.local
之外)
除了.env
之外,还可以使用特殊的.env
文件
.env
:默认。.env.local
:本地覆盖。除test
之外的所有环境都加载此文件。.env.development
,.env.test
,.env.production
:设置特定环境。.env.development.local
,.env.test.local
,.env.production.local
:设置特定环境的本地覆盖。
如果使用一个新的自定义的.env
文件,比如使用.env.stage
的环境变量文件,需要在运行npm
命令时使用env-cmd
安装:
1 | npm install env-cmd --save-dev |
使用时直接将.env.stage
的路径引入即可,在Package.json
文件中:
1 | { |
在命令行中:
1 | ./node_modules/.bin/env-cmd ./.env.stage npm run build |
这种情况下,process.env.NODE_ENV
仍然是production
,但加载的.env
文件已经不再是.env.build
,而是变为了env.stage
参考
- Docs@Create React App
- 从React脚手架工具学习React项目的最佳实践(上):前端基础配置@掘金
- 在create-react-app中使用@Ant Design
- ant-design/babel-plugin-import@github
- 在 Create React App 中启用 Sass 和 Less@掘进
- eslint-import-resolver-webpack@npm
- 关于eslint-plugin-import无法识别webpack alias问题@JERMY’S BLOG
- aze3ma/react-app-rewire-aliases@github
- create-react-app 通过 react-app-rewired 添加 webpack 的 alias@OnlyLing
- Resolve@Webpack
- env-cmd@npm
- webpack-contrib/webpack-bundle-analyzer@github