build(assets): 裁剪 tinymce 部署产物(40MB 整包 → 14 文件 1.19MB)

- copyTinymceAssets 只拷运行时必需文件(核心 js/主题/模型/图标/oxide 皮肤 + 8 个在用插件)
- closeBundle 先 rmSync 清空目标目录,防陈旧完整包残留混入 dist
- deploy.ps1 清理阶段同步删除生产 tinymce 残留,保证部署一致性
This commit is contained in:
TermiNexus committed 2026-08-13 18:14:24 +08:00
1 parent b80009c423
commit 4d49e549b5
2 files changed
+30 -5

No files matched your search

+6
View File
@@ -39,6 +39,12 @@ if (Test-Path $IndexHtml) {
Remove-Item -Force $IndexHtml Remove-Item -Force $IndexHtml
Write-Host " removed: $IndexHtml" Write-Host " removed: $IndexHtml"
} }
# tinymce 为构建产物(裁剪后的运行时文件),清理防旧完整包残留
$ProdTinymceDir = Join-Path $ProdRoot 'tinymce'
if (Test-Path $ProdTinymceDir) {
Remove-Item -Recurse -Force $ProdTinymceDir
Write-Host " removed: $ProdTinymceDir"
}
Write-Host '' Write-Host ''
# 2. Full build (vue-tsc type check + vite build) # 2. Full build (vue-tsc type check + vite build)
+24 -5
View File
@@ -1,6 +1,6 @@
import { defineConfig, type Plugin } from 'vite' import { defineConfig, type Plugin } from 'vite'
import { fileURLToPath, URL } from 'node:url' import { fileURLToPath, URL } from 'node:url'
import { cpSync } from 'node:fs' import { cpSync, rmSync } from 'node:fs'
import { resolve } from 'node:path' import { resolve } from 'node:path'
import vue from '@vitejs/plugin-vue' import vue from '@vitejs/plugin-vue'
import AutoImport from 'unplugin-auto-import/vite' import AutoImport from 'unplugin-auto-import/vite'
@@ -9,16 +9,35 @@ import { ElementPlusResolver } from 'unplugin-vue-components/resolvers'
const projectRoot = fileURLToPath(new URL('.', import.meta.url)) const projectRoot = fileURLToPath(new URL('.', import.meta.url))
/** 富文本编辑器自托管:构建完成后把 tinymce 整目录拷到 dist/tinymce, /** 富文本编辑器自托管:仅拷贝运行时必需文件到 dist/tinymce(裁剪整包 ~40MB → ~1MB)
* 运行时经 /tinymce/ 以 <script> 标签加载,规避打包器对 tinymce UMD 的处理问题 */ * 运行时经 /tinymce/ 以 <script> 标签加载 tinymce.min.js,规避打包器对 tinymce UMD 的处理问题。
* tinymce 6 运行时依赖:核心 js + silver 主题 + dom 模型 + 默认图标 + oxide 皮肤 + 用到的插件 */
function copyTinymceAssets(): Plugin { 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 { return {
name: 'copy-tinymce-assets', name: 'copy-tinymce-assets',
apply: 'build', apply: 'build',
closeBundle() { closeBundle() {
const src = resolve(projectRoot, 'node_modules/tinymce')
const dest = resolve(projectRoot, 'dist/tinymce') const dest = resolve(projectRoot, 'dist/tinymce')
cpSync(src, dest, { recursive: true, force: true }) // 先清空目标目录:防陈旧残留(完整包拷贝/历史产物)混入 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 })
}
}, },
} }
} }