0
点赞
收藏
分享

微信扫一扫

【React】从0到1搭建你的React18项目


【React】从0到1搭建你的React18项目_前端

从0到1搭建你的react18项目

  • ​​一,项目搭建​​
  • ​​安装脚手架CRA​​
  • ​​保留核心代码​​
  • ​​二、使用gitee管理项目​​
  • ​​三、使用scss预处理器​​
  • ​​四、配置路由​​
  • ​​基础路由​​
  • ​​在非组件环境下拿到路由信息​​
  • ​​路由懒加载​​
  • ​​五、组件库antd使用​​
  • ​​六、配置别名路径​​
  • ​​安装@craco/craco​​
  • ​​@别名路径提示​​
  • ​​七、安装dev-tools调试工具​​
  • ​​八、封装axios工具模块​​
  • ​​九、使用mobx​​
  • ​​模块化配置​​
  • ​​组件中使用mobx​​
  • ​​十、项目本地预览​​
  • ​​十一、 打包体积分析​​
  • ​​十二、优化CDN配置​​

一,项目搭建

安装脚手架CRA

  1. 使用​​create-react-app​​生成项目 ​​npx create-react-app 自定义项目名​
  2. 进入根目录​​cd 自定义项目名​
  3. 启动项目​​npm run start​
  4. 调整项目目录结构

/src
/assets 项目资源文件,比如,图片 等
/components 通用组件
/pages 页面
/store mobx 状态仓库
/utils 工具,比如,token、axios 的封装等
App.js 根组件
index.css 全局样式
index.js 项目入口

保留核心代码

​src/index.js​

import React from 'react'
import ReactDOM from 'react-dom'
import App from './App'

ReactDOM.render(
<React.StrictMode>
<App />
</React.StrictMode>,
document.getElementById('root')
)

​src/App.js​

export default function App() {
return <div>根组件</div>
}

二、使用gitee管理项目

  1. 在项目根目录打开终端,并初始化​​git​​​ 仓库(如果已经有了​​git​​​ 仓库,无需重复该步),命令:​​git init​
  2. 添加项目内容到暂存区:​​git add .​
  3. 提交项目内容到仓库区:​​git commit -m '项目初始化'​
  4. 添加 remote 仓库地址:​​git remote add origin [gitee 仓库地址]​
  5. 将项目内容推送到 gitee:​​git push origin master -u​

三、使用scss预处理器

​SASS​​​ 是一种预编译的 ​​CSS​​​,作用类似于 ​​Less​​​。由于 ​​React​​​ 中内置了处理 ​​SASS​​​ 的配置,所以,在 ​​CRA​​​ 创建的项目中,可以直接使用 ​​SASS​​ 来写样式。

  1. 安装解析 sass 的包:​​npm i sass -D​
  2. ​src根目录​​​创建全局样式文件:​​index.scss​

body {
margin: 0;
}

#root {
height: 100%;
}

四、配置路由

基础路由

  1. 安装路由:​​npm i react-router-dom​
  2. 在​​pages​​ 目录中创建两个路由测试文件夹:​​Login​​、​​Layout​
  3. 分别在创建的两个目录中创建​​index.js​​ 文件,并创建一个简单的组件后导出:
    ​pages/Login/index.js​

const Login = () => {
return <div>login</div>
}
export default

​pages/Layout/index.js​

const Layout = () => {
return <div>layout</div>
}
export default

  1. 在​​App​​ 组件中,导入路由组件以及两个页面组件
  2. 配置​​Login​​​ 和​​Layout​​​ 的路由规则
    ​​​App.js​

// 导入路由
import { BrowserRouter, Route, Routes } from 'react-router-dom'

// 导入页面组件
import Login from './pages/Login'
import Layout from './pages/Layout'

// 配置路由规则
function App() {
return (
<BrowserRouter>
<div className="App">
<Routes>
<Route path="/" element={<Layout/>}>
{/* 配置嵌套路由*/}
{/* 二级路由默认页面 */}
{/*<Route index element={<组件1/>} /> */}
{/*<Route path="article" element={<Article />} /> */}
</Route>
<Route path="/login" element={<Login/>}/>
</Routes>
</div>
</BrowserRouter>
)
}

export default

在非组件环境下拿到路由信息

  1. 安装:​​npm i history​
  2. 创建​​utils/history.js ​​文件
    ​utils/history.js​

// https://github.com/remix-run/react-router/issues/8264

import { createBrowserHistory } from 'history'
import { unstable_HistoryRouter as HistoryRouter } from 'react-router-dom'
const history = createBrowserHistory()

export {
HistoryRouter,
history
}

  1. 在app.js中使用我们新建的路由并配置history参数
    ​app.js​

import { HistoryRouter, history } from './utils/history'

function App() {
return (
//HistoryRouter替换BrowserRouter
<HistoryRouter history={history}>
...省略无关代码
</HistoryRouter>
)
}

export default

  1. 使用案例
    ​utils/http.js​

import { history } from './history'

http.interceptors.response.use(
response => {
return response.data
},
error => {
if (error.response.status === 401) {
// 跳转到登录页
history.push('/login')
}
return Promise.reject(error)
}
)

