vue2+webpack=>vue2+vite

242 阅读1分钟
  1. vite与webpack差别

遇到的问题:

1.svg打通:

由于升级vite,const svgFiles = require.context('./svg', true, /\.svg$/)无法进行导入svg文件。因此要对svg文件夹进行额外导入。

// vite.config.js 
import { defineConfig } from 'vite'import { createVuePlugin } from 'vite-plugin-vue2'import vitePluginSvgIcons from 'vite-plugin-svg-icons';import path from 'path';import { svgBuilder } from './static/plugins/svgBuilder'// https://vitejs.dev/config/// eslint-disable-next-lineexport default defineConfig(({command, mode})=>({  plugins: [createVuePlugin({    jsx: true, // jsx语法兼容处理}),svgBuilder('src/icons/svg/')],  resolve: {    alias: {      '@': path.resolve(__dirname, 'src'),    },    extensions:['.vue','.mjs', '.js', '.ts', '.jsx', '.tsx', '.json']  },  server: {    host: 'localhost',    port: 8001  },  // plugins: [y('./src/icons/svg/')], // 这里已经将src/icons/svg/下的svg全部导入,无需再单独导入  build: {    sourcemap: command === 'serve',    terserOptions: {      compress: {        drop_console: true,        drop_debugger: true      }    }  }}))

//svgBuilder.js
import { readFileSync, readdirSync } from 'fs'// id 前缀let idPerfix = ''// 识别svg标签的属性const svgTitle = /<svg([^>+].*?)>/// 有一些svg文件的属性会定义height和width,要把它清除掉const clearHeightWidth = /(width|height)="([^>+].*?)"/g// 没有viewBox的话就利用height和width来新建一个viewBoxconst hasViewBox = /(viewBox="[^>+].*?")/g// 清除换行符const clearReturn = /(\r)|(\n)/g/** * @param dir 路径*/function findSvgFile(dir){  const svgRes = []  const dirents = readdirSync(dir, {    withFileTypes: true  })  for (const dirent of dirents) {    const path = dir + dirent.name    if (dirent.isDirectory()) {      svgRes.push(...findSvgFile(path + '/'))    } else {      const svg = readFileSync(path)        .toString()        .replace(clearReturn, '')        .replace(svgTitle, ($1, $2) => {          let width = 0          let height = 0          let content = $2.replace(            clearHeightWidth,            (s1, s2, s3) => {              s3 = s3.replace('px', '')              if (s2 === 'width') {                width = s3              } else if (s2 === 'height') {                height = s3              }              return ''            }          )          if (!hasViewBox.test($2)) {            content += `viewBox="0 0 ${width} ${height}"`          }          return `<symbol id="${dirent.name.replace(            '.svg',            ''          )}" ${content}>`        })        .replace('</svg>', '</symbol>')      svgRes.push(svg)    }  }  return svgRes}export function svgBuilder(path, perfix = ''){  if (path === '') return  idPerfix = perfix  const res = findSvgFile(path) //引用上面的  return {    name: 'svg-transform',    transformIndexHtml(html) {      return html.replace(        '<body>',        `          <body>            <svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" style="position: absolute; width: 0; height: 0">              ${res.join('')}            </svg>        `      )    }  }}

<template>  <svg    class="icon-svg"    :width="width"    :height="height"    aria-hidden="true">    <use :xlink:href="getName"></use>  </svg></template><script>  export default {    name: 'icon-svg',    props: {      name: {        type: String,        required: true      },      className: {        type: String      },      width: {        type: String      },      height: {        type: String      }    },    computed: {      getName () {        return `#icon-${this.name}`      },      getClassName () {        return [          'icon-svg',          `icon-svg__${this.name}`,          this.className && /\S/.test(this.className) ? `${this.className}` : ''        ]      }    }  }</script><style>  .icon-svg {    width: 1em;    height: 1em;    fill: currentColor;    overflow: hidden;  }</style>

3.动态加载router不共通

function fnAddDynamicMenuRoutes (menuList = [], routes = []) {  var temp = []  for (var i = 0; i < menuList.length; i++) {    if (menuList[i].list && menuList[i].list.length >= 1) {      temp = temp.concat(menuList[i].list)    } else if (menuList[i].menuPath && /\S/.test(menuList[i].menuPath)) {      menuList[i].menuPath = menuList[i].menuPath.replace(/^\//, '')      var route = {        path: menuList[i].menuPath.replace('/', '-'),        component: null,        name: menuList[i].menuName.replace('/', '-'),        meta: {          menuId: menuList[i].seqId,          title: menuList[i].menuName,          isDynamic: true,          isTab: true,          iframeUrl: ''        }      }      // url以http[s]://开头, 通过iframe展示      if (isURL(menuList[i].menuPath)) {        route['path'] = `i-${menuList[i].seqId}`        route['name'] = `i-${menuList[i].seqId}`        route['meta']['iframeUrl'] = menuList[i].menuPath      } else {        try {          route['component'] = _import(`modules/${menuList[i].menuPath}`) || null        } catch (e) {}      }      routes.push(route)    }  }  if (temp.length >= 1) {    fnAddDynamicMenuRoutes(temp, routes)  } else {    mainRoutes.name = 'main-dynamic'    mainRoutes.children = routes    router.addRoutes([      mainRoutes,      { path: '*', redirect: { name: '404' } }    ])    sessionStorage.setItem('dynamicMenuRoutes', JSON.stringify(mainRoutes.children || '[]'))  }}

const modules = import.meta.glob('../views/**/*.vue')              Object.keys(modules).forEach(key => {   let str = menuList[i].menuPath   const nameMatch = key.match(str)       if(!nameMatch) return       route['component'] = modules[key] })

4./deep/  = > ::v-deep