Files

156 lines
5.1 KiB
JavaScript

import { viteLogo } from './src/core/config.js'
import fs from 'node:fs'
import * as path from 'path'
import { loadEnv } from 'vite'
import vuePlugin from '@vitejs/plugin-vue'
import vueDevTools from 'vite-plugin-vue-devtools'
import UnoCSS from '@unocss/vite'
const svgSpritePlugin = (roots) => ({
name: 'kra-svg-sprite',
transformIndexHtml(html) {
const symbols = []
const visit = (directory, modulePrefix = '') => {
if (!fs.existsSync(directory)) return
const entries = fs.readdirSync(directory, { withFileTypes: true })
.sort((a, b) => a.name.localeCompare(b.name))
for (const entry of entries) {
const filename = path.join(directory, entry.name)
if (entry.isDirectory()) {
visit(filename, modulePrefix || entry.name + '-')
continue
}
if (!entry.name.endsWith('.svg')) continue
const source = fs.readFileSync(filename, 'utf8')
const openingTag = source.match(/<svg\b([^>]*)>/i)
if (!openingTag) continue
const attrs = openingTag[1]
.replace(/\s(?:width|height)=(['"]).*?\1/gi, '')
.trim()
const body = source
.slice(openingTag[0].length)
.replace(/<\/svg>\s*$/i, '')
const iconName = entry.name.replace(/\.svg$/i, '')
symbols.push(`<symbol id="${modulePrefix}${iconName}"${attrs ? ` ${attrs}` : ''}>${body}</symbol>`)
}
}
for (const root of roots) {
const directory = path.resolve(root)
const moduleRoot = path.basename(path.dirname(directory)) === 'src' && path.basename(directory) === 'modules'
if (!moduleRoot) {
visit(directory)
continue
}
for (const entry of fs.readdirSync(directory, { withFileTypes: true })) {
if (entry.isDirectory()) visit(path.join(directory, entry.name), entry.name + '-')
}
}
const sprite = `<svg xmlns="http://www.w3.org/2000/svg" style="position:absolute;width:0;height:0">${symbols.join('')}</svg>`
return html.replace('<body>', `<body>\n${sprite}`)
}
})
const pathMapPlugin = () => ({
name: 'kra-vue-path-map',
buildStart() {
const roots = ['src/view', 'src/modules']
const result = {}
const walk = (directory) => {
if (!fs.existsSync(directory)) return
const entries = fs.readdirSync(directory, { withFileTypes: true })
.sort((a, b) => a.name < b.name ? -1 : a.name > b.name ? 1 : 0)
for (const entry of entries) {
const filename = path.join(directory, entry.name)
if (entry.isDirectory()) {
walk(filename)
} else if (filename.endsWith('.vue')) {
const source = fs.readFileSync(filename, 'utf8')
const match = source.match(/defineOptions\s*\(\s*{[\s\S]*?name:\s*['"]([^'"]+)['"]/)
if (match) {
const relativePath = path.relative('src', filename).split(path.sep).join('/')
result[`/src/${relativePath}`] = match[1]
}
}
}
}
roots.forEach(walk)
fs.writeFileSync('src/pathInfo.json', `${JSON.stringify(result, null, 2)}\n`)
}
})
// @see https://cn.vitejs.dev/config/
export default ({ mode }) => {
const env = loadEnv(mode, process.cwd())
viteLogo(env)
const alias = {
'@': path.resolve(import.meta.dirname, './src'),
vue$: 'vue/dist/vue.runtime.esm-bundler.js'
}
// 生产环境部署在 live.fuhua91.com/admin/ 下,由 .env.production 的 VITE_APP_BASE 控制
const base = env.VITE_APP_BASE || '/'
const root = './'
const outDir = 'dist'
const config = {
base: base, // 编译后js导入的资源路径
root: root, // index.html文件所在位置
publicDir: 'public', // 静态资源文件夹
resolve: {
alias
},
css: {
preprocessorOptions: {
scss: {
api: 'modern-compiler' // or "modern"
}
}
},
server: {
// 如果使用docker-compose开发模式,设置为false
open: true,
port: Number(env.VITE_CLI_PORT),
proxy: {
// 把key的路径代理到target位置
// detail: https://cli.vuejs.org/config/#devserver-proxy
[env.VITE_BASE_API]: {
// 需要代理的路径 例如 '/api'
target: `${env.VITE_BASE_PATH}:${env.VITE_SERVER_PORT}/`, // 代理到 目标路径
changeOrigin: true,
ws: true,
rewrite: (path) =>
path.replace(new RegExp('^' + env.VITE_BASE_API), '')
}
}
},
build: {
manifest: false, // 是否产出manifest.json
sourcemap: false, // 是否产出sourcemap.json
outDir: outDir, // 产出目录
target: 'es2015',
rolldownOptions: {
output: {
entryFileNames: 'assets/087AC4D233B64EB0[name].[hash].js',
chunkFileNames: 'assets/087AC4D233B64EB0[name].[hash].js',
assetFileNames: 'assets/087AC4D233B64EB0[name].[hash].[ext]'
}
}
},
plugins: [
env.VITE_POSITION === 'open' &&
vueDevTools({ launchEditor: env.VITE_EDITOR }),
vuePlugin(),
svgSpritePlugin(['./src/modules/', './src/assets/icons/']),
pathMapPlugin(),
UnoCSS()
]
}
return config
}