Files
GERP/vite.config.ts
T
TermiNexus 4d49e549b5 build(assets): 裁剪 tinymce 部署产物(40MB 整包 → 14 文件 1.19MB)
- copyTinymceAssets 只拷运行时必需文件(核心 js/主题/模型/图标/oxide 皮肤 + 8 个在用插件)
- closeBundle 先 rmSync 清空目标目录,防陈旧完整包残留混入 dist
- deploy.ps1 清理阶段同步删除生产 tinymce 残留,保证部署一致性
2026-08-13 18:14:24 +08:00

132 lines
4.5 KiB
TypeScript
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
import { defineConfig, type Plugin } from 'vite'
import { fileURLToPath, URL } from 'node:url'
import { cpSync, rmSync } from 'node:fs'
import { resolve } from 'node:path'
import vue from '@vitejs/plugin-vue'
import AutoImport from 'unplugin-auto-import/vite'
import Components from 'unplugin-vue-components/vite'
import { ElementPlusResolver } from 'unplugin-vue-components/resolvers'
const projectRoot = fileURLToPath(new URL('.', import.meta.url))
/** 富文本编辑器自托管:仅拷贝运行时必需文件到 dist/tinymce(裁剪整包 ~40MB → ~1MB)
* 运行时经 /tinymce/ 以 <script> 标签加载 tinymce.min.js,规避打包器对 tinymce UMD 的处理问题。
* tinymce 6 运行时依赖:核心 js + silver 主题 + dom 模型 + 默认图标 + oxide 皮肤 + 用到的插件 */
function copyTinymceAssets(): Plugin {
/** RichTextEditor 实际使用的插件(与 src/components/RichTextEditor.vue plugins 配置保持一致) */
const REQUIRED_PLUGINS = ['advlist', 'lists', 'link', 'image', 'table', 'code', 'wordcount', 'autoresize']
/** 核心文件(保持 /tinymce/ 相对路径,base_url/skin_url 据此解析) */
const CORE_FILES = [
'tinymce.min.js',
'themes/silver/theme.min.js',
'models/dom/model.min.js',
'icons/default/icons.min.js',
'skins/ui/oxide/skin.min.css',
'skins/content/default/content.min.css',
]
return {
name: 'copy-tinymce-assets',
apply: 'build',
closeBundle() {
const dest = resolve(projectRoot, 'dist/tinymce')
// 先清空目标目录:防陈旧残留(完整包拷贝/历史产物)混入 dist
rmSync(dest, { recursive: true, force: true })
const src = resolve(projectRoot, 'node_modules/tinymce')
for (const f of CORE_FILES) {
cpSync(resolve(src, f), resolve(dest, f), { force: true })
}
for (const p of REQUIRED_PLUGINS) {
cpSync(resolve(src, `plugins/${p}/plugin.min.js`), resolve(dest, `plugins/${p}/plugin.min.js`), { force: true })
}
},
}
}
// https://vite.dev/config/
export default defineConfig({
plugins: [
vue(),
// 自动导入 Vue / Vue Router / Pinia 的 API 与 Element Plus 组件
AutoImport({
imports: ['vue', 'vue-router', 'pinia'],
resolvers: [ElementPlusResolver()],
dts: 'src/types/auto-imports.d.ts',
eslintrc: { enabled: false },
}),
Components({
resolvers: [ElementPlusResolver()],
dts: 'src/types/components.d.ts',
dirs: ['src/components'],
}),
copyTinymceAssets(),
],
resolve: {
alias: {
'@': fileURLToPath(new URL('./src', import.meta.url)),
},
},
server: {
host: '0.0.0.0',
port: 5173,
// 开发期把 API 请求代理到 Django 后端,Cookie 认证跨域自动处理
proxy: {
'/api': {
target: 'http://127.0.0.1:8000',
changeOrigin: true,
},
'/API': {
target: 'http://127.0.0.1:8000',
changeOrigin: true,
},
'/Auth': {
target: 'http://127.0.0.1:8000',
changeOrigin: true,
},
'/Query': {
target: 'http://127.0.0.1:8000',
changeOrigin: true,
},
'/Modify': {
target: 'http://127.0.0.1:8000',
changeOrigin: true,
},
'/static': {
target: 'http://127.0.0.1:8000',
changeOrigin: true,
},
'/media': {
target: 'http://127.0.0.1:8000',
changeOrigin: true,
},
},
},
build: {
outDir: 'dist',
sourcemap: false,
chunkSizeWarningLimit: 2000,
// 合并全部 CSS 为单个文件:消灭按需组件产生的零碎 .css 与 css-*.js(可省约 90 个请求)
cssCodeSplit: false,
rollupOptions: {
output: {
// 归并 node_modules 公共依赖,消灭 0.1-10kB 的细碎 chunk(lodash 工具 / element-plus 小组件等)
manualChunks(id: string) {
if (!id.includes('node_modules')) return undefined
if (id.includes('element-plus') || id.includes('@element-plus')) return 'element-plus'
if (id.includes('vxe-table')) return 'vxe-table'
if (id.includes('lodash') || id.includes('xe-utils')) return 'utils'
if (
id.includes('/node_modules/vue') ||
id.includes('/node_modules/vue-router') ||
id.includes('/node_modules/pinia') ||
id.includes('/node_modules/@vue') ||
id.includes('/node_modules/@vueuse')
) {
return 'vue-vendor'
}
return 'vendor'
},
},
},
},
})