diff --git a/.idea/inspectionProfiles/Project_Default.xml b/.idea/inspectionProfiles/Project_Default.xml deleted file mode 100644 index 03d9549..0000000 --- a/.idea/inspectionProfiles/Project_Default.xml +++ /dev/null @@ -1,6 +0,0 @@ - - - - \ No newline at end of file diff --git a/packages/core/hmr/__test__/hmr.spec.ts b/packages/core/hmr/__test__/hmr.spec.ts index 26d32ec..0568d46 100644 --- a/packages/core/hmr/__test__/hmr.spec.ts +++ b/packages/core/hmr/__test__/hmr.spec.ts @@ -1,7 +1,7 @@ import { resolve } from 'path' import { beforeEach, describe, expect, test } from 'vitest' import { transformSymbol } from '@unplugin-vue-cssvars/utils' -import { triggerSFCUpdate, updatedCSSModules, viteHMR } from '../hmr' +import { reloadSFCModules, updatedCSSModules, viteHMR } from '../hmr' const mockOption = { rootDir: resolve(), @@ -54,7 +54,7 @@ describe('HMR', () => { expect(hmrModule).toMatchObject({ id: 'foo.vue' }) }) - test('HMR: triggerSFCUpdate basic', () => { + test('HMR: reloadSFCModules basic', () => { const CSSFileModuleMap = new Map() CSSFileModuleMap.set(file, { importer: new Set(), @@ -62,17 +62,15 @@ describe('HMR', () => { sfcPath: new Set(['../D/test']), }) - triggerSFCUpdate(CSSFileModuleMap, mockOption, { + reloadSFCModules(CSSFileModuleMap, mockOption, { importer: new Set(), vBindCode: ['foo'], sfcPath: new Set(['../D/test']), } as any, file, mockServer as any) - expect(CSSFileModuleMap.get(file).content).toBeTruthy() - expect(CSSFileModuleMap.get(file).vBindCode).toMatchObject(['test']) expect(hmrModule).toMatchObject({ id: 'foo.vue' }) }) - test('HMR: triggerSFCUpdate sfcPath is undefined', () => { + test('HMR: reloadSFCModules sfcPath is undefined', () => { const CSSFileModuleMap = new Map() CSSFileModuleMap.set(file, { importer: new Set(), @@ -80,7 +78,7 @@ describe('HMR', () => { sfcPath: new Set(['../D/test']), }) - triggerSFCUpdate(CSSFileModuleMap, mockOption, { + reloadSFCModules(CSSFileModuleMap, mockOption, { importer: new Set(), vBindCode: ['foo'], } as any, file, mockServer as any) @@ -89,7 +87,7 @@ describe('HMR', () => { expect(hmrModule).not.toBeTruthy() }) - test('HMR: triggerSFCUpdate sfcPath is empty', () => { + test('HMR: reloadSFCModules sfcPath is empty', () => { const CSSFileModuleMap = new Map() CSSFileModuleMap.set(file, { importer: new Set(), @@ -97,7 +95,7 @@ describe('HMR', () => { sfcPath: new Set(['../D/test']), }) - triggerSFCUpdate(CSSFileModuleMap, mockOption, { + reloadSFCModules(CSSFileModuleMap, mockOption, { importer: new Set(), vBindCode: ['foo'], sfcPath: new Set(), diff --git a/packages/core/hmr/hmr.ts b/packages/core/hmr/hmr.ts index 556c4bf..a273390 100644 --- a/packages/core/hmr/hmr.ts +++ b/packages/core/hmr/hmr.ts @@ -11,7 +11,11 @@ export function viteHMR( ) { // 获取变化的样式文件的 CSSFileMap上有使用它的 const sfcModulesPathList = CSSFileModuleMap.get(file) - triggerSFCUpdate(CSSFileModuleMap, userOptions, sfcModulesPathList!, file, server) + if (!(sfcModulesPathList && sfcModulesPathList.sfcPath)) return + // update CSSModules + updatedCSSModules(CSSFileModuleMap, userOptions, file) + // reload sfc Module + reloadSFCModules(CSSFileModuleMap, userOptions, sfcModulesPathList!, file, server) } // TODO: unit test @@ -20,15 +24,7 @@ export function webpackHMR( userOptions: Options, file: string, ) { - // 获取变化的样式文件的 CSSFileMap上有使用它的 - const sfcModulesPathList = CSSFileModuleMap.get(file) - if (sfcModulesPathList && sfcModulesPathList.sfcPath) { - const ls = setTArray(sfcModulesPathList.sfcPath) - ls.forEach(() => { - // updated CSSModules - updatedCSSModules(CSSFileModuleMap, userOptions, file) - }) - } + updatedCSSModules(CSSFileModuleMap, userOptions, file) } /** @@ -51,14 +47,14 @@ export function updatedCSSModules( } /** - * triggerSFCUpdate + * reloadSFCModules * @param CSSFileModuleMap * @param userOptions * @param sfcModulesPathList * @param file * @param server */ -export function triggerSFCUpdate( +export function reloadSFCModules( CSSFileModuleMap: ICSSFileMap, userOptions: Options, sfcModulesPathList: ICSSFile, @@ -68,8 +64,6 @@ export function triggerSFCUpdate( // 变化的样式文件的 CSSFileMap上有使用它的 sfc 的信息 const ls = setTArray(sfcModulesPathList.sfcPath) ls.forEach((sfcp: string) => { - // updatedCSSModules - updatedCSSModules(CSSFileModuleMap, userOptions, file) // update sfc const modules = server.moduleGraph.fileToModulesMap.get(sfcp) || new Set() const modulesList = setTArray(modules) diff --git a/packages/core/index.ts b/packages/core/index.ts index 2a470f3..96e777d 100644 --- a/packages/core/index.ts +++ b/packages/core/index.ts @@ -3,7 +3,6 @@ import { JSX_TSX_REG, NAME, SUPPORT_FILE_REG, log, - runAsyncTaskList, setTArray, transformSymbol, } from '@unplugin-vue-cssvars/utils' @@ -25,7 +24,7 @@ import type { MagicStringBase } from 'magic-string-ast' import type { HmrContext, ResolvedConfig } from 'vite' import type { TMatchVariable } from './parser' import type { Options } from './types' -// TODO: webpack hmr +// TODO refactor const unplugin = createUnplugin( (options: Options = {}, meta): any => { const framework = meta.framework @@ -39,12 +38,13 @@ const unplugin = createUnplugin( const vbindVariableList = new Map() let isScriptSetup = false if (userOptions.server === undefined) { + log('warning', 'The server of option is not set, you need to specify whether you are using the development server or building the project') + log('warning', 'The server of option is not set, you need to specify whether you are using the development server or building the project') console.warn(chalk.yellowBright.bold(`[${NAME}] The server of option is not set, you need to specify whether you are using the development server or building the project`)) console.warn(chalk.yellowBright.bold(`[${NAME}] See: https://github.com/baiwusanyu-c/unplugin-vue-cssvars/blob/master/README.md#option`)) } let isServer = !!userOptions.server let isHMR = false - const cacheWebpackModule = new Map() function handleVBindVariable( code: string, @@ -93,8 +93,9 @@ const unplugin = createUnplugin( mgcStr = res } - if ((transId.includes('?vue&type=style') && isHMR && framework === 'webpack')) { - transId = transId.split('?vue&type=style')[0] + if ((transId.includes('?vue&type=style') || transId.includes('?vue&type=script')) + && isHMR && framework === 'webpack') { + transId = transId.split('?vue')[0] const res = handleVBindVariable(code, transId, mgcStr) if (res) mgcStr = res @@ -134,10 +135,12 @@ const unplugin = createUnplugin( } }, }, + + // TODO unit test webpack(compiler) { // mark webpack hmr let modifiedFile = '' - compiler.hooks.watchRun.tap(NAME, (compilation1) => { + compiler.hooks.watchRun.tapAsync(NAME, (compilation1, watchRunCallBack) => { if (compilation1.modifiedFiles) { modifiedFile = transformSymbol(setTArray(compilation1.modifiedFiles)[0] as string) if (SUPPORT_FILE_REG.test(modifiedFile)) { @@ -149,6 +152,7 @@ const unplugin = createUnplugin( ) } } + watchRunCallBack() }) compiler.hooks.compilation.tap(NAME, (compilation) => { @@ -180,6 +184,8 @@ const unplugin = createUnplugin( Promise.all(promises) .then(() => { callback() + // hmr end + isHMR = false }) .catch((e) => { log('error', e) @@ -202,6 +208,7 @@ const unplugin = createUnplugin( return filter(id) }, async transform(code: string, id: string) { + console.log(id) let transId = transformSymbol(id) let mgcStr = new MagicString(code) // ⭐TODO: 只支持 .vue ? jsx, tsx, js, ts ? @@ -211,7 +218,7 @@ const unplugin = createUnplugin( const injectRes = injectCSSVars(vbindVariableList.get(idKey), isScriptSetup, parseRes, mgcStr) mgcStr = injectRes.mgcStr injectRes.vbindVariableList && vbindVariableList.set(transId, injectRes.vbindVariableList) - isHMR = false + // TODO vite hmr close ? isHMR -> false } // transform in dev @@ -237,7 +244,7 @@ const unplugin = createUnplugin( // webpack dev 和 build 都回进入这里 if (framework === 'webpack') { if (transId.includes('?vue&type=script')) { - transId = transId.split('?vue&type=script')[0] + transId = transId.split('?vue')[0] injectCSSVarsFn(transId) } diff --git a/packages/core/inject/inject-css.ts b/packages/core/inject/inject-css.ts index 92147c7..69ce28b 100644 --- a/packages/core/inject/inject-css.ts +++ b/packages/core/inject/inject-css.ts @@ -1,7 +1,7 @@ import hash from 'hash-sum' -import { type MagicStringBase } from 'magic-string-ast' import { transformInjectCSS } from '../transform/transform-inject-css' import { parseImports } from '../parser' +import type { MagicStringBase } from 'magic-string-ast' import type { TInjectCSSContent } from '../runtime/process-css' import type { SFCDescriptor } from '@vue/compiler-sfc' import type { TMatchVariable } from '../parser' @@ -11,7 +11,7 @@ export function injectCSSOnServer( isHMR: boolean, ) { vbindVariableList && vbindVariableList.forEach((vbVar) => { - // 样式文件修改后,热更新会先于 sfc 热更新运行,这里先设置hash + // 样式文件修改后,style热更新可能会先于 sfc 热更新运行,这里先设置hash // 详见 packages/core/index.ts的 handleHotUpdate if (!vbVar.hash && isHMR) vbVar.hash = hash(vbVar.value + vbVar.has) diff --git a/play/vite/src/assets/css/foo.css b/play/vite/src/assets/css/foo.css index f984443..201b228 100644 --- a/play/vite/src/assets/css/foo.css +++ b/play/vite/src/assets/css/foo.css @@ -1,6 +1,9 @@ #foo{ - color: v-bind-m(color); + color: v-bind-m(sassColor); background: #ffebf8; width: 200px; height: 30px; } +p { + color: v-bind-m(color); +} \ No newline at end of file diff --git a/play/vite/src/comp.vue b/play/vite/src/comp.vue index 85174ca..52284a0 100644 --- a/play/vite/src/comp.vue +++ b/play/vite/src/comp.vue @@ -1,36 +1,12 @@ - - diff --git a/play/vite/src/comp2.vue b/play/vite/src/comp2.vue new file mode 100644 index 0000000..0cfa6f4 --- /dev/null +++ b/play/vite/src/comp2.vue @@ -0,0 +1,12 @@ + + + + + diff --git a/play/vite/src/views/app/App.vue b/play/vite/src/views/app/App.vue index 7b364d6..4f724bf 100644 --- a/play/vite/src/views/app/App.vue +++ b/play/vite/src/views/app/App.vue @@ -1,7 +1,8 @@ + + - + --> diff --git a/play/webpack/src/App.vue b/play/webpack/src/App.vue index ff604b7..10a3f9a 100644 --- a/play/webpack/src/App.vue +++ b/play/webpack/src/App.vue @@ -1,7 +1,7 @@ + + + + diff --git a/play/webpack/src/comp2.vue b/play/webpack/src/comp2.vue new file mode 100644 index 0000000..0cfa6f4 --- /dev/null +++ b/play/webpack/src/comp2.vue @@ -0,0 +1,12 @@ + + + + +