Skip to content

Commit e764f58

Browse files
authored
Merge pull request #553 from zh-lx/fix/vue-loader-mode
feat: add vue loader mode option
2 parents 7f8790a + 9aee729 commit e764f58

11 files changed

Lines changed: 299 additions & 110 deletions

File tree

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

Lines changed: 13 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -4,8 +4,13 @@ import { transformJsx } from './transform-jsx';
44
import { transformMdx } from './transform-mdx';
55
import { transformSvelte } from './transform-svelte';
66
import { transformVue } from './transform-vue';
7-
export { createVueInspectorNodeTransform } from './vue-node-transform';
8-
import { EscapeTags, PathType, isIgnoredFile, CodeInspectorEscapeTags } from '../../shared';
7+
export { createVueInspectorNodeTransform } from './transform-vue-node';
8+
import {
9+
EscapeTags,
10+
PathType,
11+
isIgnoredFile,
12+
CodeInspectorEscapeTags,
13+
} from '../../shared';
914
import { getRelativeOrAbsolutePath } from '../server';
1015

1116
type FileType = 'vue' | 'jsx' | 'svelte' | 'astro' | 'mdx' | unknown;
@@ -44,7 +49,12 @@ export async function transformCode(params: TransformCodeParams) {
4449
} else if (fileType === 'svelte') {
4550
return transformSvelte(content, filePath, finalEscapeTags);
4651
} else if (fileType === 'astro') {
47-
return transformAstro(content, filePath, finalEscapeTags, resolveFilePath);
52+
return transformAstro(
53+
content,
54+
filePath,
55+
finalEscapeTags,
56+
resolveFilePath,
57+
);
4858
} else if (fileType === 'mdx') {
4959
if (!mdx) {
5060
return content;

packages/core/src/server/transform/vue-node-transform.ts renamed to packages/core/src/server/transform/transform-vue-node.ts

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -58,7 +58,11 @@ function getNodeFilePath(
5858
context: TransformContext,
5959
options: VueInspectorNodeTransformOptions,
6060
) {
61-
const filename = normalizePath(context.filename || '');
61+
if (!context.filename) {
62+
return '';
63+
}
64+
65+
const filename = normalizePath(context.filename);
6266
const mappedFilePath = getMappingFilePath(filename, options.mappings);
6367
return getRelativeOrAbsolutePath(
6468
mappedFilePath,
@@ -85,6 +89,10 @@ export function createVueInspectorNodeTransform(
8589

8690
const { line, column } = node.loc.start;
8791
const filePath = getNodeFilePath(context, options);
92+
if (!filePath) {
93+
return;
94+
}
95+
8896
node.props.unshift(
8997
createAttributeNode(
9098
PathName,

packages/core/src/shared/type.ts

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -144,6 +144,15 @@ export type CodeOptions = {
144144
* @en Additional files to be compiled (used to make some files in `node_modules` participate in compilation to inject path information)
145145
*/
146146
include?: Condition;
147+
/**
148+
* @zh Vue 文件的编译方式,仅对 `webpack/rspack/rsbuild` 项目生效,默认值为 `custom`
149+
* - `custom` 表示使用 code-inspector-plugin 自定义的 loader 注入,优点是兼容性强,部分 vue 项目生产环境使用可能导致 scoped css 失效
150+
* - `internal` 表示使用 vue-loader 内部 compiler node transform,可以解决生产环境 scoped css 失效问题,但是低版本 vue compiler 不兼容
151+
* @en Vue file compilation mode, only effective for `webpack/rspack/rsbuild` projects, default value is `custom`
152+
* - `custom` means using code-inspector-plugin's custom loader injection, with strong compatibility, but may cause scoped CSS to fail in some Vue projects in production environment
153+
* - `internal` means using vue-loader's internal compiler node transform, which can solve the scoped CSS failure issue in production environment, but is not compatible with lower versions of Vue compiler
154+
*/
155+
vueLoader?: 'custom' | 'internal';
147156
/**
148157
* @zh 不参与编译的文件
149158
* @en Files not to be compiled

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

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
export { createVueInspectorNodeTransform } from './vue-node-transform';
1+
export { createVueInspectorNodeTransform } from './transform-vue-node';
22
import { EscapeTags, PathType } from '../../shared';
33
type FileType = 'vue' | 'jsx' | 'svelte' | 'astro' | 'mdx' | unknown;
44
type TransformCodeParams = {

packages/core/types/server/transform/vue-node-transform.d.ts renamed to packages/core/types/server/transform/transform-vue-node.d.ts

File renamed without changes.

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

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -139,6 +139,11 @@ export type CodeOptions = {
139139
* @en Additional files to be compiled (used to make some files in `node_modules` participate in compilation to inject path information)
140140
*/
141141
include?: Condition;
142+
/**
143+
* @zh Vue 文件的注入方式。`custom` 表示使用 loader 注入,`internal` 表示使用 vue-loader 内部 compiler node transform。
144+
* @en Vue injection mode. `custom` uses the loader path, `internal` uses vue-loader's internal compiler node transform.
145+
*/
146+
vueLoader?: 'custom' | 'internal';
142147
/**
143148
* @zh 不参与编译的文件
144149
* @en Files not to be compiled

packages/webpack/src/index.ts

Lines changed: 6 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,6 @@ const compatibleDirname = path.dirname(fileURLToPath(import.meta.url));
1515

1616
interface LoaderOptions extends CodeOptions {
1717
record: RecordInfo;
18-
vueCompilerNodeTransform?: boolean;
1918
}
2019

2120
const baseLoaderPath = path.resolve(compatibleDirname, './loader.js');
@@ -62,21 +61,13 @@ function isVueLoader(loader: string) {
6261
return /(^|[\\/])vue-loader([\\/]|$)/.test(loader);
6362
}
6463

65-
function isVueTemplateLoader(loader: string) {
66-
return /(^|[\\/])vue-loader[\\/]dist[\\/]templateLoader\.js$/.test(loader);
67-
}
68-
6964
function applyVueCompilerNodeTransform(options: CodeOptions, compiler: any) {
7065
const rules = getCompilerRules(compiler);
71-
let applied = false;
7266

7367
walkRules(rules, (rule) => {
7468
getUseItems(rule).forEach((item) => {
7569
const loader = typeof item === 'string' ? item : item?.loader;
76-
if (
77-
typeof loader !== 'string' ||
78-
(!isVueLoader(loader) && !isVueTemplateLoader(loader))
79-
) {
70+
if (typeof loader !== 'string' || !isVueLoader(loader)) {
8071
return;
8172
}
8273

@@ -117,12 +108,8 @@ function applyVueCompilerNodeTransform(options: CodeOptions, compiler: any) {
117108
});
118109
nodeTransforms.push(transform);
119110
}
120-
121-
applied = true;
122111
});
123112
});
124-
125-
return applied;
126113
}
127114

128115
function hasRegisteredCodeInspectorLoader(rules: any[]) {
@@ -275,14 +262,11 @@ class WebpackCodeInspectorPlugin {
275262
}
276263
}
277264

278-
const vueCompilerNodeTransform = applyVueCompilerNodeTransform(
279-
this.options,
280-
compiler,
281-
);
282-
applyLoader(
283-
{ ...this.options, record, vueCompilerNodeTransform },
284-
compiler,
285-
);
265+
if (this.options.vueLoader === 'internal') {
266+
applyVueCompilerNodeTransform(this.options, compiler);
267+
}
268+
269+
applyLoader({ ...this.options, record }, compiler);
286270

287271
if (
288272
compiler?.hooks?.emit &&

packages/webpack/src/loader.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -79,7 +79,7 @@ async function transformWebpackCodeInspectorContent(
7979
filePath.endsWith('.html') &&
8080
params.get('type') === 'template' &&
8181
params.has('vue');
82-
if (options.vueCompilerNodeTransform && (isVue || isHtmlVue)) {
82+
if (options.vueLoader === 'internal' && (isVue || isHtmlVue)) {
8383
return content;
8484
}
8585
if (isVue || isHtmlVue) {

0 commit comments

Comments
 (0)