🌈React的优点

学习简单

学完ES6+或TS基本语法再过一遍React官方文档即可进入简单的开发

语法简洁

React对TS有着近乎完美的支持度和Eslint的编辑器友好.与Vue需要记一大堆API不同的是React几乎没有API也没有类似Vue3中的setup等啰嗦的东西,更加极客,适合治疗代码强迫症.

生态丰富

无论国内外大厂,React的采样率都是三大框架中最高的,所以其生态也是非常强大的,与Vue的生态基本不相上下,远超Angular,比如支持小程序开发的Taro,支持移动端开发的React Native等,基本开发中要用到的东西都有开源实现的方案

社区庞大

因为是三大框架中全球用户最多的,所以社区庞大,爬坑最容易,一般找生态,查问题,基本谷歌一下,各种stackoverflow,github issue,medium,dev.to等各种社区会报出最准确的解决方案.

🌧React缺点

React最大的缺点在于过于灵活,一大堆杂七杂八的状态管理,有时候会导致选择障碍,路由也是组件实现,需要配置式必须要自己封装,并且工程化团队开发困难,NG虽然工程化比较好,但生态的落差基本直接弃.React还有一个缺点就是移动端好用的UI库并不多,而上述问题Vue都解决的不错,比如拥有官方的vuex和配置式的vue router以及类似Vant这种现象级别的移动组件库.所以站长建议最好有时间把两者都学习一下,那么在开发的时候就可以灵活选择.

✍️目标学者

本教程适合以下朋友学习

👉 前端入门者: 已经学习过TS和ES6的基础知识,需要快速学习一个前端框架

👉 React初学者: 已经学会了各种React知识希望有一套能进行项目实战练习的教程

👉 Vue开发者: 觉得Vue3太啰嗦不够Geek或者对TS和编辑器支持度有强迫症想尝试一下新东西

👉 Angular开发者: 想开发一下小程序或者移动APP

👉 Jquery为主的传统MVC开发者: Jquery+PHP/ROR写腻了? 那么就来追一下潮流哈

👉 Gopher,Javaer等职业后端: 想成为全栈开发者或者至少不再与前端争论对错和扯皮,自己能看懂前端代码,那么本教程正适合你

👀教程内容

本教程是一套从React入门到项目实战的全解析教程.内容涉及React的几乎所有知识以及Spa后台和SSR网站两个实战案例的开发等,非常全面地讲解React+TS项目开发中的方方面面,使大家能全面深入的掌握React及其周边的生态.

Spa应用的脚手架选择更好更快的vitejs,SSR应用的脚手架选择next.js.为了教程更轻量易懂,我们直接略过传统的Class组件,而直接全部使用函数组件讲解,后续所有React系列的教程也全部使用函数组件.并且为了与本站其它教程相对应,本站所有的前端/Node教程全部使用Typescript讲解.

🌒知识点

  • React+TS+Vitejs的开发环境构建
  • 掌握React开发的绝大部分技术
  • 灵活的使用Hooks以及编写自定义的Hooks
  • React Router的深度配置化封装以及懒加载实现
  • 学会使用Reducer+Context封装轻量级的状态管理
  • 掌握Redux与Mobx两种模式来进行全局的状态管理
  • 全面掌握React Router的使用和配置化封装
  • 学会css in js等多种css模式的使用
  • 使用Antd Components快速构建布局和表单
  • 使用localforage构建本地化数据缓存
  • 使用umi request进行与后端的数据互交
  • 动态暗黑模式和实时皮肤切换实现
  • 登录手机认证,社会化认证和验证码实现
  • 动态权限路由与菜单的生成
  • 图片上传以及区块拖动等常用组件的使用
  • Antd Charts实现数据可视化
  • TailWindCss与Material ui的使用
  • SSR原理以及React手动构建SSR应用
  • 完全掌握Nextjs框架的使用
  • 初步学会使用Mobx进行状态管理
  • 学会使用swr.js来和后端进行数据互交
  • Monorepo和同构架构的实现

🔥后续可期待

后面我们还会围绕着《精通React》这个系列制作其它教程,大概有以下几个内容

  • React+Electron桌面应用开发
  • Taro+RN开发跨端应用
  • React原理与实现

希望大家喜欢

创建项目

如果比较熟悉webpack也可以使用create-react-app,umi或自己手动写一个,为了有更加流畅的开发体验,本教程选择基于[esbuild][]的更加快速的[vite][]来构建开发环境

安装与配置node.js

如果没有安装brew请先安装

建议:安装到GLOBAL里面的东西统一使用一个包管理器,我这里使用pnpm

安装node.js

~ brew install node

配置npm淘宝镜像

~ npm config set registry https://registry.npm.taobao.org

安装pnpm

~ npm install -g pnpm

配置pnpm淘宝镜像

~ pnpm config set registry https://registry.npm.taobao.org

安装镜像管理工具

~ pnpm add nrm -g

建议安装一个node版本管理工具比如n或者nvm

~ pnpm add n -g

使用[Vite][]创建项目

在你的编码目录下初始化一个项目

~ pnpx create-vite

提示Install the following package: create-vite@latest?,按y

