使用 vite + typescript + react + antd 一个月的开发体验和遇到的问题


使用 vite 一个月的开发体验

先总结下,体验很好,快得飞起,很舒服。但是,在每次重新构建的时候也挺慢的看这儿 file-system-cache。

Technologies Stack

  • typescript - TypeScript is a typed superset of JavaScript that compiles to plain JavaScrip
  • pnpm - 快速的,节省磁盘空间的包管理工具
  • vite - 下一代前端开发与构建工具
  • rollup - A module bundler for JavaScript
  • react - A JavaScript library for building user interfaces
  • @ahooksjs/use-request/umi-request - 再见 axios!!!
  • pont - 搭建前后端之桥
  • Java to TypeScript - 也许可以不用 Swagger 之类的工具,而是本地静态编译/远程git编译 Java 到 type script。

UI Frameworks

  • ant-design - 企业级产品设计体系,创造高效愉悦的工作体验
  • ant-design-pro - 开箱即用的中台前端/设计解决方案
  • ProComponents - ?? 让中后台开发更简单
  • fusion-design - 企业级的中后台设计系统解决方案

TypeScript

  • TypeScript with React App
  • Declaration Reference
  • In TypeScript, how to get the keys of an object type whose values are of a given type?
  • How to build a type from enum values in TypeScript?
  • Use Typescript enum values to create new type
  • Using the keys of an object literal as a Typescript type?
  • TypeScript: extending imported enum
  • Typescript: Type 'string | undefined' is not assignable to type 'string'
  • useRef TypeScript - not assignable to type LegacyRef
  • How to force tsc to ignore node_modules folder?
  • When to use JSX.Element vs ReactNode vs ReactElement?
  • How to detect a React component vs. a React element?
  • how to pass props to lazy loading components?
  • Is it possible to use getters/setters in TypeScript Interfaces? - Stack Overflow
  • What is the syntax for Typescript arrow functions with generics?

Import antd step by step

  • Install antd
pnpm i antd @ant-design/icons -S
  • Load dependencies on-demand
pnpm i vite-plugin-imp -D
  • Add imp configuration

vite.config.ts:

  vitePluginImp({
      optimize: true,
      libList: [
        {
          libName: 'antd',
          libDirectory: 'es',
          style: (name) => `antd/es/${name}/style`
        }
      ]
    })
  • Install less & less loader
pnpm i less less-loader -D
  • Enable JavaScript for less

vite.config.ts:

  css: {
    preprocessorOptions: {
      less: {
        javascriptEnabled: true
      }
    }
  }
  • Install ant-design & procomponents
pnpm i @ant-design/pro-layout @ant-design/pro-table @ant-design/pro-skeleton @ant-design/pro-form --save
  • Fix ~ issue

因为在 @ant-design/pro-* 即 procomponents 中使用 ~ 引入了 ~antd 的样式,所以需要重写下 resolve.alias

  resolve: {
    alias: [
      { find: /^~antd/, replacement: path.resolve('./', 'node_modules/antd/') },
      { find: '@', replacement: path.resolve('./', 'src') }
      /* {
        '@': path.resolve('./', 'src')
      } */
    ]
  }

References

  • Vite 2.0 + React + Ant Design 4.0 搭建开发环境
  • 这篇比上篇更全更好更少坑:从零搭建 Vite + React 开发环境
  • 在vue3-vite中配置less的全局变量
  • umijs docs
  • vite-plugin-imp 一个自动导入组件库样式的vite插件
  • Why moment? antd 依赖了 moment 和 lodash ~~
  • When to use useCallback, useMemo and useEffect?

Issues

  • Cannot find module 'antd' 如何解决?
  • VSCode: Cannot find module 'antd' or its corresponding type declarations

    我的解决办法是重新安装了一遍依赖,居然就好了?!!!
  • HMR does not work
  • IMPORTANT: 如果当前页面当前组件热更新了了多次,事件会被绑定多次!!!
  • React Router with - Ant Design Sider: how to populate content section with components for relevant menu item
  • 使用 antd Row 组件时 vite 提示引入 row 组件 css 发生错误:
