Vue CLI项目转Vite

5,311 阅读3分钟

背景

项目代码越来越多,使用Vue-cli每次启动项目或者热更新的时间都比较长,尤大开发的Vite早有耳闻并也有一点了解,所以准备将Vue-cli转到Vite,使用的工具是webpack-to-vite

1、屏蔽Vue.conf.js里面的配置

注释掉chainWebpackconfigureWebpack等配置,否则转换会报错。

2、require的写法转换

由于vite是不支持CommonJs的写法的(比如这边的require),原先可以这样写是Vue-cli帮我们做了转换。转为vite之后,虽然不做改动的话,开发环境不会报错,但是打包环境(npm run build之后npm run preview)会报错:require is not defined,这是因为开发环境使用了@originjs/vite-plugin-commonjs插件,但是这个插件未对打包结果做处理。

写法转换可以参考知乎或者CSDN

原先的写法:

function getSvgIcon(path, name) {
  return require(`../../public/icons/${path}/${name}.svg`)
}

改为:

function getSvgIcon(path, name) {
  return new URL(`/icons/${path}/${name}.svg`, import.meta.url).href
}

但是,这样改动,Vue-cli启动会报错。

3、代理

vite提供的功能更类似webpackvue-cli是包装webpack提供了检测是否本地文件的功能。 vite提供了类似bypass函数。

这边套用官网的server配置:

// vite.config.js
server: {
  proxy: {
    '/apidev': {
      target: 'http://10.136.96.79:19997',
      changeOrigin: true,
      rewrite: (path) => path.replace(/^\/apidev/, '')
    }
  }
}

// http.js
const isProduction = process.env.NODE_ENV !== 'development'
axios.defaults.baseURL = isProduction ? settings.backendUrl : `/apidev/${settings.backendUrl}`

上面的proxy中之所以用/apidev之后又删掉,是因为尝试了直接使用'/','/*'等写法均不生效(猜测可能是’/‘区分不了是静态文件还是请求),这种写法是参考的官网

4、国际化

原先国际化load语言的时候有require相关的写法:

// i18n.js
function loadLocaleMessages() {
  const locales = require.context('../locales', true, /[A-Za-z0-9-_,\s]+\.json$/i)
  const messages = {}
  locales.keys().forEach(key => {
    const matched = key.match(/([A-Za-z0-9-_]+)\./i)
    if (matched && matched.length > 1) {
      const locale = matched[1]
      messages[locale] = locales(key)
    }
  })
  return messages
}

// App.vue
loadLocaleMessages: function() {
    const locales = require.context('../../locales', true, /[A-Za-z0-9-_,\s]+\.json$/i)
    const messages = {}
    locales.keys().forEach(key => {
      const matched = key.match(/([A-Za-z0-9-_]+)\./i)
      if (matched && matched.length > 1) {
        const locale = matched[1]
        messages[locale] = locales(key)
      }
    })
    return messages
  }
}

改为:

// i18n.js
import zh from '@/locales/zh.json'
import en from '@/locales/en.json'

function loadLocaleMessages() {
  return {
    en,
    zh
  }
}

// App.vue
import zh from '@/locales/zh.json'
import en from '@/locales/en.json'

loadLocaleMessages: function() {
    return {
      en,
      zh
    }
}

【建议】import.meta.glob / new URL 回头试试

5、开发环境CSS乱了

原先的index.html中:

  <body class="xx">
    XXXX
  </body>

body中有class="xx",但是现在vite生成的index.html默认没有带上这个class导致我们自己写的很多样式没有生效。只需要在vite生成的index.html手动加上class="xx"即可。

注意:vite.config.js配置build的多入口

6、打包

可以正常打包,但是有warning信息:

rendering chunks (80)...warnings when minifying css:
 > <stdin>:20:24: warning: Unexpected ">"
    20 │ .main-content .dialog > > > .node-fill .v-text-field[data-v-23fae236] {
       ╵                         ^


 > <stdin>:25:18: warning: Unexpected ">"
    25 │ .dialog .upload > > > .v-file-input .v-text-field__details[data-v-e0...
       ╵                   ^


 > <stdin>:31:18: warning: Unexpected ">"
    31 │ .dialog .upload > > > .v-text-field > .v-input__control > .v-input__...
       ╵                   ^


 > <stdin>:34:18: warning: Unexpected ">"
    34 │ .dialog .upload > > > .update-file[data-v-e0246af8] {

学习下vue中style scope深度访问新方式(::v-deep)

这个需要改一下深度作用选择器的写法:

image.png

>>> 改为 ::v-deep

7、build的时候warning: "@charset" must be the first rule in the file

参见issue,忽视这个warning

8、首屏加载优化

开发环境虽然npm run serve很快,但是页面首屏加载时间很长【请求400+】。看了下是VuetifystaticInfo相关请求过多。

建议:优化

优化1. 参见官网,修改一下vuetify的引入方式

// 修改前
import Vue from 'vue'
import Vuetify from 'vuetify/lib'

Vue.use(Vuetify)

export default new Vuetify({
  icons: {
    iconfont: 'md'
  }
})

// 修改后,并且删除步骤10引入的vite-plugin-components以及vite.config.js中相关的配置
import Vue from 'vue'
import Vuetify from 'vuetify'
import 'vuetify/dist/vuetify.min.css'

Vue.use(Vuetify)

export default new Vuetify({
  icons: {
    iconfont: 'md'
  }
})

页面首次加载的请求减少100+,页面加载时间(首次)优化到5.84s,缩短了10s+

优化2. 开启http2试试,因为http 1.x 同时只能6-8个请求, http2没这个限制。否则存在优先级高的请求、并发TCP连接数超过6个(本实例是这个原因)、缓存读写异常这三个原因会导致请求stalled时间长。

效果比对

代码量:src目录约9w

Vue-CliVite
启动时间39s805ms
页面加载时间(首次)1.68s17.24s(5.8s)
组件热更新时间130ms【+编译时间】82ms

webpack 热更新时间:构建时间 + 请求时间,vite 则只有请求时间