- copyTinymceAssets 只拷运行时必需文件(核心 js/主题/模型/图标/oxide 皮肤 + 8 个在用插件) - closeBundle 先 rmSync 清空目标目录,防陈旧完整包残留混入 dist - deploy.ps1 清理阶段同步删除生产 tinymce 残留,保证部署一致性
132 lines
4.5 KiB
TypeScript
132 lines
4.5 KiB
TypeScript
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'
|
||
},
|
||
},
|
||
},
|
||
},
|
||
})
|