[plugin:vite:import-analysis] Failed to resolve import "antd/lib/row/style/index.less" from "src/views/Form/Base/Project/index.tsx". Does the file exist?
/Users/wucheng085/Development/WorkSpace/luban/construct-luban-award-frontend/src/views/Form/Base/Project/index.tsx:2:9
1  |  import 'antd/lib/steps/style/index.less'
2  |  import 'antd/lib/row/style/index.less'
   |          ^
3  |  import 'antd/lib/col/style/index.less'
4  |

我特地去看了下,的确没有 index.less:

ls node_modules/antd/lib/row/style/
css.js      index.d.ts  index.js

所以这里要把 import 'antd/lib/row/style/index.less' 改成 import 'antd/lib/row/style/css.js'。

  1. 我试着改全局的 vitePluginImp 配置。
  2. 不行的话,我在重写方法,匹配 Row/Col 去定义。

第一个方法出错了,意思就是说不支持在 js 中引入 .css:

react.development.js:1309 Uncaught Error: Dynamic require of "/Users/wucheng085/Development/WorkSpace/luban/construct-luban-award-frontend/node_modules/.pnpm/antd@4.16.7_react-dom@17.0.2+react@17.0.2/node_modules/antd/lib/style/index.css" is not supported
    at __require (chunk-R6I3GLEQ.js?v=9a889dec:11)
    at node_modules/.pnpm/antd@4.16.7_react-dom@17.0.2+react@17.0.2/node_modules/antd/lib/avatar/style/css.js (css.js:3)
    at __require2 (chunk-R6I3GLEQ.js?v=9a889dec:14)
    at dep:antd_lib_avatar_style_css_js:1
__require @ chunk-R6I3GLEQ.js?v=9a889dec:11
node_modules/.pnpm/antd@4.16.7_react-dom@17.0.2+react@17.0.2/node_modules/antd/lib/avatar/style/css.js @ css.js:3
__require2 @ chunk-R6I3GLEQ.js?v=9a889dec:14
(anonymous) @ dep:antd_lib_avatar_style_css_js:1
  1. 看了 vite-plugin-imp 的 API,最终改成了这样解决,完美:
    vitePluginImp({
      optimize: true,
      libList: [
        {
          libName: 'antd',
          libDirectory: 'es',
          style: (name) => `antd/es/${name}/style`
        }
      ]
    })
  • eslint import/resolver 并不支持 alias导致 eslint 报错:
error  Unable to resolve path to module '@/layouts/LoginLayout'  import/no-unresolved

解决办法是:

  1. 安装 eslint-import-resolver-alias 插件
pnpm install npm install eslint-plugin-import eslint-import-resolver-alias --save-dev
  1. Vite.js + Eslint unable to resolve path alias
  2. .eslintrc 添加如下配置:
  settings: {
    'import/resolver': {
      node: {
        extensions: ['.js', '.jsx', '.ts', '.tsx']
      },
      alias: {
        map: [['@', './src']],
        extensions: ['.ts', '.tsx', '.js', '.jsx', '.json']
      },
    }
  }
  • 在把 @ant-design/pro-form 从 v1.34.2 升级到 v1.35.0 时候发现本地代码没有更新依然使用的缓存。
  1. pnpm 中的代码包没有更新,但是执行了 pnpm install/update package@version 之后依然无效
  2. vite 中的预构建文件系统缓存没有更新
  3. 删除缓存,重新构建,结果奇慢
  • React - How to forward multiple refs?
  • React - forceUpdate with React Hooks
  • Can't perform a React state update on an unmounted component
  • React state update on an unmounted component
  • 执行 pnpm update 更新依赖之后报错。我的推测是此次更新重建了 node_modules 目录,删除了 .vite 下面的缓存,导致某些隐式依赖(即A包引用了B包,但package.json中没有声明B包)没有找到。
