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

相关推荐
徐同保2 小时前
n8n项目编译时取消类型检测,提交代码时取消校验
开发语言·前端·javascript
不会kao代码的小王2 小时前
openEuler上Docker部署Kafka消息队列实战
前端·云原生·stable diffusion·eureka
Lenyiin2 小时前
makefile
java·大数据·前端
汝生淮南吾在北3 小时前
SpringBoot+Vue非遗文化宣传网站
java·前端·vue.js·spring boot·后端·毕业设计·课程设计
谷粒.3 小时前
AI在测试中的应用:从自动化到智能化的跨越
运维·前端·网络·人工智能·测试工具·开源·自动化
斗鹰一余洛晟3 小时前
Web跨域问题
前端·状态模式
悟能不能悟3 小时前
前端如何重定向
前端
GIS遥遥3 小时前
如何用 Cesium 实现楼栋单体化?前端 WebGIS 实战教程
前端·javascript·cesium·三维gis开发