前言
跟着官网学习总结的,操作每一步都自己试过,官网教程有部分文章过旧了,我做了修正。如果你是刚学react,需要了解cra框架,学习怎么使用它,文章一定对你有帮助。
框架主要特点
开发不需要手动配置 webpack 、 babel 等构建工具,由框架来管理构建工具的配置,开发只需要专注于代码。以后升级也只用执行一条命令就能更新构建工具。
命令和使用说明
创建项目:npx create-react-app [项目名称] --template typescript
升级(更新构建工具):npm i react-scripts@latest
预览构建产物:
- npm i -g serve
- npm run build
- serve -s build [-l 端口]
弹出配置文件,此后需要手动维护配置(不建议,框架最大优势就没了):npm run eject
eject的替代方案:CRACO
补充说明:由于cra框架年久失修,已经谈不上一键更新了,项目基本都直接eject。
修改package.json后不会立即生效。这是由于babel-loader未检测到package.json,快速解决方案是删除 node_modules/.cache 文件夹并重试。
兼容旧版浏览器:react-app-polyfill、使用autoprefixer自动添加样式前缀(自带)
在生产构建时,src内的脚本和样式文件都会被压缩合并到一起,生成的文件名包含内容哈希,浏览器不会缓存旧版。而public内的资源webpack仅做复制不会处理,每次变更需要刷新缓存。
一般都是将资源放入src然后import导入,除非是以下情况才会放入public:
-
需要文件名保持不变
-
大量图片需要动态引用
-
小脚本
-
不兼容webpack的库
public内的资源引用:process.env.PUBLIC_URL + 相对public的路径
扩展ESLint配置
"eslintConfig": {
"extends": [ // 基本配置(最好保持不变)
"react-app",
"react-app/jest"
],
"rules": { // 适用于所有 js 和 ts 文件的新规则
"no-alert": "error"
},
"overrides": [
{
"files": [
"**/*.ts?(x)"
],
"rules": {} // 仅针对 ts文件的新规则
}
]
},
vscode内断点调试
{
"version": "0.2.0",
"configurations": [
{
"name": "Chrome",
"type": "chrome",
"request": "launch",
"url": "http://localhost:3000",
"webRoot": "${workspaceFolder}/src",
"sourceMapPathOverrides": {
"webpack:///src/*": "${webRoot}/*"
}
}
]
}
在 git 提交时自动格式化代码
-
npm i -D husky lint-staged prettier
-
npx husky init
-
pre-commit写入:npx lint-staged
-
.prettierrc写入:适合团队的格式化配置
-
首次格式化整个项目:./node_modules/.bin/prettier --write "src/**/*.{js,jsx,ts,tsx,json,css,scss,md}"
"husky": {
"hooks": {
"pre-commit": "lint-staged"
}
},
"lint-staged": {
"src/**/*.{js,jsx,ts,tsx,json,css,scss,md}": [
"prettier --write"
]
}
分析生产构建的包大小
-
npm i -D source-map-explorer
-
scripts添加命令:"analyze": "source-map-explorer 'build/static/js/*.js'"
-
npm run build
-
npm run analyze
在开发中使用HTTPS
scripts添加命令:"start:https": "HTTPS=true npm start"
PS:可以设置自定义证书。
css-modules
[name].module.[css|scss] => [filename]_[classname]__[hash]
原理:通过生成唯一的类名,来解决css全局作用域的问题
好处:防止样式污染、方便命名
使用:
import styles from './xxx.module.css';
className={styles.error}
其他特征:
@value 变量名: 变量值;
@value 变量名 from 'other module';
composes: 类名;
composes: 类名 from 'other module';
:global(选择器)
变量用来复用值,composes用来复用样式,:global能把选择器的作用域提升到全局。
:global中可以使用变量,但不能使用composes。
添加saas预处理器
npm i -D sass
saas可以和css modules一起使用,带来嵌套、mixin的增强。
添加css样式重置
样式入口添加:@import-normalize;
.vscode/settings.json添加:"[css|scss].lint.unknownAtRules": "ignore"
引入图片或svg
import logo from './logo.png';
<img src={logo} alt="Logo" />
import { ReactComponent as Logo } from './logo.svg';
<Logo title="logo" width="1em" fill="#f00" />
svg文件可以直接作为react组件引入,方便挂载属性到svg标签上(除了title)。
使用绝对路径导入模块
// tsconfig.json
compilerOptions.baseUrl: "src"
// 使用
import Button from 'components/Button';
使用全局变量
方法一:const $ = (window as any).$;
方法二(推荐,扩展Window类型):
declare global {
interface Window {
$: any; // jQuery
}
}
export {};
(坑:名称不能是index.d.ts,因为会和index.tsx冲突导致无法加载)
添加自定义的环境变量
环境变量就是特殊的占位符,在构建时会用值对占位符进行字符串替换。
通过process.env访问环境变量(index.html中通过 %变量名% 访问),其中内置变量NODE_ENV表示当前环境,可以用于在不同环境执行不同代码。
自定义的环境变量在env文件中声明,必须以 REACT_APP_ 开头,建议全大写,单词间以 _ 连接。
# 通用环境变量
# 网站标题
REACT_APP_WEBSITE_NAME="React 开发模板"
# 网站描述
REACT_APP_WEBSITE_DESCRIPTION="一个基于 Create-React-App 的 React 开发模板,用于项目初始化"
# 版本号(读取 package.json 的 version 字段值)
REACT_APP_VERSION=$npm_package_version
注意:修改env文件后需要重启开发服务器。
对生产构建使用缓存控制
安全有效的起点:(后面可以根据自己项目做针对控制)
build/static:Cache-Control: max-age=31536000
其他所有资源:Cache-Control: no-cache
这样浏览器会始终检查index.html,并把build/static的资源都缓存一年。
注意:如果build/static的资源更新了也会获取最新版本,因为文件名带有文件内容哈希,内容变了,URL也变了。
开发代理
方式一:在package.json中添加proxy选项,支持HTTP、HTTPS 和 WebSocket 连接。
// package.json
"proxy": "后端服务地址",
// .env.development
# 服务器主机。如果代理出现 Invalid Host header,则必须明确指定 HOST
# HOST=mypublicdevhost.com
# 如果指定 HOST 无效,只有打开下面设置(注意:这很危险,因为计算机可能会遭受恶意网站的远程代码执行)
# DANGEROUSLY_DISABLE_HOST_CHECK=true
方式二:自定义代理配置(不要和proxy选项混用)
-
npm i http-proxy-middleware
-
创建src/setupProxy.js
// 这个文件仅支持 Node 的 JavaScript 语法,不支持 ES 模块
const { createProxyMiddleware } = require('http-proxy-middleware');
module.exports = function (app) {
app.use(
'/api/*',
createProxyMiddleware({
target: 'https://jsonplaceholder.typicode.com',
ws: false,
changeOrigin: true,
pathRewrite: (path) => path.replace(/^\/api/, ''),
// logLevel: 'debug',
}),
);
};
项目部署
package.json添加homepage字段,确定生成的HTML文件中使用的根路径。
没有homepage ==> /static/xxx
"homepage": "." ==> ./static/xxx
"homepage": "http://mywebsite.com/relativepath" ==> /relativepath/static/xxx
一般情况设置为“.”即可,相对路径,方便部署到不同位置。
或者设置PUBLIC_URL环境变量,强制将资源引用到指定路径(包括主机名),优先级大于homepage
PUBLIC_URL=http://mywebsite.com/relativepath
=> http://mywebsite.com/relativepath/static/xxx
另外,如果build时报错找不到XXX,很可能是文件名大小写不对导致。
最后
如果文章有哪里写的不对,理解的不对,可以提出我会修改,帮到你了可以点个赞。
2024-07-04 补充eject说明
2024-07-03 发布