338 lines
7.6 KiB
JavaScript
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://cdn.azizichat.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,
|
|
},
|
|
}
|
|
})
|