路由懒加载

  1. 在​​App​​​ 组件中,导入​​Suspense​​ 组件
  2. 在 路由​​Router​​​ 内部,使用​​Suspense​​ 组件包裹组件内容
  3. 为​​Suspense​​​ 组件提供​​fallback​​​ 属性,指定​​loading​​ 占位内容
  4. 导入​​lazy​​ 函数,并修改为懒加载方式导入路由组件

​App.js​

import { Routes, Route } from 'react-router-dom'
import { HistoryRouter, history } from './utils/history'


// 导入必要组件
import { lazy, Suspense } from 'react'
// 按需导入路由组件
const Login = lazy(() => import('./pages/Login'))
const Layout = lazy(() => import('./pages/Layout'))
function App () {
return (
<HistoryRouter history={history}>
<Suspense
fallback={
<div
style={{
textAlign: 'center',
marginTop: 200
}}
>
loading...
</div>
}
>
<Routes>
<Route path="/" element={<Layout/>}>
{/* 配置嵌套路由*/}
{/* 二级路由默认页面 */}
{/*<Route index element={<组件1/>} /> */}
{/*<Route path="article" element={<Article />} /> */}
</Route>
<Route path="/login" element={<Login/>}/>
</Routes>
</Suspense>
</HistoryRouter>
)
}

export default

五、组件库antd使用

  1. 安装​​antd​​ 组件库:​​npm i antd​
  2. 全局导入​​antd​​ 组件库的样式
    ​src/index.js​​:

// 先导入 antd 样式文件
// https://github.com/ant-design/ant-design/issues/33327
import 'antd/dist/antd.min.css'
// 再导入全局样式文件,防止样式覆盖!
import './index.css'

  1. 导入​​Button​​ 组件进行测试
  2. 在​​Login​​ 页面渲染 ​​Button​​ 组件进行测试
    ​pages/Login/index.js ​

import { Button } from 'antd'

const Login = () => (
<div>
<Button type="primary">Button</Button>
</div>
)

注意

  1. 在​​src/index.js​​文件中导入 antd 的样式文件
  2. ​antd​​ 的样式文件和我们自己的全局样式文件的导入顺序

六、配置别名路径

安装@craco/craco

