aslan-h5/vite.config.js
2026-04-21 16:42:29 +08:00

338 lines
7.6 KiB
JavaScript

import vue from '@vitejs/plugin-vue'
import Components from 'unplugin-vue-components/vite'
import { defineConfig } from 'vite'
import { fileURLToPath, URL } from 'node:url'
import { VantResolver } from 'unplugin-vue-components/resolvers'
const buildTimestamp = Date.now()
const PRODUCTION_LIKE_MODES = new Set(['production', 'production-atu'])
const STRIPPABLE_CONSOLE_METHODS = ['log', 'debug', 'info']
function isEscaped(code, index) {
let backslashCount = 0
let cursor = index - 1
while (cursor >= 0 && code[cursor] === '\\') {
backslashCount += 1
cursor -= 1
}
return backslashCount % 2 === 1
}
function findCallEnd(code, openParenIndex) {
let depth = 0
let quote = null
let templateExpressionDepth = 0
let inLineComment = false
let inBlockComment = false
for (let index = openParenIndex; index < code.length; index += 1) {
const current = code[index]
const next = code[index + 1]
if (inLineComment) {
if (current === '\n') {
inLineComment = false
}
continue
}
if (inBlockComment) {
if (current === '*' && next === '/') {
inBlockComment = false
index += 1
}
continue
}
if (quote) {
if (quote === '`') {
if (current === '$' && next === '{' && !isEscaped(code, index)) {
templateExpressionDepth += 1
index += 1
continue
}
if (current === '}' && templateExpressionDepth > 0 && !isEscaped(code, index)) {
templateExpressionDepth -= 1
continue
}
if (current === '`' && templateExpressionDepth === 0 && !isEscaped(code, index)) {
quote = null
}
continue
}
if (current === quote && !isEscaped(code, index)) {
quote = null
}
continue
}
if (current === '/' && next === '/') {
inLineComment = true
index += 1
continue
}
if (current === '/' && next === '*') {
inBlockComment = true
index += 1
continue
}
if (current === '"' || current === "'" || current === '`') {
quote = current
continue
}
if (current === '(') {
depth += 1
continue
}
if (current === ')') {
depth -= 1
if (depth === 0) {
let endIndex = index + 1
while (endIndex < code.length && /\s/.test(code[endIndex])) {
endIndex += 1
}
if (code[endIndex] === ';') {
endIndex += 1
}
return endIndex
}
}
}
return -1
}
function findTokenOutsideLiterals(code, token, fromIndex = 0) {
let quote = null
let templateExpressionDepth = 0
let inLineComment = false
let inBlockComment = false
for (let index = fromIndex; index < code.length; index += 1) {
const current = code[index]
const next = code[index + 1]
if (inLineComment) {
if (current === '\n') {
inLineComment = false
}
continue
}
if (inBlockComment) {
if (current === '*' && next === '/') {
inBlockComment = false
index += 1
}
continue
}
if (quote) {
if (quote === '`') {
if (current === '$' && next === '{' && !isEscaped(code, index)) {
templateExpressionDepth += 1
index += 1
continue
}
if (current === '}' && templateExpressionDepth > 0 && !isEscaped(code, index)) {
templateExpressionDepth -= 1
continue
}
if (current === '`' && templateExpressionDepth === 0 && !isEscaped(code, index)) {
quote = null
}
continue
}
if (current === quote && !isEscaped(code, index)) {
quote = null
}
continue
}
if (current === '/' && next === '/') {
inLineComment = true
index += 1
continue
}
if (current === '/' && next === '*') {
inBlockComment = true
index += 1
continue
}
if (current === '"' || current === "'" || current === '`') {
quote = current
continue
}
if (code.startsWith(token, index)) {
return index
}
}
return -1
}
function stripSelectedConsoleCalls(code) {
let output = code
STRIPPABLE_CONSOLE_METHODS.forEach((method) => {
let searchIndex = 0
const token = `console.${method}`
while (searchIndex < output.length) {
const startIndex = findTokenOutsideLiterals(output, token, searchIndex)
if (startIndex === -1) {
break
}
let cursor = startIndex + token.length
while (cursor < output.length && /\s/.test(output[cursor])) {
cursor += 1
}
if (output[cursor] !== '(') {
searchIndex = startIndex + token.length
continue
}
const endIndex = findCallEnd(output, cursor)
if (endIndex === -1) {
searchIndex = cursor + 1
continue
}
output = `${output.slice(0, startIndex)}void 0;${output.slice(endIndex)}`
searchIndex = startIndex + 'void 0;'.length
}
})
return output
}
function createBuildLogControlPlugin(stripDebugLogs) {
return {
name: 'likei-build-log-control',
apply: 'build',
enforce: 'post',
transform(code, id) {
if (!stripDebugLogs || id.includes('node_modules')) {
return null
}
if (!/\.(vue|js|ts|jsx|tsx|mjs|cjs)(\?|$)/.test(id)) {
return null
}
const transformedCode = stripSelectedConsoleCalls(code)
if (transformedCode === code) {
return null
}
return {
code: transformedCode,
map: null,
}
},
}
}
export default defineConfig(({ mode }) => {
const keepBuildLogs = process.env.LIKEI_KEEP_BUILD_LOGS === 'true'
const stripDebugLogs = PRODUCTION_LIKE_MODES.has(mode) && !keepBuildLogs
return {
plugins: [
vue(),
Components({
resolvers: [VantResolver()],
}),
createBuildLogControlPlugin(stripDebugLogs),
],
resolve: {
alias: {
'@': fileURLToPath(new URL('./src', import.meta.url)),
},
},
build: {
minify: 'esbuild',
sourcemap: false,
cssMinify: 'esbuild',
reportCompressedSize: false,
esbuild: {
drop: stripDebugLogs ? ['debugger'] : [],
charset: 'ascii',
legalComments: 'none',
minifyIdentifiers: true,
minifySyntax: true,
minifyWhitespace: true,
treeShaking: true,
},
rollupOptions: {
output: {
entryFileNames: `js/[hash]-${buildTimestamp}.js`,
chunkFileNames: `js/[hash]-${buildTimestamp}.js`,
assetFileNames: (assetInfo) => {
const info = assetInfo.name.split('.')
const ext = info[info.length - 1]
if (/\.(css)$/.test(assetInfo.name)) {
return `css/[hash]-${buildTimestamp}.[ext]`
}
return `assets/[hash]-${buildTimestamp}.[ext]`
},
},
},
},
server: {
host: '0.0.0.0',
port: 5173,
strictPort: true,
open: false,
cors: true,
proxy: {
'/oss': {
target: 'https://tkm-likei.oss-ap-southeast-1.aliyuncs.com',
changeOrigin: true,
secure: true,
rewrite: (path) => path.replace(/^\/oss/, ''),
configure: (proxy) => {
proxy.on('proxyRes', (proxyRes) => {
delete proxyRes.headers.etag
delete proxyRes.headers['last-modified']
delete proxyRes.headers['cache-control']
delete proxyRes.headers.expires
})
},
},
},
},
preview: {
host: '0.0.0.0',
port: 4173,
strictPort: true,
open: false,
},
}
})