From de4540a911fb7ebc7b4d92f35b6214edb0b8a37a Mon Sep 17 00:00:00 2001 From: Anthony Fu Date: Fri, 19 Nov 2021 02:31:43 +0800 Subject: [PATCH] fix(vite): css generate hash should changes, close #110 --- packages/vite/src/modes/global/build.ts | 32 ++++++++++++++++++++++--- 1 file changed, 29 insertions(+), 3 deletions(-) diff --git a/packages/vite/src/modes/global/build.ts b/packages/vite/src/modes/global/build.ts index bb71efd80d..c84ef82346 100644 --- a/packages/vite/src/modes/global/build.ts +++ b/packages/vite/src/modes/global/build.ts @@ -1,6 +1,6 @@ import type { Plugin } from 'vite' import { createFilter } from '@rollup/pluginutils' -import { getPath } from '../../utils' +import { getHash, getPath } from '../../utils' import { UnocssPluginContext } from '../../context' import { defaultExclude, defaultInclude } from '../../../../plugins-common/defaults' import { LAYER_MARK_ALL, getLayerPlaceholder, LAYER_PLACEHOLDER_RE, resolveId } from '../../../../plugins-common/layers' @@ -51,29 +51,55 @@ export function GlobalModeBuildPlugin({ uno, config, scan, tokens }: UnocssPlugi enforce: 'post', async generateBundle(options, bundle) { const files = Object.keys(bundle) + const cssFiles = files .filter(i => i.endsWith('.css')) - if (!files.length) + if (!cssFiles.length) return await Promise.all(tasks) const result = await uno.generate(tokens, { layerComments: false }) let replaced = false - for (const file of files) { + const cssReplacedMap = new Map() + for (const file of cssFiles) { const chunk = bundle[file] if (chunk.type === 'asset' && typeof chunk.source === 'string') { + let currentReplaced = false chunk.source = chunk.source.replace(LAYER_PLACEHOLDER_RE, (_, __, layer) => { + currentReplaced = true replaced = true return layer === LAYER_MARK_ALL ? result.getLayers(undefined, Array.from(entries.values())) : result.getLayer(layer) || '' }) + // recalculate hash + if (currentReplaced) { + const newName = chunk.fileName.replace(/\.(\w+)\.css$/, `.${getHash(chunk.source)}.css`) + cssReplacedMap.set(chunk.fileName, newName) + chunk.fileName = newName + } } } if (!replaced) this.error(new Error('[unocss] does not found CSS placeholder in the generated chunks,\nthis is likely an internal bug of unocss vite plugin')) + + if (!cssReplacedMap.size) + return + + const entires = Object.entries(cssReplacedMap) + for (const file of files) { + const chunk = bundle[file] + if (chunk.type === 'chunk' && typeof chunk.code === 'string') { + for (const [k, v] of entires) + chunk.code = chunk.code.replace(k, v) + } + else if (chunk.type === 'asset' && typeof chunk.source === 'string') { + for (const [k, v] of entires) + chunk.source = chunk.source.replace(k, v) + } + } }, }, ]