112 lines
2.8 KiB
TypeScript
112 lines
2.8 KiB
TypeScript
import { defineConfig } from 'vite'
|
||
import path from 'path'
|
||
import vue from '@vitejs/plugin-vue'
|
||
import vueJsx from '@vitejs/plugin-vue-jsx'
|
||
import AutoImport from 'unplugin-auto-import/vite'
|
||
import Components from 'unplugin-vue-components/vite'
|
||
import { ElementPlusResolver, VantResolver } from 'unplugin-vue-components/resolvers'
|
||
|
||
/** 与 xuexiaole-web 一致:构建/开发时将绝大部分 px 转为 vw(设计稿宽 1920) */
|
||
const pxToViewport = (options = {}) => {
|
||
const defaultOptions = {
|
||
unitToConvert: 'px',
|
||
viewportWidth: 1920,
|
||
viewportHeight: 1200,
|
||
unitPrecision: 2,
|
||
propList: ['*'],
|
||
viewportUnit: 'vw',
|
||
fontViewportUnit: 'vw',
|
||
selectorBlackList: ['.px-w'],
|
||
minPixelValue: 1,
|
||
mediaQuery: true,
|
||
replace: true,
|
||
landscape: false,
|
||
landscapeUnit: 'vw',
|
||
landscapeWidth: 1920,
|
||
}
|
||
|
||
const opts = { ...defaultOptions, ...options }
|
||
|
||
return {
|
||
postcssPlugin: 'postcss-px-to-viewport',
|
||
Declaration(decl: { value: string }) {
|
||
if (!decl.value.includes('px')) return
|
||
|
||
const pxRegex = /(\d*\.?\d+)px/g
|
||
decl.value = decl.value.replace(pxRegex, (match, group) => {
|
||
const pixels = parseFloat(group)
|
||
if (pixels <= opts.minPixelValue) return match
|
||
|
||
const vw = ((pixels / opts.viewportWidth) * 100).toFixed(opts.unitPrecision)
|
||
return `${vw}${opts.viewportUnit}`
|
||
})
|
||
},
|
||
}
|
||
}
|
||
pxToViewport.postcss = true
|
||
|
||
const dir = (url: string): string => path.resolve(__dirname, url)
|
||
|
||
export default defineConfig({
|
||
resolve: {
|
||
alias: {
|
||
'@': dir('src'),
|
||
'@c': dir('src/components'),
|
||
'@p': dir('src/plugins'),
|
||
},
|
||
},
|
||
plugins: [
|
||
vue(),
|
||
vueJsx(),
|
||
AutoImport({
|
||
imports: ['vue', 'vue-router', 'pinia'],
|
||
resolvers: [ElementPlusResolver(), VantResolver()],
|
||
eslintrc: {
|
||
enabled: true,
|
||
filepath: '.auto-import.json',
|
||
globalsPropValue: true,
|
||
},
|
||
dirs: ['src/stores'],
|
||
dts: dir('.auto-import.d.ts'),
|
||
}),
|
||
Components({
|
||
dirs: ['src/components'],
|
||
extensions: ['vue', 'tsx'],
|
||
resolvers: [ElementPlusResolver(), VantResolver()],
|
||
dts: dir('.components.d.ts'),
|
||
}),
|
||
],
|
||
css: {
|
||
preprocessorOptions: {
|
||
scss: {
|
||
additionalData: `
|
||
@use "@/styles/variate.scss" as *;
|
||
`,
|
||
api: 'modern',
|
||
silenceDeprecations: ['legacy-js-api'],
|
||
},
|
||
},
|
||
postcss: {
|
||
plugins: [
|
||
pxToViewport({
|
||
viewportWidth: 1920,
|
||
viewportHeight: 1200,
|
||
unitPrecision: 2,
|
||
selectorBlackList: ['.px-w'],
|
||
}),
|
||
],
|
||
},
|
||
},
|
||
server: {
|
||
port: 5173,
|
||
host: '0.0.0.0',
|
||
open: true,
|
||
proxy: {
|
||
'/api': {
|
||
target: 'http://127.0.0.1:8080',
|
||
changeOrigin: true,
|
||
},
|
||
},
|
||
},
|
||
})
|