Skip to content

feat: 支持 vue 的 template 与 js 分开定义的模式(非标准 vue 文件)#491

Open
L-H-B-666 wants to merge 1 commit intozh-lx:nextfrom
L-H-B-666:next
Open

feat: 支持 vue 的 template 与 js 分开定义的模式(非标准 vue 文件)#491
L-H-B-666 wants to merge 1 commit intozh-lx:nextfrom
L-H-B-666:next

Conversation

@L-H-B-666
Copy link
Copy Markdown

code-inspector-plugin 支持分离式 Vue HTML 模板文件

问题

某些项目中 Vue 代码采用 .js + .html 分离式写法,HTML 模板通过 require("./xxx.html") 引入。code-inspector-plugin 无法为这类 HTML 模板文件注入 data-insp-path 定位属性。

根因

插件的 webpack loader 对 .html 文件只处理带 ?vue&type=template query 的情况(通过 vue-loader 的 SFC 机制),直接 require 的 HTML 文件不会触发转换。

修改文件

  1. packages/webpack/src/index.ts - 新增独立 .html 文件的 loader 规则(enforce: 'pre'
  2. packages/webpack/src/loader.ts - 新增 isStandaloneHtmlTemplate 判断分支
  3. packages/core/src/server/transform/index.ts - 新增 vue-html 文件类型处理
  4. packages/core/src/server/transform/transform-vue.ts - 新增 transformVueHtml 函数

@qodo-free-for-open-source-projects
Copy link
Copy Markdown

Review Summary by Qodo

Support separated Vue template and script file patterns

✨ Enhancement

Grey Divider

Walkthroughs

Description
• Support separated Vue template and script files via require('./xxx.html')
• Add standalone HTML template transformation with vue-html file type
• Detect and handle HTML files containing Vue template syntax
• Inject data-insp-path attributes into separated HTML templates
Diagram
flowchart LR
  A["HTML file via require"] --> B["Webpack loader detects standalone HTML"]
  B --> C["transformCode with vue-html type"]
  C --> D["transformVueHtml parses template"]
  D --> E["Inject data-insp-path attributes"]
  E --> F["Return transformed HTML"]
Loading

Grey Divider

File Changes

1. packages/webpack/src/index.ts ✨ Enhancement +24/-1

Add webpack rule for standalone HTML templates

• Add logic to detect if user's match pattern includes .html files
• Create separate webpack rule for standalone .html files with enforce: 'pre'
• Conditionally add .html rule only when user's pattern matches .html
• Preserve original match pattern logic for non-.html patterns

packages/webpack/src/index.ts


2. packages/webpack/src/loader.ts ✨ Enhancement +10/-2

Detect standalone HTML template files in loader

• Add isStandaloneHtmlTemplate detection for .html files without vue query
• Check if file matches user's configured match pattern
• Pass 'vue-html' fileType for standalone HTML templates
• Distinguish between vue-loader processed and standalone HTML files

packages/webpack/src/loader.ts


3. packages/core/src/server/transform/index.ts ✨ Enhancement +4/-2

Add vue-html file type handling in transform

• Add 'vue-html' to FileType union type
• Import transformVueHtml function from transform-vue module
• Add conditional branch to handle vue-html file type
• Call transformVueHtml for standalone HTML templates

packages/core/src/server/transform/index.ts


View more (5)
4. packages/core/src/server/transform/transform-vue.ts ✨ Enhancement +24/-0

Implement transformVueHtml for standalone templates

• Add new transformVueHtml function for standalone HTML templates
• Parse HTML content directly as Vue template fragment
• Reuse transformVueTemplate logic for attribute injection
• Include comprehensive JSDoc explaining the function's purpose

packages/core/src/server/transform/transform-vue.ts


5. packages/core/src/shared/utils.ts ✨ Enhancement +3/-3

Support vue-html in ignore file detection

• Add 'vue-html' to FileType union in isIgnoredFile function
• Update comment to include vue-html in HTML comment checking logic
• Extend ignore directive detection to cover standalone HTML templates

packages/core/src/shared/utils.ts


6. packages/core/types/server/transform/index.d.ts 📝 Documentation +1/-1

Update FileType declaration with vue-html

• Add 'vue-html' to FileType type definition
• Update type declaration to match implementation changes

packages/core/types/server/transform/index.d.ts


7. packages/core/types/server/transform/transform-vue.d.ts 📝 Documentation +9/-0

Add transformVueHtml type declaration

• Add transformVueHtml function declaration
• Include JSDoc documentation for the new function
• Document the purpose and use case for standalone HTML templates

packages/core/types/server/transform/transform-vue.d.ts


8. packages/core/types/shared/utils.d.ts 📝 Documentation +1/-1

Update isIgnoredFile type with vue-html

• Add 'vue-html' to FileType union in isIgnoredFile declaration
• Update JSDoc to mention vue-html file type support

packages/core/types/shared/utils.d.ts


Grey Divider

Qodo Logo

@qodo-free-for-open-source-projects
Copy link
Copy Markdown

qodo-free-for-open-source-projects bot commented Mar 5, 2026

Code Review by Qodo

🐞 Bugs (3) 📘 Rule violations (0) 📎 Requirement gaps (0)

Grey Divider


Action required

1. Match overridden when html 🐞 Bug ✓ Correctness
Description
When options.match includes .html, the webpack plugin replaces the user-provided match regex
with a hard-coded default for the main rule, which can silently stop transforming user-intended file
types (or start transforming unintended ones). This breaks the documented contract that match
controls which files participate in transformation.
Code

packages/webpack/src/index.ts[R74-76]

+      test: matchIncludesHtml
+        ? /\.(vue|jsx|tsx|js|ts|mjs|mts|svelte)$/
+        : matchPattern,
Evidence
CodeOptions.match is documented as the regex that determines which files are transformed. However,
when matchIncludesHtml is true, webpack rule #3 ignores the user regex and uses a fixed regex for
vue/js/ts/svelte only, so any custom patterns/extensions/path-scoped matches are lost.

packages/webpack/src/index.ts[40-76]
packages/core/src/shared/type.ts[302-307]

Agent prompt
The issue below was found during a code review. Follow the provided context and guidance below and implement a solution

## Issue description
When `options.match` includes `.html`, the webpack rules currently replace the user's `match` regex with a fixed default regex for the main transform rule. This breaks user configuration and can skip intended files.

## Issue Context
`CodeOptions.match` is documented as the controlling filter for which files participate in transformation.

## Fix Focus Areas
- packages/webpack/src/index.ts[40-84]

ⓘ Copy this prompt and use it to remediate the issue with your preferred AI generation tools


2. Html detection uses test('.html') 🐞 Bug ⛯ Reliability
Description
The code decides whether .html is included by running RegExp.test('.html'), which is unreliable
for path-scoped regexes (e.g. /src\/.*\.html$/) and can prevent enabling the standalone html rule
and/or the loader’s standalone branch. This can make the new feature silently not work for common
match patterns.
Code

packages/webpack/src/index.ts[R40-43]

+  // Determine the file match pattern, supporting both default and user-configured patterns
+  const matchPattern = options.match ?? /\.(vue|jsx|tsx|js|ts|mjs|mts|svelte)$/;
+  // Check if user's match pattern includes .html
+  const matchIncludesHtml = matchPattern instanceof RegExp && matchPattern.test('.html');
Evidence
match is used elsewhere in the repo as a file-path matcher (options.match.test(filePath)), so
users may reasonably supply path-scoped regexes. Testing against the literal string '.html' will
not match those patterns, leading matchIncludesHtml / isStandaloneHtmlTemplate to be false even
for actual .html files that do match the user’s regex.

packages/webpack/src/index.ts[40-44]
packages/webpack/src/loader.ts[79-87]
packages/vite/src/index.ts[115-118]

Agent prompt
The issue below was found during a code review. Follow the provided context and guidance below and implement a solution

## Issue description
Determining whether HTML is enabled via `RegExp.test('.html')` is brittle for path-scoped `options.match` patterns and can disable the feature unexpectedly.

## Issue Context
Other bundlers in this repo apply `options.match` to the real file path. Webpack path matching should behave similarly.

## Fix Focus Areas
- packages/webpack/src/index.ts[40-44]
- packages/webpack/src/loader.ts[79-94]

ⓘ Copy this prompt and use it to remediate the issue with your preferred AI generation tools



Remediation recommended

3. Overlapping html rules duplicate 🐞 Bug ➹ Performance
Description
When matchIncludesHtml is true, .html?vue... requests can match both the resourceQuery: /vue/
rule and the standalone .html rule, leading to the same loader being applied multiple times to the
same module (extra parse/transform work and higher build cost).
Code

packages/webpack/src/index.ts[R57-70]

+    // If user's match pattern includes .html, add a separate rule for standalone .html files
+    // These are HTML template files used as Vue templates via require('./xxx.html')
+    ...(matchIncludesHtml
+      ? [
+          {
+            test: /\.html$/,
+            use: [
+              {
+                loader: path.resolve(compatibleDirname, `./loader.js`),
+                options,
+              },
+            ],
+            ...(options.enforcePre === false ? {} : { enforce: 'pre' }),
+          },
Evidence
The webpack config adds both a .html rule keyed on resourceQuery: /vue/ and another
unconditional .html rule. The loader itself will transform .html with params.has('vue')
(isHtmlVue branch), so if both rules contribute the loader, the work can be duplicated.

packages/webpack/src/index.ts[45-72]
packages/webpack/src/loader.ts[75-95]

Agent prompt
The issue below was found during a code review. Follow the provided context and guidance below and implement a solution

## Issue description
`.html?vue...` requests can match both the vue-query html rule and the standalone html rule, duplicating loader work.

## Issue Context
The loader transforms based on query params, so if it is present twice in the chain it will run twice.

## Fix Focus Areas
- packages/webpack/src/index.ts[45-72]

ⓘ Copy this prompt and use it to remediate the issue with your preferred AI generation tools


Grey Divider

ⓘ The new review experience is currently in Beta. Learn more

Grey Divider

Qodo Logo

Comment on lines +74 to +76
test: matchIncludesHtml
? /\.(vue|jsx|tsx|js|ts|mjs|mts|svelte)$/
: matchPattern,
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Action required

1. Match overridden when html 🐞 Bug ✓ Correctness

When options.match includes .html, the webpack plugin replaces the user-provided match regex
with a hard-coded default for the main rule, which can silently stop transforming user-intended file
types (or start transforming unintended ones). This breaks the documented contract that match
controls which files participate in transformation.
Agent Prompt
## Issue description
When `options.match` includes `.html`, the webpack rules currently replace the user's `match` regex with a fixed default regex for the main transform rule. This breaks user configuration and can skip intended files.

## Issue Context
`CodeOptions.match` is documented as the controlling filter for which files participate in transformation.

## Fix Focus Areas
- packages/webpack/src/index.ts[40-84]

ⓘ Copy this prompt and use it to remediate the issue with your preferred AI generation tools

Comment on lines +40 to +43
// Determine the file match pattern, supporting both default and user-configured patterns
const matchPattern = options.match ?? /\.(vue|jsx|tsx|js|ts|mjs|mts|svelte)$/;
// Check if user's match pattern includes .html
const matchIncludesHtml = matchPattern instanceof RegExp && matchPattern.test('.html');
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Action required

2. Html detection uses test('.html') 🐞 Bug ⛯ Reliability

The code decides whether .html is included by running RegExp.test('.html'), which is unreliable
for path-scoped regexes (e.g. /src\/.*\.html$/) and can prevent enabling the standalone html rule
and/or the loader’s standalone branch. This can make the new feature silently not work for common
match patterns.
Agent Prompt
## Issue description
Determining whether HTML is enabled via `RegExp.test('.html')` is brittle for path-scoped `options.match` patterns and can disable the feature unexpectedly.

## Issue Context
Other bundlers in this repo apply `options.match` to the real file path. Webpack path matching should behave similarly.

## Fix Focus Areas
- packages/webpack/src/index.ts[40-44]
- packages/webpack/src/loader.ts[79-94]

ⓘ Copy this prompt and use it to remediate the issue with your preferred AI generation tools

@zh-lx zh-lx changed the base branch from next to main March 5, 2026 04:39
@zh-lx zh-lx changed the base branch from main to next March 5, 2026 04:40
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant