-
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