​​自定义 CRA 的默认配置​​​​craco 配置文档​​

  • ​CRA​​​ 将所有工程化配置,都隐藏在了​​react-scripts​​ 包中,所以项目中看不到任何配置信息
  • 如果要修改​​CRA​​ 的默认配置,有以下几种方案:
  1. 通过第三方库来修改,比如,​​@craco/craco​​ (推荐
  2. 通过执行​​yarn eject​​​ 命令,释放​​react-scripts​​ 中的所有配置到项目中
  1. 安装修改 CRA 配置的包:​​npm i -D @craco/craco​
  2. 在项目根目录中创建 craco 的配置文件:​​craco.config.js​​,并在配置文件中配置路径别名
    ​craco.config.js​

const path = require('path')

module.exports = {
// webpack 配置
webpack: {
// 配置别名
alias: {
// 约定:使用 @ 表示 src 文件所在路径
'@': path.resolve(__dirname, 'src')
}
}
}

  1. 修改​​package.json​​ 中的脚本命令
    ​package.json​

// 将 start/build/test 三个命令修改为 craco 方式
"scripts": {
"start": "craco start",
"build": "craco build",
"test": "craco test",
"eject": "react-scripts eject"
}

  1. 在代码中,就可以通过​​@​​ 来表示 src 目录的绝对路径
  2. 重启项目,让配置生效

@别名路径提示

  1. 在项目根目录创建​​jsconfig.json​​ 配置文件
  2. 在配置文件中添加以下配置

{

"compilerOptions": {
"baseUrl": "./",
"paths": {
"@/*": ["src/*"]
}
}
}

vscode会自动读取​​jsconfig.json​​​ 中的配置,让vscode知道​​@​​​就是​​src​​目录

七、安装dev-tools调试工具

​​Edge插件下载链接​​

【React】从0到1搭建你的React18项目_前端_02

八、封装axios工具模块

  1. 安装​​axios​​ :​​npm i axios​
  2. 创建​​utils/http.js​​ 文件
    ​utils/http.js​

import axios from 'axios'

const http = axios.create({
baseURL: '请求统一地址',
timeout: 5000 //请求超时时间
})
// 添加请求拦截器
http.interceptors.request.use((config)=> {
return config
}, (error)=> {
return Promise.reject(error)
})

// 添加响应拦截器
http.interceptors.response.use((response)=> {
// 2xx 范围内的状态码都会触发该函数。
// 对响应数据做点什么
return response
}, (error)=> {
// 超出 2xx 范围的状态码都会触发该函数。
// 对响应错误做点什么
return Promise.reject(error)
})

export { http }

  1. 在​​utils/index.js​​ 中,统一导出 ​​http​​​​utils/index.js​

import { http } from './http'
export { http }

九、使用mobx

模块化配置

  1. 安装​​mobx​​: ​​npm i mobx mobx-react-lite​
  2. ​store​​​文件夹下创建单一模块​​store​​ 例:​​store/use.Store.js​

//用户模块
import { computed, makeAutoObservable } from "mobx";
class UserStore {
//定义数据
userinfo= [];
constructor() {
//响应式处理
makeAutoObservable(this, {
// 标记computed
fillterList: computed,
});
//如果没有计算属性直接:
//makeAutoObservable(this);
}
//get计算属性:computed,计算属性需要在makeAutoObservable里做一下标记
get fillterList() {
return this.userinfo.filter((item) => item.name==='ailjx');
}
addUse = () => {
this.userinfo.push({//...});
};
}

//导出
export default UserStore;

  1. ​store​​​文件下创建​​index.js​​统一导出​​store​​​​store/index.js​

import React from "react";
import UserStore from "./use.Store";
class RootStore {
// 组合store
constructor() {
//对子模块进行实例化操作并赋值给RootStore对应的属性
//这样将来实例化RootStore的时候就可以通过对应的属性获取导入的对应子模块的实例对象
this.userStore= new UserStore();
//多个模块按照上述语法补充...
}
}

//实例化根store注入context
const rootStore = new RootStore();
//使用React的useContext机制 导出useStore方法,供业务组件统一使用
//useContext查找机制:优先从Provider value找,如果找不到,就会找createContext方法传递过来的默认参数
//核心目的:让每个业务组件可以通过统一一样的方法获取store的数据
const context = React.createContext(rootStore);

//通过useContext拿到rootStore实例对象,然后返回给useStore
//导出useStore方法,供组件通过调用该方法使用根实例
//在业务组件中 调用useStore()->rootStore
const useStore = () => React.useContext(context);
export { useStore };

//以上是模板代码,在不同项目都通用

组件中使用mobx

例如:在​​Login​​组件中使用

import { useStore } from '@/store'
const Login = () => {
//解构出useStore模块
const { useStore} = useStore()
//调用useStore模块的addUse方法
useStore.addUse ()
return (...)
}

十、项目本地预览

项目经过打包过后,往往需要本地预览服务端运行时的效果:

  1. 全局安装本地服务包​​npm i -g serve​​​ 该包提供了​​serve​​命令,用来启动本地服务
  2. 在项目根目录中执行命令​​serve -s ./build​​ 在build目录中开启服务器
  3. 在浏览器中访问:​​http://localhost:3000/​​ 预览项目

十一、 打包体积分析

  1. 安装分析打包体积的包:​​npm i source-map-explorer​
  2. 在​​package.json​​ 中的 ​​scripts​​ 标签中,添加分析打包体积的命令
    ​package.json​​ 中:

"scripts": {
"analyze": "source-map-explorer 'build/static/js/*.js'",
}

  1. 对项目打包:​​npm run build​​(如果已经打过包,可省略这一步)
  2. 运行分析命令:​​npm run analyze​
  3. 通过浏览器打开的页面,分析图表中的包体积

十二、优化CDN配置

通过 craco 来修改 webpack 配置,从而实现 CDN 优化
​​​craco.config.js​

// 添加自定义对于webpack的配置

const path = require("path");
const { whenProd, getPlugin, pluginByName } = require("@craco/craco");

module.exports = {
// webpack 配置
webpack: {
// 配置别名
alias: {
// 约定:使用 @ 表示 src 文件所在路径
"@": path.resolve(__dirname, "src"),
},
// 配置webpack
// 配置CDN,配和public/index.html中配置使用
configure: (webpackConfig) => {
// webpackConfig自动注入的webpack配置对象
// 可以在这个函数中对它进行详细的自定义配置
// 只要最后return出去就行
let cdn = {
js: [],
css: [],
};
// 只有生产环境才配置
whenProd(() => {
// key:需要不参与打包的具体的包
// value: cdn文件中 挂载于全局的变量名称 为了替换之前在开发环境下
// 通过import 导入的 react / react-dom
webpackConfig.externals = {
react: "React",
"react-dom": "ReactDOM",
};
// 配置现成的cdn 资源数组 现在是公共为了测试
// 实际开发的时候 用公司自己花钱买的cdn服务器
cdn = {
js: [
"https://cdnjs.cloudflare.com/ajax/libs/react/18.1.0/umd/react.production.min.js",
"https://cdnjs.cloudflare.com/ajax/libs/react-dom/18.1.0/umd/react-dom.production.min.js",
],
css: [],
};
});

// 都是为了将来配置 htmlWebpackPlugin插件 将来在public/index.html注入
// cdn资源数组时 准备好的一些现成的资源
const { isFound, match } = getPlugin(
webpackConfig,
pluginByName("HtmlWebpackPlugin")
);

if (isFound) {
// 找到了HtmlWebpackPlugin的插件
match.userOptions.cdn = cdn;
}

return webpackConfig;
},
},
};

​public/index.html ​

<body>
<div id="root"></div>
<!-- 加载第三发包的 CDN 链接 -->
<% htmlWebpackPlugin.options.cdn.js.forEach(cdnURL=> { %>
<script src="<%= cdnURL %>"></script>
<% }) %>
</body>


举报

相关推荐

0 条评论