【React】极客园案例实践-编辑文章模块和项目打包

前情提要-文章列表模块完成

编辑文章模块

  • 6、编辑文章模块
    • [6-1 基础数据回填](#6-1 基础数据回填)
    • [6-2 回填封面信息](#6-2 回填封面信息)
    • [6-3 根据id适配发布和编辑状态](#6-3 根据id适配发布和编辑状态)
    • [6-4 更新文章](#6-4 更新文章)
  • 7、项目打包
    • [7-1 项目打包](#7-1 项目打包)
    • [7-2 项目本地预览](#7-2 项目本地预览)
    • [7-3 优化-路由懒加载](#7-3 优化-路由懒加载)
    • [7-4 优化-包体积分析](#7-4 优化-包体积分析)
    • [7-5 优化-配置CDN](#7-5 优化-配置CDN)

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创建

实现步骤

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

使用vite创建

Vite 自带 生产环境预览命令,不需要额外装 serve 包
启动本地预览服务器

bash 复制代码
npm run preview

可以自定义预览端口

json 复制代码
{
  "scripts": {
    "build": "vite build",
    "preview": "vite preview --port 3000" // 自定义端口 3000
  }
}

7-3 优化-路由懒加载

路由懒加载是指路由的JS资源只有在被访问时才会动态获取,目的是为了优化项目首次打开的时间

使用步骤

  1. 使用 lazy 方法导入路由组件
  2. 使用内置的 Suspense 组件渲染路由组件

代码实现
router/index.js

查看效果

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

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

7-4 优化-包体积分析

通过可视化的方式,直观的体现项目中各种包打包之后的体积大小,方便做优化

怎么做到?

source-map-explorer

  1. 安装包
  2. 配置命令指定要分析的js文件

使用步骤

  1. 安装分析打包体积的包:npm i source-map-explorer
  2. 在 package.json 中的 scripts 标签中,添加分析打包体积的命令
  3. 对项目打包:npm run build(如果已经打过包,可省略这一步)
  4. 运行分析命令:npm run analyze
  5. 通过浏览器打开的页面,分析图表中的包体积

核心代码

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的实现步骤由豆包生成,未实践

相关推荐
mldong22 分钟前
你的 Vue3 项目也能有钉钉同款审批流设计器:npm 装包,10 分钟画出第一条审批流
前端·vue.js
2分钟速写快排1 小时前
什么是 RAG?如何用 RAG 实现一个用户记忆?
前端·后端·ai编程
passerby60612 小时前
如何自己造一个时间处理库
前端·javascript·github
走到天涯海角3 小时前
react里面的长列表渲染优化
前端·react.js·前端框架
小羊没烦恼!3 小时前
Hello Web API系列教程——Web API与国际化
java·服务器·前端·javascript·php
北岛贰3 小时前
迷茫焦虑期,我做了一个带支付带官网的 AI 聊天虚拟恋人 App
前端·人工智能·后端
mayaairi4 小时前
Vue2 组件通讯(三):全局事件总线、PubSub、插槽与组件实例属性
前端·javascript·vue.js
kyriewen5 小时前
面试官问我:AI 都能写代码了,前端凭什么还值 25K
前端·javascript·人工智能
风骏时光牛马6 小时前
AI源码分析:拆解模型底层实现逻辑
前端
IT_陈寒6 小时前
React子组件莫名其妙重渲染?你可能漏了这个Hook
前端·人工智能·后端