温馨提示×

温馨提示×

您好,登录后才能下订单哦!

密码登录×
登录注册×
其他方式登录
点击 登录注册 即表示同意《亿速云用户服务条款》

如何解决antd+react项目迁移vite的问题

发布时间:2021-07-07 15:54:04 来源:亿速云 阅读:250 作者:chen 栏目:编程语言

本篇内容介绍了“如何解决antd+react项目迁移vite的问题”的有关知识,在实际案例的操作过程中,不少人都会遇到这样的困境,接下来就让小编带领大家学习一下如何处理这些情况吧!希望大家仔细阅读,能够学有所成!

  antd+react+webpack往往是以react技术栈为主的前端项目的标准组合,三者都有成熟的生态和稳定的表现,但随着前端圈的技术不断革新,号称下一代构建平台vite2的发布,webpack似乎不那么香了,为什么这么说呢,因为vite太快了。经过一段时间的尝试,决定在项目中把webpack替换成vite试试,遂写成本文分享给大家。

  Vite是什么

  作为本文的主角,首先简单介绍一下vite这个构建工具,该工具是尤雨溪推出的【下一代前端开发和构建工具】,vite其实也不是一个新的工具,早在一年多以前,就已经推出了很多版本,直到2.x版本的推出,在前端圈引起了足够大的震动,标志着vite的成熟和强大,这里并不打算详细介绍vite,大家可以参考官网https://cn.vitejs.dev/ 了解。

  迁移过程

  了解了vite这款工具之后,我们就可以着手准备做迁移工作了;

  1.安装vite依赖

  npm i vite antd-vite-import-plugin @vitejs/plugin-react-refresh vite-plugin-html -D

  2.更新项目原有依赖项

  这里我们项目使用的是dva+antd3.x作为基础的开发框架,这里我将系统的主要依赖项都升级到了最新的版本,比如dva我用的2.6.0-beta.22版本,其他附带的react、react-dom、react-router-dom及@babel/plugin-transform-runtime等相关依赖项都更新了(antd还是3.x版本,暂未更新到4.x的大版本),这一块取决于自己的实际需求;

  3.项目根目录添加vite.config.js配置文件

  和webpack的配置文件比起来,vite的简单了许多,而且很多功能都是内置的,比如对静态资源的处理,功能开启也比较简单,具体如下:

  import { defineConfig } from 'vite';

  import vitePluginHtml from 'vite-plugin-html';

  import reactRefresh from '@vitejs/plugin-react-refresh';

  export default defineConfig({

  css: {

  preprocessorOptions: {

  less: {

  javascriptEnabled: true,

  },

  }

  },

  publicDir: './src/configs',

  plugins: [

  reactRefresh(),

  antdViteImportPlugin(),

  vitePluginHtml({

  minify: true,

  inject: {

  injectData: {

  title: 'vite-react-example',

  injectScript: '', // publicDir作为根目录

  },

  injectOptions: {

  filename: './index.html', // 模板页

  }

  },

  }),

  ],

  server: {

  open: true,

  port: 10010,

  }

  });

  这里我们使用了vite-plugin-html插件作为html-webpack-plugin的替代方案,其中需要注意injectData和injectOptions选项,injectData可以方便的往我们的模板页中插入自定义数据,injectOptions可以指定模板页,还有其他配置项可以参考https://www.npmjs.com/package/vite-plugin-html 。相应的需要改造index.html页面:

  ......

  和webpack有差异的是,这里我们需要手动指定一下入口文件,script的标签type为module。

  4.修改文件后缀

  这里的文件是以js作为后缀的react组件,在webpack构建平台下,js(x)、ts(x)都是没啥问题的,但如果使用vite的话,那么最好是ts 、 jsx 、 tsx 的后缀文件,关于这个问题,可以看下这个issue:https://github.com/vitejs/vite/issues/1552 ,最后作者发出批量改个后缀有这么难的吐槽,算了,还是改吧,如果觉得手动改麻烦,写个脚本也不是啥难事。

  5.添加启动脚本

  "scripts": {

  "dev": "vite",

  "build": "vite build",

  ......

  }

  到这里应该就差不多了吧,但是情况却不是那么顺利,项目居然跑不起来,好吧,没有那么一帆风顺的事情,接下来我们来看下遇到的问题吧。

  遇到的问题

  1.decorators not support

  在业务代码中,我们使用了dva提供的connect来绑定状态,形如:

  @connect(state => state.foo)

  class Foo extends React.PureComponent {

  ....

  }

  但是decorators语法居然不被vite支持,关于这个问题,也有一个issus:https://github.com/vitejs/vite/issues/2349 ,目前没有一个好的解决办法,只好去掉decorators,改用常规的函数绑定了。

  2.antd Unknown theme type: undefined, name: undefined

  我们项目目前还是使用的antd的3.x版本,在启动时就出现了这个错误,其实主要是antd组件初始化的时候,加载了antd/es/icon/index.js文件:

  import * as allIcons from '@ant-design/icons/lib/dist';

  ......

  ReactIcon.add.apply(ReactIcon, _toConsumableArray(Object.keys(allIcons).map(function (key) {

  return allIcons[key];

  })));

  ......

  '@ant-design/icons/lib/dist'导出的对象是{ default: {...} },要正确访问的形式是allIcons.default,而不是allIcons,因此导致获取不到icon的正确导出对象,关于这个问题,大家可以看下这个issue:https://github.com/ant-design/ant-design/issues/19002 ,这里要说明的一点是antd4.x版本不会出现,但是对于我们的项目来讲,目前还不会升级到4这个大版本,那么怎么解决呢,其实只要引用antd/lib下的组件,就没有这个问题了,我们可以看下antd/lib/icon/index.js:

  ......

  var allIcons = _interopRequireWildcard(require("@ant-design/icons/lib/dist"));

  function _interopRequireWildcard(obj) { if (obj && obj.__esModule) { return obj; } if (obj === null || _typeof(obj) !== "object" && typeof obj !== "function") { return { "default": obj }; } var cache = _getRequireWildcardCache(); if (cache && cache.has(obj)) { return cache.get(obj); } var newObj = {}; var hasPropertyDescriptor = Object.defineProperty && Object.getOwnPropertyDescriptor; for (var key in obj) { if (Object.prototype.hasOwnProperty.call(obj, key)) { var desc = hasPropertyDescriptor ? Object.getOwnPropertyDescriptor(obj, key) : null; if (desc && (desc.get || desc.set)) { Object.defineProperty(newObj, key, desc); } else { newObj[key] = obj[key]; } } } newObj["default"] = obj; if (cache) { cache.set(obj, newObj); } return newObj; }

  ......

  这里_interopRequireWildcard方法帮我们处理了导出的问题,那么修改一下babel-plugin-import的配置不就好了么,好吧,没有那么容易的,vite对babel-plugin-import支持不那么好,首先还是去vite的issues里面找找看,有一个类似的提问:https://github.com/vitejs/vite/issues/1389 ,看了下,并没有解决我的问题,里面提到的几个插件倒是给我了思路,那就自己写个vite插件去实现我们的需求呗。插件的思路很简单,就是将antd组件的引入方式进行统一的修改:

  ---修改前---

  import { Button } from 'antd';

  ---修改后---

  import Button from 'antd/lib/button';

  import 'antd/lib/button/style/index.css';郑州治疗男科病医院http://www.zztjnk.com/

  这里需要说明的是css样式的引入,如果引入style/index或者style/css,会出现require is not defined的问题,因为这两个js文件中使用了require,但是vite在预编译时不是node环境,当然就报错了。

  关于这个插件的使用,可以参考https://www.npmjs.com/package/antd-vite-import-plugin 。

  3.'default' is not exported  郑州同济医院http://www.xasgnk.com/

  有时候三方依赖项加载会出错,例如'default' is not exported等,这里可以参考https://github.com/vitejs/vite/issues/2679

  在实际开发过程中,还是难免遇到一些奇怪的问题,这都是尝鲜的代价。

  速度之争

  vite的一个优势就是快,那么和webpack相比,到底有多大的差距呢,这里我们用webpack和vite分别启动同一个本地项目:

  构建工具启动时间(ms)  郑州同济医院http://www.zzfkyy120.com/

  vite702ms

  webpack7093ms

  这里只是一个粗略的对比,从数据上看有十倍之差,单从速度上讲,vite是很快了,根据官网的解释,Vite 将会使用 esbuild 预构建依赖。Esbuild 使用 Go 编写,并且比以 JavaScript 编写的打包器预构建依赖快 10-100 倍。

  最后

  经历过一番折腾后,觉得vite2的成熟度有所欠缺,在一些小项目中可以试试。对我而言还是决定先用webpack吧,毕竟webpack经过这么多年的发展,坑很少,而目前vite对于react来说还是不那么完美。

“如何解决antd+react项目迁移vite的问题”的内容就介绍到这里了,感谢大家的阅读。如果想了解更多行业相关的知识可以关注亿速云网站,小编将为大家输出更多高质量的实用文章!

向AI问一下细节

免责声明:本站发布的内容(图片、视频和文字)以原创、转载和分享为主,文章观点不代表本网站立场,如果涉及侵权请联系站长邮箱:is@yisu.com进行举报,并提供相关证据,一经查实,将立刻删除涉嫌侵权内容。

AI