error when starting dev server:
Error: The following dependencies are imported but could not be resolved:

  @ant-design/pro-utils (imported by /Users/wucheng085/Development/WorkSpace/luban/construct-luban-award-frontend/src/views/Form/Base/Project/useFormData.ts)
  @ant-design/pro-field (imported by /Users/wucheng085/Development/WorkSpace/luban/construct-luban-award-frontend/src/views/Form/Overview/StepDesc.tsx)

Are they installed?
    at optimizeDeps (/Users/wucheng085/Development/WorkSpace/luban/construct-luban-award-frontend/node_modules/.pnpm/registry.nlark.com+vite@2.5.3/node_modules/vite/dist/node/chunks/dep-1be34a63.js:71523:15)
    at processTicksAndRejections (internal/process/task_queues.js:97:5)
    at async runOptimize (/Users/wucheng085/Development/WorkSpace/luban/construct-luban-award-frontend/node_modules/.pnpm/registry.nlark.com+vite@2.5.3/node_modules/vite/dist/node/chunks/dep-1be34a63.js:75389:48)
    at async Server.httpServer.listen (/Users/wucheng085/Development/WorkSpace/luban/construct-luban-award-frontend/node_modules/.pnpm/registry.nlark.com+vite@2.5.3/node_modules/vite/dist/node/chunks/dep-1be34a63.js:75405:21)
?ERROR? Command failed with exit code 1.

解决办法:
Are they installed?看到,那就手动的 install 一遍并声明到 package.json 中做显式依赖。又开始愉快的编程了。

扩展与思考

  • vite 简介 - 下一代前端开发与构建工具
    • 接近于完美的文档 - https://cn.vitejs.dev/
    • 越发完善的社区 - https://github.com/vitejs/awesome-vite#integrations-with-backends
  • vite 搭建项目(react + typescript + antd + pro-components 爬坑)
    - pro-components - 中后台大杀器
    - Field
    - ValueType
    • 遇到的问题(坑)
  • vite 开发体验 - https://juejin.cn/post/6937847568114122760
    • Lightning fast cold server start - 闪电般的冷启动速度
      • 预构建
        • https://cn.vitejs.dev/guide/dep-pre-bundling.html - 演示项目的 .vite 缓存
        • BTW, https://zhuanlan.zhihu.com/p/360109945 - 与官方文档基本一样,贴了几张源码阅读
    • Instant hot module replacement (HMR) - 即时热模块更换(热更新)
    • True on-demand compilation - 真正的按需编译
  • vite 与 Snowpack/Sandpack, Webpack/Parcel 的对比
    • vite 的比较章节 https://cn.vitejs.dev/guide/comparisons.html
    • React-Conf Europe 2020 - Let’s Make Development Fast Again! - https://www.youtube.com/watch?v=Yu9zcJJ4Uz0
      • Recompilation 优化笔记
      • Bundlers
        • Webpack/Parcel...
      • Unbundled/Bundleless - Development focused “Bundlers”
        • Vite/Sandpack/Snowpack
          • https://cn.vitejs.dev/guide/why.html
          • https://www.snowpack.dev/concepts/how-snowpack-works
  • 社区项目探讨 - Next?
    • Prepack - https://prepack.io/
    • Umi.js mfsu - https://umijs.org/zh-CN/docs/mfsu
    • esbuild - https://esbuild.github.io/
    • swc - https://swc.rs/
    • skypack, Load optimized npm packages with no install and no build tools. - https://www.skypack.dev/
    • quick.js - https://github.com/quickjs-zh/QuickJS

Refs

  • 卷?能有搞开源打包工具的大佬们卷?- https://zhuanlan.zhihu.com/p/375402673
  • Vite 2.0 初探 - https://zhuanlan.zhihu.com/p/360109945
  • Vite 2.0 预构建源码解析 - https://juejin.cn/post/6938003239610613773