前情提要-文章列表模块完成
编辑文章模块
- 6、编辑文章模块
-
- [6-1 基础数据回填](#6-1 基础数据回填)
- [6-2 回填封面信息](#6-2 回填封面信息)
- [6-3 根据id适配发布和编辑状态](#6-3 根据id适配发布和编辑状态)
- [6-4 更新文章](#6-4 更新文章)
- 7、项目打包
6、编辑文章模块
6-1 基础数据回填




提交-33编辑功能-基础数据回填

此时回显没有回显图片
6-2 回填封面信息


// 获取实例
const [form] = Form.useForm()
// 回填数据
const [searchParams] = useSearchParams()
const articleId = searchParams.get('id')
useEffect(() => {
// 1.通过文章id获取数据
async function getArticleDetails() {
const res = await getArticleByID(articleId)
// 2.通过调用form组件的实例方法setFieldsValue回显数据
form.setFieldsValue({
...res.data,
// 回显封面类型
type: res.data.cover.type
})
// 回显图片列表(控制Upload组件的显示,ImageType > 0才显示)
setImageType(res.data.cover.type)
// 回显图片
setImageList(res.data.cover.images.map(url => {
return { url }
}))
// 同时将图片存在仓库里,这样无图单图三图切换已经上传的图片不会消失
cacheImageList.current = res.data.cover.images.map(url => {
return { url }
})
}
getArticleDetails()
}, [articleId, form])
提交-34编辑功能-回填封面信息

6-3 根据id适配发布和编辑状态


提交-35使用id区分发布和编辑状态
6-4 更新文章



提交-36编辑功能-更新文章

7、项目打包
7-1 项目打包
打包指的是将项目中的源代码和资源文件进行处理,生成可在生产环境中运行的静态文件的过程
bash
npm run build
构建出生产环境包(vite生成 dist 目录,CRA 生成 build 目录)
7-2 项目本地预览
本地预览是指在本地通过静态服务器模拟生产服务器运行项目的过程
使用CRA创建
实现步骤
- 全局安装本地服务包
npm i -g serve该包提供了serve命令,用来启动本地服务器 - 在项目根目录中执行命令
serve -s ./build在build目录中开启服务器 - 在浏览器中访问:
http://localhost:3000/预览项目
使用vite创建
Vite 自带 生产环境预览命令,不需要额外装 serve 包
启动本地预览服务器
bash
npm run preview
可以自定义预览端口

json
{
"scripts": {
"build": "vite build",
"preview": "vite preview --port 3000" // 自定义端口 3000
}
}
7-3 优化-路由懒加载
路由懒加载是指路由的JS资源只有在被访问时才会动态获取,目的是为了优化项目首次打开的时间

使用步骤
- 使用 lazy 方法导入路由组件
- 使用内置的 Suspense 组件渲染路由组件
代码实现
router/index.js

查看效果
我们可以在打包之后,通过切换路由,监控network面板资源的请求情况,验证是否分隔成功

提交-打包路由懒加载优化

7-4 优化-包体积分析
通过可视化的方式,直观的体现项目中各种包打包之后的体积大小,方便做优化
怎么做到?
source-map-explorer
- 安装包
- 配置命令指定要分析的js文件
使用步骤
- 安装分析打包体积的包:
npm i source-map-explorer - 在 package.json 中的 scripts 标签中,添加分析打包体积的命令
- 对项目打包:
npm run build(如果已经打过包,可省略这一步) - 运行分析命令:
npm run analyze - 通过浏览器打开的页面,分析图表中的包体积
核心代码:
json
"scripts": {
"analyze": "source-map-explorer 'build/static/js/*.js'",
}
7-5 优化-配置CDN
排除不需要打包的依赖 + 注入 CDN 链接到 HTML

使用CRA创建
分析说明 :通过 craco 来修改 webpack 配置,从而实现 CDN 优化
核心代码
craco.config.js
javascript
// 添加自定义对于webpack的配置
const path = require('path')
const { whenProd, getPlugin, pluginByName } = require('@craco/craco')
module.exports = {
// webpack 配置
webpack: {
// 配置别名
alias: {
// 约定:使用 @ 表示 src 文件所在路径
'@': path.resolve(__dirname, 'src')
},
// 配置webpack
// 配置CDN
configure: (webpackConfig) => {
let cdn = {
js:[]
}
whenProd(() => {
// key: 不参与打包的包(由dependencies依赖项中的key决定)
// value: cdn文件中 挂载于全局的变量名称 为了替换之前在开发环境下
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',
]
}
})
// 通过 htmlWebpackPlugin插件 在public/index.html注入cdn资源url
const { isFound, match } = getPlugin(
webpackConfig,
pluginByName('HtmlWebpackPlugin')
)
if (isFound) {
// 找到了HtmlWebpackPlugin的插件
match.userOptions.files = cdn
}
return webpackConfig
}
}
}
public/index.html
html
<body>
<div id="root"></div>
<!-- 加载第三发包的 CDN 链接 -->
<% htmlWebpackPlugin.options.files.js.forEach(cdnURL => { %>
<script src="<%= cdnURL %>"></script>
<% }) %>
</body>
使用vite创建
修改vite.config.js
bash
import { defineConfig, loadEnv } from 'vite'
import react from '@vitejs/plugin-react'
export default defineConfig(({ mode }) => {
const env = loadEnv(mode, process.cwd()) // 加载环境变量(区分开发/生产)
return {
plugins: [react()],
// 1. 配置别名(和你 CRA 的 @ 别名一致)
resolve: {
alias: {
'@': '/src' // 约定 @ 指向 src 目录(Vite 支持直接写绝对路径,无需 path.resolve)
}
},
// 2. 配置 CDN:生产环境排除依赖 + 注入 CDN 链接
build: {
rollupOptions: {
external: mode === 'production' ? ['react', 'react-dom'] : [], // 生产环境排除依赖(不打包)
output: {
// 3. 映射:告诉 Vite 排除的依赖,对应的全局变量名(和 CRA 的 externals 作用一致)
globals: {
react: 'React', // 对应 CDN 暴露的全局变量 React
'react-dom': 'ReactDOM' // 对应 CDN 暴露的全局变量 ReactDOM
}
}
}
},
// 4. 注入 CDN 链接到 HTML(替代 CRA 的 HtmlWebpackPlugin 配置)
plugins: [
react(),
// 生产环境才注入 CDN 链接
mode === 'production' && {
name: 'inject-cdn',
transformIndexHtml(html) {
// 要注入的 CDN 链接(和你 CRA 的 cdn.js 一致)
const cdnJs = [
'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'
]
// 拼接成 script 标签,注入到 body 末尾(root 后面)
const cdnScript = cdnJs.map(url => `<script src="${url}"></script>`).join('\n')
// 替换 </div> 后面的位置,和你 CRA 的 index.html 注入逻辑一致
return html.replace('</div>', `</div>\n${cdnScript}`)
}
}
].filter(Boolean) // 过滤掉开发环境的 undefined 插件
}
})
public/index.html
和你CRA 不同,Vite 可以通过插件自动注入 CDN 链接,不需要在 HTML 中写 <% htmlWebpackPlugin %> 模板语法
bash
<!DOCTYPE html>
<html lang="zh-CN">
<head>
<meta charset="UTF-8">
<link rel="icon" type="image/svg+xml" href="/vite.svg">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Vite + React</title>
</head>
<body>
<div id="root"></div>
<!-- CDN 链接会被 Vite 自动注入到这里(生产环境) -->
<script type="module" src="/src/main.jsx"></script>
</body>
</html>
vite创建的项目配置CDN的实现步骤由豆包生成,未实践