Project name:是你的项目目录和package.json中的项目名称,随意填

Select a framework框架选择中按方向键选择react

Select a variant选择react-ts

cd {你的Project name目录}

执行pnpm i安装依赖

代码规范化

具体代码与配置请自行查看源代码

代码风格

配置airbnb的eslint规则并整合prettier,并且经过一定的客制化同时配合vscode可达到完美的编码体验

pnpm add typescript \
eslint \
prettier \
@typescript-eslint/parser \
eslint-config-airbnb-typescript \
eslint-plugin-import \
eslint-plugin-jsx-a11y \
eslint-plugin-react \
eslint-plugin-react-hooks \
@typescript-eslint/eslint-plugin \
jest \
eslint-plugin-jest \
eslint-config-prettier \
eslint-plugin-prettier \
eslint-plugin-unused-imports -D

配置内容

为了让eslint能规范化自定义的文件,比如.eslintrc.js本身,使用一个新建的继承自tsconfig.jsontsconfig.eslint.json作为@typescript-eslint/parser的配置文件

...
plugins: ['@typescript-eslint', 'jest', 'prettier', 'import', 'unused-imports'],
extends: [
    // 兼容typescript的airbnb规范
   'airbnb-typescript',
    // react hooks的airbnb规范
    'airbnb/hooks',

    // typescript的eslint插件
    'plugin:@typescript-eslint/recommended',
    'plugin:@typescript-eslint/recommended-requiring-type-checking',

    // 支持jest
    'plugin:jest/recommended',

    // 使用prettier格式化代码
    // 整合typescript-eslint与prettier
    'prettier',
    'plugin:prettier/recommended',
],
parserOptions: {
    ...
    project: './tsconfig.eslint.json',
},

一些重要的规则

其余配置自行查看代码

eslint-plugin-unused-imports用于自动删除未使用的导入,对不是'_'前缀且未使用变量报错

...
 'no-unused-vars': 0,
 '@typescript-eslint/no-unused-vars': 0,
 'unused-imports/no-unused-imports': 1,
 'unused-imports/no-unused-vars': [
    'error',
    {
        vars: 'all',
        args: 'none',
        ignoreRestSiblings: true,
    },
]

import插件,import/order可以按照自己的需求配置

// 导入模块的顺序
'import/order': [
     'error',
     {
         pathGroups: [
             {
                 pattern: '@/**',
                 group: 'external',
                 position: 'after',
             },
         ],
         alphabetize: { order: 'asc', caseInsensitive: false },
         'newlines-between': 'always-and-inside-groups',
         warnOnUnassignedImports: true,
     },
],
// 导入的依赖不必一定要在dependencies的文件
'import/no-extraneous-dependencies': [
    'error',
     {
         devDependencies: [
             '**/*.test.{ts,js}',
             '**/*.spec.{ts,js}',
             'build/**/*.{ts,js}',
             'vite.config.ts',
         ],
     },
],

最后需要配置一下.prettierrc,和.editorconfig,并且把一些它们各自需要忽略的目录和文件分别添加到.eslintignore.prettierignore,最后把git仓库需要忽略的目录和文件写入.gitignore

Tsconfig配置

tsconfig.json文件中添加一个@作为根目录映射符,其它的配置按需要更改

{
    "compilerOptions": {
        // ...
        "paths": {
            "@/*": ["src/*"]
        }
    },
    "include": [
        "./src",
        "./typings/**/*.d.ts",
    ]
}

tsconfig.eslint.json

{
    "extends": "./tsconfig.json",
    "include": ["./src", "./test", "./typings", "./build", "**.js", "**.ts"]
}

配置vitejs

基础配置

安装deepmerge用于合并配置对象

~ pnpm add deepmerge -D

创建一个build目录专门用于放置vitejs的配置文件

Configure类型是外部vite.config.ts文件中自定义额外配置的回调函数的类型

// build/types.ts
export type Configure = (params: ConfigEnv, isBuild: boolean) => UserConfig;

getPlugins函数用于设置插件

// build/plugins/index.ts
export function getPlugins(isBuild: boolean) {
    const vitePlugins: (Plugin | Plugin[])[] = [reactRefresh()];

    return vitePlugins;
}

getConfig函数用于生成最终配置

// build/config.ts
export const getConfig = (
    params: ConfigEnv,
    configure?: Configure,
): UserConfig => {
    const isBuild = params.command === 'build';
    return merge(
        {
            resolve: {
                // 添加别名
                alias: {
                    '/@': pathResolve('src'),
                },
            },
            css: {},
            plugins: getPlugins(isBuild),
            // 启动端口
            server: { port: 4000 },
        },
        typeof configure === 'function' ? configure(params, isBuild) : {},
        {
            arrayMerge: (_d, s, _o) => Array.from(new Set([..._d, ...s])),
        },
    );
};

使用配置

// vite.config.ts
export default (params: ConfigEnv): UserConfig => getConfig(params);

支持react17风格

如果需要支持react17风格(即不需要在每个页面写import React from 'react')的话

一般情况下不需要

先把tsconfg.json中的"jsx": "react"改为"jsx": "react-jsx",然后添加如下配置

