refactor: optimize global libs filenames for better cache hit rates (#7530)

#### What type of PR is this?

/area ui
/kind improvement
/milestone 2.21.x

#### What this PR does / why we need it:

Optimize the file suffixes of global dependencies by using content hashes instead of random strings. This ensures that when dependencies do not change, the output filenames remain the same after building, resulting in better cache utilization.

#### Does this PR introduce a user-facing change?

```release-note
优化 Console 的全局依赖文件名,以获得更好的缓存利用率。
```
pull/7531/head
Ryan Wang 2025-06-10 12:00:34 +08:00 committed by GitHub
parent 2332e09ead
commit 2469043248
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
3 changed files with 37 additions and 51 deletions

View File

@ -145,7 +145,6 @@
"prettier": "^2.8.8",
"prettier-plugin-organize-imports": "^4.1.0",
"prettier-plugin-tailwindcss": "^0.1.13",
"randomstring": "^1.2.3",
"rollup-plugin-gzip": "^3.1.0",
"sass-embedded": "^1.82.0",
"start-server-and-test": "^1.14.0",

View File

@ -330,9 +330,6 @@ importers:
prettier-plugin-tailwindcss:
specifier: ^0.1.13
version: 0.1.13(prettier@2.8.8)
randomstring:
specifier: ^1.2.3
version: 1.2.3
rollup-plugin-gzip:
specifier: ^3.1.0
version: 3.1.0(rollup@4.28.1)
@ -5202,10 +5199,6 @@ packages:
resolution: {integrity: sha512-HGyxoOTYUyCM6stUe6EJgnd4EoewAI7zMdfqO+kGjnlZmBDz/cR5pf8r/cR4Wq60sL/p0IkcjUEEPwS3GFrIyw==}
engines: {node: '>=8'}
array-uniq@1.0.2:
resolution: {integrity: sha512-GVYjmpL05al4dNlKJm53mKE4w9OOLiuVHWorsIA3YVz+Hu0hcn6PtE3Ydl0EqU7v+7ABC4mjjWsnLUxbpno+CA==}
engines: {node: '>=0.10.0'}
array.prototype.map@1.0.6:
resolution: {integrity: sha512-nK1psgF2cXqP3wSyCSq0Hc7zwNq3sfljQqaG27r/7a7ooNUnn5nGq6yYWyks9jMO5EoFQ0ax80hSg6oXSRNXaw==}
engines: {node: '>= 0.4'}
@ -8965,16 +8958,9 @@ packages:
ramda@0.29.0:
resolution: {integrity: sha512-BBea6L67bYLtdbOqfp8f58fPMqEwx0doL+pAi8TZyp2YWz8R9G8z9x75CZI8W+ftqhFHCpEX2cRnUUXK130iKA==}
randombytes@2.0.3:
resolution: {integrity: sha512-lDVjxQQFoCG1jcrP06LNo2lbWp4QTShEXnhActFBwYuHprllQV6VUpwreApsYqCgD+N1mHoqJ/BI/4eV4R2GYg==}
randombytes@2.1.0:
resolution: {integrity: sha512-vYl3iOX+4CKUWuxGi9Ukhie6fsqXqS9FE2Zaic4tNFD2N2QQaXOMFbuKK4QmDHC0JO6B1Zp41J0LpT0oR68amQ==}
randomstring@1.2.3:
resolution: {integrity: sha512-3dEFySepTzp2CvH6W/ASYGguPPveBuz5MpZ7MuoUkoVehmyNl9+F9c9GFVrz2QPbM9NXTIHGcmJDY/3j4677kQ==}
hasBin: true
range-parser@1.2.1:
resolution: {integrity: sha512-Hrgsx+orqoygnmhFbKaHE6c296J+HTAQXoxEF6gNupROmmGJRoyzfG3ccAveqCBrwr/2yxQ5BVd/GTl5agOwSg==}
engines: {node: '>= 0.6'}
@ -16297,24 +16283,24 @@ snapshots:
'@types/babel__core@7.20.5':
dependencies:
'@babel/parser': 7.26.3
'@babel/types': 7.26.3
'@babel/parser': 7.27.5
'@babel/types': 7.27.6
'@types/babel__generator': 7.6.7
'@types/babel__template': 7.4.4
'@types/babel__traverse': 7.20.4
'@types/babel__generator@7.6.7':
dependencies:
'@babel/types': 7.26.3
'@babel/types': 7.27.6
'@types/babel__template@7.4.4':
dependencies:
'@babel/parser': 7.26.3
'@babel/types': 7.26.3
'@babel/parser': 7.27.5
'@babel/types': 7.27.6
'@types/babel__traverse@7.20.4':
dependencies:
'@babel/types': 7.26.3
'@babel/types': 7.27.6
'@types/body-parser@1.19.5':
dependencies:
@ -17367,8 +17353,6 @@ snapshots:
array-union@2.1.0: {}
array-uniq@1.0.2: {}
array.prototype.map@1.0.6:
dependencies:
call-bind: 1.0.7
@ -20069,7 +20053,7 @@ snapshots:
jest-worker@26.6.2:
dependencies:
'@types/node': 20.14.2
'@types/node': 18.19.34
merge-stream: 2.0.0
supports-color: 7.2.0
@ -21613,17 +21597,10 @@ snapshots:
ramda@0.29.0: {}
randombytes@2.0.3: {}
randombytes@2.1.0:
dependencies:
safe-buffer: 5.2.1
randomstring@1.2.3:
dependencies:
array-uniq: 1.0.2
randombytes: 2.0.3
range-parser@1.2.1: {}
raw-body@2.5.1:

View File

@ -1,4 +1,6 @@
import randomstring from "randomstring";
import crypto from "node:crypto";
import fs from "node:fs";
import path from "node:path";
import type { HtmlTagDescriptor } from "vite";
import { viteExternalsPlugin as ViteExternals } from "vite-plugin-externals";
import { createHtmlPlugin as VitePluginHtml } from "vite-plugin-html";
@ -19,77 +21,80 @@ export const setupLibraryExternal = (
baseUrl: string,
entry: string
) => {
const staticSuffix = randomstring.generate({
length: 8,
charset: "hex",
});
const staticTargets: Target[] = [
{
src: `./node_modules/vue/dist/vue.global${
isProduction ? ".prod" : ""
}.js`,
dest: "assets/vue",
rename: `vue.global.${staticSuffix}.js`,
rename: `vue.[hash].js`,
},
{
src: `./node_modules/vue-router/dist/vue-router.global${
isProduction ? ".prod" : ""
}.js`,
dest: "assets/vue-router",
rename: `vue-router.global.${staticSuffix}.js`,
rename: `vue-router.[hash].js`,
},
{
src: "./node_modules/axios/dist/axios.min.js",
dest: "assets/axios",
rename: `axios.${staticSuffix}.js`,
rename: `axios.[hash].js`,
},
{
src: `./node_modules/vue-demi/lib/index.iife.js`,
dest: "assets/vue-demi",
rename: `vue-demi.${staticSuffix}.js`,
rename: `vue-demi.[hash].js`,
},
{
src: "./node_modules/@vueuse/shared/index.iife.min.js",
dest: "assets/vueuse",
rename: `vueuse.shared.iife.${staticSuffix}.js`,
rename: `vueuse.shared.[hash].js`,
},
{
src: "./node_modules/@vueuse/core/index.iife.min.js",
dest: "assets/vueuse",
rename: `vueuse.core.iife.${staticSuffix}.js`,
rename: `vueuse.core.[hash].js`,
},
{
src: "./node_modules/@vueuse/components/index.iife.min.js",
dest: "assets/vueuse",
rename: `vueuse.components.iife.${staticSuffix}.js`,
rename: `vueuse.components.[hash].js`,
},
{
src: "./node_modules/@vueuse/router/index.iife.min.js",
dest: "assets/vueuse",
rename: `vueuse.router.iife.${staticSuffix}.js`,
rename: `vueuse.router.[hash].js`,
},
{
src: "./node_modules/@halo-dev/components/dist/halo-components.iife.js",
dest: "assets/components",
rename: `halo-components.iife.${staticSuffix}.js`,
rename: `components.[hash].js`,
},
{
src: "./node_modules/@halo-dev/console-shared/dist/halo-console-shared.iife.js",
dest: "assets/console-shared",
rename: `halo-console-shared.iife.${staticSuffix}.js`,
rename: `console-shared.[hash].js`,
},
{
src: "./node_modules/@halo-dev/richtext-editor/dist/rich-text-editor.iife.js",
dest: "assets/richtext-editor",
rename: `halo-rich-text-editor.iife.${staticSuffix}.js`,
dest: "assets/editor",
rename: `editor.[hash].js`,
},
{
src: "./node_modules/@halo-dev/api-client/dist/halo-api-client.iife.js",
dest: "assets/api-client",
rename: `halo-api-client.iife.${staticSuffix}.js`,
rename: `api-client.[hash].js`,
},
];
].map((target) => {
return {
...target,
rename: `${target.rename.replace(
"[hash]",
computeLibraryHash(target.src)
)}`,
};
});
const injectTags = staticTargets
.map((target) => {
@ -132,3 +137,8 @@ export const setupLibraryExternal = (
}),
];
};
function computeLibraryHash(file: string) {
const content = fs.readFileSync(path.resolve(process.cwd(), file), "utf8");
return crypto.createHash("md5").update(content).digest("hex").substring(0, 8);
}