Vue Cli4 升级/迁移到 Vite3实践/踩坑/指北

516 阅读2分钟

vuecli4迁移到vite3已知修改点:

  1. vuejs/create-vue的npm init vue@2, 新建一个vite+vue2的空模板,拷贝原项目文件到空模板里面
    
  2. vite把根目录作为服务,所以默认以根目录的index.html作为入口,html自己去引用入口main.js文件
    
  3. vite配置sass添加全局自动注入公共引用语句
    
  4. js文件里写了jsx 那扩展名就要改为jsx
    
  5. proccess.env改成import.env
    
  6. require.context("./",true/*递归*/,/\.vue$/) 改成 import.meta.glob("./*.vue", {eager:true})
    
  7. await import动态导入解决循环依赖报错
    
  8. 删除未声明的引入 
    
  9. 批量去除文件后缀(但两个文件重名可能导错)
    

问题:

  1. 在入口文件在window上挂载变量无效,因为没有被执行到???//只是因为报错才没继续执行下去
    
  2. vue的render中不能写jsx语法?//<script lang='jsx'>即可       
    
  3. 老系统是如何支持js写jsx?是如何支持装饰器语法的?//vuecli的@vue/babel-preset-app预设用了@babel/plugin-syntax-jsx支持的
    
  4. 导入/node_modules/element-ui跟element-ui有什么区别?//前者不被vite转译了,报错require is not defined //解决:改用后者,或通过vite配置将出问题的包,包含到预构建/预捆绑里面 
    
  5. element-ui的packages/checkbox/index.js里的import语句加个.vue才不会报错?,/好像后来去掉也行,原因未知/
    
  6. 子应用 scss 怎么 @import /public 下的文件不报错? //root在哪拿个目录就作为文件服务器,所以没法做到
    

vite.config.js

import { fileURLToPath, URL } from 'node:url';
import { resolve } from 'path';
import { defineConfig, loadEnv, searchForWorkspaceRoot } from 'vite';
import legacy from '@vitejs/plugin-legacy';
import vue2 from '@vitejs/plugin-vue2';
import vueJsx from '@vitejs/plugin-vue2-jsx';

export default ({ mode }) => {

    const env = loadEnv(mode, process.cwd());
    const wsRoot = searchForWorkspaceRoot(process.cwd());

    return defineConfig({
        root: 'src/subsystem/dcom',
        esbuild: { supported: { 
          // fix: 生产时 ERROR: Top-level await is not available in the configured target environment
          'top-level-await': true } },
        build: {
            rollupOptions: {
              // 只关乎生产时
                input: {
                    platform: resolve(__dirname, 'index.html'),
                    tb: resolve(__dirname, 'src/subsystem/tb/index.html'),
                    dcom: resolve(__dirname, 'src/subsystem/dcom/index.html'),
                },
            },
        },
        css: {
            preprocessorOptions: {
                scss: {
                  // 一次配置,全局使用,因为这个scss每个文件都要引入
                    additionalData:
                        '@import "@/frameworks/assets/css/main.scss";',
                },
            },
        },
        plugins: [
            vue2(),
            vueJsx(),
            // 生产时,为老浏览器提供支持
            legacy({
                targets: ['ie >= 11'],
                // 非ES语法用到的所需Polyfill
                additionalLegacyPolyfills: ['regenerator-runtime/runtime'],
            }),
        ],
        resolve: {
            extensions: ['.js', '.vue', '.json', '.scss', '.jsx'],
            alias: {
                '@': fileURLToPath(new URL('./src', import.meta.url)),
                '@common': resolve(__dirname, './src/common'),
                '@frameworks': resolve(__dirname, './src/frameworks'),
                '@modules': resolve(__dirname, './src/modules'),
                '@subsystem': resolve(__dirname, './src/subsystem'),
            },
        },
        define: { 'process.env': { ...env } },
        server: {
            // 解决某些资源403
            fs: { allow: [wsRoot] },
            proxy: {
                ['^/api']: {
                    target: 'http://192.168.79.196',
                    changeOrigin: true,
                    ws: true,
                    rewrite: (path) => path.replace(/^\/api /, ''),
                },
            },
        },
    });
};