webpack react项目 完美迁移vite — 坑点记录!

前言

最近我们的cli打包工具要全面升级,@mx-design/cli,github地址,欢迎给个start:https://github.com/lio-mengxiang/mx-design-cli

我们这个工具分为三大功能,市面还没有这样的集成工具:

  • 开发环境是 vite
  • 打包业务代码是 webpack5,支持自定义配置
  • 打包组件库是rollup(正在升级,这周完成),支持6种默认打包方式(带css,不带css,umd/esm/cjs格式)

目的是让业务方0配置就能启动基本的项目。

欢迎加我微信进群一起讨论:a2298613245

下面是具体在用vite替换webpack5遇到的问题汇总,总体来说还是比较顺利,花了1天半升级完毕。

css module

webpack里css module的开启方法是在css-loader里配置,而vite是天生就支持,但是蛋疼的是需要把less或者css文件改为 module.less或者module.css结尾,会自动开启css module

动态import

webpack里动态分割代码用的是import,在vite的开发环境也是支持import语法的,但是,vite的import的语法是有规范的。

我们当时不成功的原因是没有补全后缀,比如说在webpack里,我这样引用

import('./pages/home')

在vite里你要补全为

import('./pages/home/index.tsx')

当然,你的项目文件名后缀是js,就改成js。不能向webpack里是目录然后帮我们自动找底下的index.tsx。

原因也很简单,vite主要遵守的是浏览器的esma规范,webpack是遵守的node的commonjs规范,不一样。毕竟浏览器不存在说使用node_modules一说。肯定是代码全打包才能正常启动应用。

proxy配置,rewrite配置名称不一致

为了防止跨域,我们使用代理,在webpack里,代理也是挂载在devServer的配置上,vite也是,但是当时被坑了的是如下的配置:

'/user_api': {
              target: 'http://10.23.4.247:30413',
              pathRewrite: { '/user_api': '/api' },
              changeOrigin: true,
            },

上面的意思是请求的url地址如果包含/user_api字符串,就把它替换为/api字符串。

但是在vite里不生效,需要改为

'/user_api': {
        target: 'http://10.23.4.247:30413',
        rewrite: (path) => path.replace(/\/user_api/, '/api'),
        changeOrigin: true,
      },

webpack叫pathRewrite,vite叫rewrite,而且接收的是函数。

环境变量不支持

在webpack里,我的代码可以使用process.env,例如判断当前环境

const isTest = process.env.NODE_ENV === 'test'

webpack是如何办到的呢,帮我们替换 process.env, 我们使用了DefinePlugin来实现

  plugins: [
    new webpack.DefinePlugin({
      'process.env': JSON.stringify(process.env),
    }),
  ],

在vite里如何实现呢,更简单了,在vite.config.ts里,增加define属性即可

define: {
    'process.env': process.env,
  },

less不支持@import ‘~’

这个波浪号是啥意思呢,例如

@import "~@/css/mixin-classes";

且在webpack配置中添加了alias

resolve:{
    extensions:['.js','.json','.web.js','.less'],
    modules:['node_modules'],
    alias:{
        '@':path.resolve(__dirname,'../src')
    }
}

那么@也就代表了在webpack中定义的别名路径。

在vite中我们需要这么处理(针对less)

 css: {
    preprocessorOptions: {
      less: {
        javascriptEnabled: true,
      },
    },
  },
  resolve: {
    alias: [
      {
        find: '@',
        replacement: path.resolve(__dirname, './src'),
      },
      { find: /^~@/, replacement: './src/' },
    ],
  },

首先路径别名,要跟webpack一致,然后重点啊,css开启javascriptEnabled是啥意思呢,查询官网,翻译如下:

Enables evaluation of JavaScript inline in .less files. This created a security problem for some developers who didn’t expect user input for style sheets to have executable code.

启用 .less 文件中内联 JavaScript 的值。 这给一些开发人员带来了安全问题,他们不希望样式表的用户输入具有可执行代码。

我们举个例子,less可以使用javascript编写函数,这是一个很重要的技巧,less可以像scss一样便编写mixin。

.remMixin() {
  @functions: ~`(function() {
    var clientWidth = '375px';
    function convert(size) {
      return typeof size === 'string' ? 
        +size.replace('px', '') : size;
    }
    this.rem = function(size) {
      return convert(size) / convert(clientWidth) * 10 + 'rem';
    }
  })()`;
  }
 .remMixin();

因为写了convert函数,可以传数值或字符串都行):

 .el-function {
   width: ~`rem("300px")`;
   height: ~`rem(150)`;
   background: blue;
 }

根目录需要有一个index.html

还需要注意,你需要在根目录放上一个index.html(这个webpack的dev server就比vite方便了),案例如下

<!DOCTYPE html>
<html lang="en">

<head>
  <meta charset="UTF-8" />
  <meta name="viewport" content="width=device-width, initial-scale=1.0" />
  <meta http-equiv="X-UA-Compatible" content="ie=edge" />

  <title>AI一体化平台</title>
</head>

<body>
  <div id="root"></div>
  <script type="module" src="./src/index.tsx"></script>
</body>

</html>

完整的vite.config.js或者ts

import { defineConfig } from 'vite';
import react from '@vitejs/plugin-react';
import path from 'path';

export default defineConfig({
  css: {
    preprocessorOptions: {
      less: {
        javascriptEnabled: true,
      },
    },
  },
  resolve: {
    alias: [
      {
        find: '@',
        replacement: path.resolve(__dirname, './src'),
      },
      { find: /^~@/, replacement: './src/' },
    ],
  },
  server: {
    host: '0.0.0.0',
    port: 3000,
    open: true,
    proxy: {
      '/user_api': {
        target: 'http://10.23.24.247:3000',
        rewrite: (path) => path.replace(/\/user_api/, '/api'),
        changeOrigin: true,
      },
    },
  },
  plugins: [react()],
  define: {
    'process.env': process.env,
  },
});

© 版权声明
THE END
喜欢就支持一下吧
点赞6 分享
评论 抢沙发
头像
欢迎您留下宝贵的见解!
提交
头像

昵称

取消
昵称表情代码图片

    暂无评论内容