diff --git a/README.md b/README.md index a3097ae..ab645b4 100644 --- a/README.md +++ b/README.md @@ -169,6 +169,12 @@ interface VitePluginInspectorOptions { * @default code (Visual Studio Code) */ launchEditor?: 'appcode' | 'atom' | 'atom-beta' | 'brackets' | 'clion' | 'code' | 'code-insiders' | 'codium' | 'emacs' | 'idea' | 'notepad++' | 'pycharm' | 'phpstorm' | 'rubymine' | 'sublime' | 'vim' | 'visualstudio' | 'webstorm' + + /** + * Exclude .vue file tags from being treated as templates. + * By default, `style` and `i18n` tags are excluded. + */ + excludedTags?: string[] } ``` diff --git a/packages/core/README.md b/packages/core/README.md index a3097ae..ab645b4 100644 --- a/packages/core/README.md +++ b/packages/core/README.md @@ -169,6 +169,12 @@ interface VitePluginInspectorOptions { * @default code (Visual Studio Code) */ launchEditor?: 'appcode' | 'atom' | 'atom-beta' | 'brackets' | 'clion' | 'code' | 'code-insiders' | 'codium' | 'emacs' | 'idea' | 'notepad++' | 'pycharm' | 'phpstorm' | 'rubymine' | 'sublime' | 'vim' | 'visualstudio' | 'webstorm' + + /** + * Exclude .vue file tags from being treated as templates. + * By default, `style` and `i18n` tags are excluded. + */ + excludedTags?: string[] } ``` diff --git a/packages/core/src/compiler/template.ts b/packages/core/src/compiler/template.ts index bca7dae..7d9036b 100644 --- a/packages/core/src/compiler/template.ts +++ b/packages/core/src/compiler/template.ts @@ -1,6 +1,6 @@ import path from 'node:path' import MagicString from 'magic-string' -import { parse as vueParse, transform as vueTransform } from '@vue/compiler-dom' +import { type PlainElementNode, parse as vueParse, transform as vueTransform } from '@vue/compiler-dom' import { parse as babelParse, traverse as babelTraverse } from '@babel/core' import vueJsxPlugin from '@vue/babel-plugin-jsx' import typescriptPlugin from '@babel/plugin-transform-typescript' @@ -16,9 +16,10 @@ interface CompileSFCTemplateOptions { code: string id: string type: 'template' | 'jsx' + excludedTopLevelTags?: string[] } export async function compileSFCTemplate( - { code, id, type }: CompileSFCTemplateOptions, + { code, id, type, excludedTopLevelTags = [] }: CompileSFCTemplateOptions, ) { const s = new MagicString(code) const relativePath = normalizePath(path.relative(process.cwd(), id)) @@ -26,6 +27,10 @@ export async function compileSFCTemplate( switch (type) { case 'template': { const ast = vueParse(code, { comments: true }) + + // Remove excluded top level tags - their content should not be mutated + ast.children = ast.children.filter((c: PlainElementNode) => !excludedTopLevelTags.includes(c.tag)) + vueTransform(ast, { nodeTransforms: [ (node) => { diff --git a/packages/core/src/index.ts b/packages/core/src/index.ts index abe0bac..f51ac7f 100644 --- a/packages/core/src/index.ts +++ b/packages/core/src/index.ts @@ -110,6 +110,12 @@ export interface VitePluginInspectorOptions { * @default process.env.LAUNCH_EDITOR ?? code (Visual Studio Code) */ launchEditor?: 'appcode' | 'atom' | 'atom-beta' | 'brackets' | 'clion' | 'code' | 'code-insiders' | 'codium' | 'emacs' | 'idea' | 'notepad++' | 'pycharm' | 'phpstorm' | 'rubymine' | 'sublime' | 'vim' | 'visualstudio' | 'webstorm' | 'rider' | string + + /** + * Exclude .vue file tags from being treated as templates. + * By default, `style` and `i18n` tags are excluded. + */ + excludedTags?: string[] } const toggleComboKeysMap = { @@ -136,6 +142,7 @@ export const DEFAULT_INSPECTOR_OPTIONS: VitePluginInspectorOptions = { appendTo: '', lazyLoad: false, launchEditor: process.env.LAUNCH_EDITOR ?? 'code', + excludedTags: ['style', 'i18n'] as string[], } as const function VitePluginInspector(options: VitePluginInspectorOptions = DEFAULT_INSPECTOR_OPTIONS): PluginOption { @@ -193,10 +200,10 @@ function VitePluginInspector(options: VitePluginInspectorOptions = DEFAULT_INSPE const { filename, query } = parseVueRequest(id) const isJsx = filename.endsWith('.jsx') || filename.endsWith('.tsx') || (filename.endsWith('.vue') && query.isJsx) - const isTpl = filename.endsWith('.vue') && query.type !== 'style' && !query.raw + const isTpl = filename.endsWith('.vue') && !normalizedOptions.excludedTags?.includes(query.type) && !query.raw if (isJsx || isTpl) - return compileSFCTemplate({ code, id: filename, type: isJsx ? 'jsx' : 'template' }) + return compileSFCTemplate({ code, id: filename, type: isJsx ? 'jsx' : 'template', excludedTopLevelTags: normalizedOptions.excludedTags }) if (!appendTo) return diff --git a/packages/playground/vue3/src/App.vue b/packages/playground/vue3/src/App.vue index def47d6..21453cd 100644 --- a/packages/playground/vue3/src/App.vue +++ b/packages/playground/vue3/src/App.vue @@ -40,3 +40,11 @@ p color: #35495d cursor: pointer + + +{ + "en": { + "somethingWithHtml": "This is HTML content" + } +} + \ No newline at end of file diff --git a/packages/unplugin/README.md b/packages/unplugin/README.md index 939599d..a3831b3 100644 --- a/packages/unplugin/README.md +++ b/packages/unplugin/README.md @@ -169,6 +169,12 @@ interface VitePluginInspectorOptions { * @default code (Visual Studio Code) */ launchEditor?: 'appcode' | 'atom' | 'atom-beta' | 'brackets' | 'clion' | 'code' | 'code-insiders' | 'codium' | 'emacs' | 'idea' | 'notepad++' | 'pycharm' | 'phpstorm' | 'rubymine' | 'sublime' | 'vim' | 'visualstudio' | 'webstorm' + + /** + * Exclude .vue file tags from being treated as templates. + * By default, `style` and `i18n` tags are excluded. + */ + excludedTags?: string[] } ```