caroundsky / QA

0 stars 0 forks source link

vue2 + TS(vue-class-component) 转 vite5 #18

Open caroundsky opened 8 months ago

caroundsky commented 8 months ago

Step1:改造 package.json

vueCli 相关的依赖可以删除:

# devDependencies
-"@vue/cli-plugin-babel": "~4.5.12", 
-"@vue/cli-plugin-eslint": "~4.5.12", 
-"@vue/cli-plugin-typescript": "~4.5.12", 
-"@vue/cli-plugin-unit-jest": "~4.5.12",
-"@vue/cli-service": "~4.5.12"

less等编译loader依赖也可删除,因为vite已经自带了,相应的,新增postcss和autoprefixer:

# devDependencies
-"less-loader": "^4.1.0",
+"postcss": "^8.4.32",
+"autoprefixer": "^10.4.16",

添加vite相关依赖,已经对vue2的相关依赖做处理:

# dependencies
-"vue": "^2.6.12",
+"vue": "^2.7.16",
-"core-js": "^3.6.5",
+"@vitejs/plugin-vue2-jsx": "^1.1.1",

# devDependencies
-"vue-template-compiler": "^2.6.12",
+"vite": "^4.4.6",
+"@vitejs/plugin-vue2": "^2.3.1",

对eslint依赖进行升级,并修改.eslintrc.js配置:

yarn add eslint@8 eslint-plugin-vue@8

# .eslintrc.js
// remove
parserOptions: {
    parser: "babel-eslint",
}

// add
env: {
    node: true,
    es2022: true, // 👈 add this
}

修改运行指令:

-"serve:dev": "vue-cli-service serve --open --mode serve-dev",
+"serve:dev": "vite",
-"build:dev": "vue-cli-service build --mode build-dev",
+"build:dev": "vite build",
caroundsky commented 8 months ago

Step2:添加 vite.config.js && 改造入口文件

根目录添加 vite.config.ts 文件:

import { defineConfig } from 'vite'
import vue from '@vitejs/plugin-vue2'
import vueJsx from '@vitejs/plugin-vue2-jsx'
import path from 'path'

export default defineConfig({
  plugins: [
    vue(),
    vueJsx(),
  ],

  resolve: {
    alias: {
      '@': '/src',
    },
  }
})

改造入口文件,删将public内的index.html移入根目录下,并修改:

# 去除带有变量名的字符串
-<title><%= htmlWebpackPlugin.options.title %></title> 
-<strong>We're sorry but <%= htmlWebpackPlugin.options.title %> doesn't work properly without JavaScript enabled. Please enable it to continue.</strong>
-<link rel="icon" href="<%= BASE_URL %>favicon.ico">
+<link rel="icon" href="/favicon.ico">

# 添加入口文件
+<script type="module" src="/src/main.ts"></script>
caroundsky commented 8 months ago

Step3:运行解决相关报错

1、不识别 less 定义的变量

image

// vite.config.ts 新增
css: {
  preprocessorOptions: {
    less: {
      javascriptEnabled: true,
      additionalData: `@import "${path.resolve(
        __dirname,
        'src/styles/variables.less'
      )}";`,  // 注意这个分号
    },
  },
},

2、不识别 component-class 装饰器

image

yarn add -D @babel/plugin-proposal-decorators

# vite.config.ts
-vueJsx()
+vueJsx({ babelPlugins: [['@babel/plugin-proposal-decorators', { legacy: true }]] }

3、国际化js脚本内使用了require.context报错

image

4、vscode import.meta.glob 报不识别警告

新建env.d.ts文件声明,删除shims-vue.d.ts文件,同时,如有其它文件申明了相同的变量,去到对应文件进行删除或者调整即可

/// <reference types="vite/client" />

declare module '*.vue' {
  import type { DefineComponent } from 'vue'
  const component: DefineComponent<{}, {}, any>
  export default component
}

5、Uncaught ReferenceError: require is not defined

检索全局文件,将require方法替换为import

6、Please ensure that transform-class-properties is enabled and runs after the decorators transform

image

yarn add -D @babel/plugin-proposal-class-properties

// vite.config.ts
vueJsx({
  babelPlugins: [
    ['@babel/plugin-proposal-decorators', { legacy: true }],
    ['@babel/plugin-proposal-class-properties'], // add
  ],
}),

7、项目内使用了svg组件化svg-sprite-loadersvg-to-vue-component,转vite后报组件错误,使用vite-svg-loader平替

yarn add -D vite-svg-loader

// vite.config.ts
import svgLoader from 'vite-svg-loader'
plugins: [ svgLoader() ]

8、组件name值丢失,浏览器警告

image

// 手动加上name值
@Component({
  name: 'MainContent',
})
export default class MainContent extends Vue { ... }

9、后缀名为.ts的文件,如果文件内引入后缀为.vue的文件,提示没有改模块

image

解决方案: 定义 xx.d.ts 文件

declare module '*.vue' {
  import type { DefineComponent } from 'vue'
  const component: DefineComponent<{}, {}, any>
  export default component
}

虽然解决了报错问题,但是在vscode中依然无法通过ctrl+左键定位到相应文件,这是因为vue2对ts文件的支持性不够好导致的,可以通过安装vscode插件 TypeScript Vue Plugin (Volar) 解决

10、引入一些外部样式,如element组件库样式,vite运行时会报样式警告

企业微信截图_17059120675589

解决方案:

import { createLogger } from 'vite'

const logger = createLogger()
const loggerWarn = logger.warn
logger.warn = (msg, options) => {
  // 忽略空 CSS 文件的警告
  if (msg.includes('vite:css') && msg.includes(' display: contents')) return
  loggerWarn(msg, options)
}

export default defineConfig({
  ...
  customLogger: logger,
})

11、某些依赖包是非ES模块

// vite.config
optimizeDeps: {
  exclude: [xxx]
}

11、某些依赖包内使用了node的一些方法,比fs

安装插件vite-plugin-node-polyfills解决