// build/config.ts
export const getConfig = (
    params: ConfigEnv,
    configure?: Configure,
): UserConfig => {
    const isBuild = params.command === 'build';
    return merge(
        {
            ...
            esbuild: {
                jsxInject: `import React from 'react'`,
            },
        },
      ...
    );
};

支持antdless

安装lessantd

~ pnpm add antd
~ pnpm add less -D

定制主题

modules配置用于转换css变量名称格式

// build/config.ts
return merge(
  {
    ...
    css: {
        modules: {
            localsConvention: 'camelCaseOnly',
        },
        preprocessorOptions: {
            less: {
                javascriptEnabled: true,
                javascriptEnabled: true,
                modifyVars: {},
            },
        },
    },
  }
)

按需导入

安装vite-plugin-style-import

~ pnpm add vite-plugin-style-import -D

配置插件

// build/plugins/antd.ts
export function antdPlugin(isBuild: boolean) {
    if (!isBuild) return [];
    const antd = styleImport({
        libs: [
            {
                libraryName: 'antd',
                esModule: true,
                resolveStyle: (name) => {
                    return `antd/es/${name}/style/index`;
                },
            },
        ],
    });
    return antd;
}

加载该插件

// build/plugins/index.ts
export function getPlugins(isBuild: boolean) {
    const vitePlugins: (Plugin | Plugin[])[] = [];
    vitePlugins.push(reactRefresh());
    vitePlugins.push(antdPlugin(isBuild));
    return vitePlugins;
}

效果测试

// src/App.tsx
const App: FC = () => (
    <div className="App">
        <Button type="primary">Button</Button>
    </div>
);

main.tsx如下设置,这是为了在开发环境中使用antd样式

// src/main.tsx
if (import.meta.env.DEV) {
    import('antd/dist/antd.less');
}

因为只在生产环境按需加载,所以执行以下命令在生产环境下测试

~ pnpm build && pnpm serve

支持tailwindcss

postcss可以按自己需求配置,或者不配置也没关系

安装[tailwincss][]与vite插件

~ pnpm add tailwindcss@latest postcss@latest autoprefixer@latest -D

初始化tailwindcss

npx tailwindcss init -p

配置tailwindcss

module.exports = {
    // 在生产环境中清除未使用的样式
    purge: {
        enable: process.env.NODE_ENV === 'production',
        content: ['./index.html', './src/**/*.{ts,tsx}'],
    },
    darkMode: 'class',
    theme: {
        extend: {},
    },
    variants: {
        extend: {},
    },
    plugins: [],
};

开发工具

推荐使用vscode作为开发工具

VSCode已经自带同步配置和插件的功能,建议启用

vscode

安装vscode

~ brew install vscode

安装eslint插件prettier插件

~ code --install-extension dbaeumer.vscode-eslint \
  && code esbenp.prettier-vscode

cmd+,选择偏好设置->工作空间,配置eslint插件

{
    "editor.formatOnSave": false,
    "editor.codeActionsOnSave": {
        "source.fixAll.eslint": true
    }
}

为了确保pnpm安装的package可以拥有像npm,yarn一样的本地目录的提示效果,请在vscode底部选择工作区版本或者安装nighty插件并选择vscode版本

调试

shift+cmd+d创建lanunch.json,按如下配置即可通过浏览器调试

{
  "version": "0.2.0",
  "configurations": [
    {
      "type": "chrome",
      "request": "launch",
      "name": "Launch Chrome",
      "url": "http://localhost:3100",
      "webRoot": "${workspaceFolder}/src",
      "sourceMaps": true
    },
  ]
}

因为视频教程的制作耗费站长大量的业余时间,有着巨大的工作量.每一集教程,需要编写代码,编写文档,录制视频,剪辑视频等多个流程,并且还提供了问答服务,如果全部免费的话本站将很难持续发展下去为大家提供更优质的内容.所以不得不收取一定费用,望大家谅解.

订阅本站后可以使用本站的一切服务,包括视频教程的学习,下载,问答以及本站发布的其它任何资源都可以随意使用.本站保证不再对订阅者收取二次费用.需要注意的是,后续推送的站长直播服务只有终身订阅者才可以享受.

本站目前提供各类编程开发相关的技术视频教程以及针对这些视频教程的问答服务和这些技术周边生态的导航,文档的翻译,开源项目的推荐,技巧性文章的发布等等.并且也为订阅者提供QQ群和discord问答服务.对于视频教程中的代码,站长专门搭建了一个代码托管平台方便大家下载.

本站在编程语言方面专注于Javascript/Typescript,Golang,PHP等几种站长擅长以及工作中常用的语言.技术栈涉及React,Vue等前端生态以及,Node.js,各种golang和php技术等后端技能,同时也会涉及一些包括Linux,Devops,Docker,K8S等在内与编程相关的技术,甚至还会讲解一些硬件方面的东西,总之用"杂七杂八"形容最为贴切.

本站绝大多数收费属于原创的虚拟商品,具有可复制性,可传播性,一旦授予,不接受任何形式的退款、换货要求。请您在购买获取或订阅之前确认好 ,避免引起不必要的纠纷