From 24690432480c45cf0f1a875cfda6ef1a3ba53d09 Mon Sep 17 00:00:00 2001 From: Ryan Wang Date: Tue, 10 Jun 2025 12:00:34 +0800 Subject: [PATCH] refactor: optimize global libs filenames for better cache hit rates (#7530) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit #### 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 的全局依赖文件名,以获得更好的缓存利用率。 ``` --- ui/package.json | 1 - ui/pnpm-lock.yaml | 37 +++++------------------- ui/src/vite/library-external.ts | 50 ++++++++++++++++++++------------- 3 files changed, 37 insertions(+), 51 deletions(-) diff --git a/ui/package.json b/ui/package.json index 1344c68b9..a8135b94e 100644 --- a/ui/package.json +++ b/ui/package.json @@ -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", diff --git a/ui/pnpm-lock.yaml b/ui/pnpm-lock.yaml index 68c963ab0..0555e3b80 100644 --- a/ui/pnpm-lock.yaml +++ b/ui/pnpm-lock.yaml @@ -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: diff --git a/ui/src/vite/library-external.ts b/ui/src/vite/library-external.ts index 85e2054e9..5257f86ce 100644 --- a/ui/src/vite/library-external.ts +++ b/ui/src/vite/library-external.ts @@ -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); +}