Skip to content

Commit 9aee729

Browse files
committed
test: cover webpack vue loader branches
1 parent 1b0574a commit 9aee729

2 files changed

Lines changed: 183 additions & 8 deletions

File tree

packages/webpack/src/index.ts

Lines changed: 1 addition & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -61,20 +61,13 @@ function isVueLoader(loader: string) {
6161
return /(^|[\\/])vue-loader([\\/]|$)/.test(loader);
6262
}
6363

64-
function isVueTemplateLoader(loader: string) {
65-
return /(^|[\\/])vue-loader[\\/]dist[\\/]templateLoader\.js$/.test(loader);
66-
}
67-
6864
function applyVueCompilerNodeTransform(options: CodeOptions, compiler: any) {
6965
const rules = getCompilerRules(compiler);
7066

7167
walkRules(rules, (rule) => {
7268
getUseItems(rule).forEach((item) => {
7369
const loader = typeof item === 'string' ? item : item?.loader;
74-
if (
75-
typeof loader !== 'string' ||
76-
(!isVueLoader(loader) && !isVueTemplateLoader(loader))
77-
) {
70+
if (typeof loader !== 'string' || !isVueLoader(loader)) {
7871
return;
7972
}
8073

test/webpack/index.test.ts

Lines changed: 182 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -199,6 +199,73 @@ describe('WebpackCodeInspectorPlugin', () => {
199199
expect(codeInspectorRule.use[0].options.vueLoader).toBe('internal');
200200
});
201201

202+
it('should register Vue template loader node transform when internal mode is enabled', async () => {
203+
vi.mocked(isDev).mockReturnValueOnce(true);
204+
const templateLoaderOptions = {};
205+
mockCompiler.options.module.rules.push({
206+
test: /\.html$/,
207+
use: [
208+
{
209+
loader: '/test/node_modules/vue-loader/dist/templateLoader.js',
210+
options: templateLoaderOptions,
211+
},
212+
],
213+
});
214+
215+
const plugin = new WebpackCodeInspectorPlugin({
216+
bundler: 'webpack',
217+
output: '/test',
218+
vueLoader: 'internal',
219+
});
220+
221+
await plugin.apply(mockCompiler);
222+
223+
expect(templateLoaderOptions.compilerOptions.nodeTransforms).toHaveLength(
224+
1,
225+
);
226+
});
227+
228+
it('should skip string-only vue loader entries', async () => {
229+
vi.mocked(isDev).mockReturnValueOnce(true);
230+
mockCompiler.options.module.rules.push({
231+
test: /\.vue$/,
232+
use: ['vue-loader'],
233+
});
234+
235+
const plugin = new WebpackCodeInspectorPlugin({
236+
bundler: 'webpack',
237+
output: '/test',
238+
vueLoader: 'internal',
239+
});
240+
241+
await plugin.apply(mockCompiler);
242+
243+
expect(createVueInspectorNodeTransform).not.toHaveBeenCalled();
244+
});
245+
246+
it('should skip non-vue loaders when internal mode is enabled', async () => {
247+
vi.mocked(isDev).mockReturnValueOnce(true);
248+
mockCompiler.options.module.rules.push({
249+
test: /\.vue$/,
250+
use: [
251+
{
252+
loader: '/test/node_modules/not-vue-loader/dist/index.js',
253+
options: {},
254+
},
255+
],
256+
});
257+
258+
const plugin = new WebpackCodeInspectorPlugin({
259+
bundler: 'webpack',
260+
output: '/test',
261+
vueLoader: 'internal',
262+
});
263+
264+
await plugin.apply(mockCompiler);
265+
266+
expect(createVueInspectorNodeTransform).not.toHaveBeenCalled();
267+
});
268+
202269
it('should keep vueLoader defaulting to custom', async () => {
203270
vi.mocked(isDev).mockReturnValueOnce(true);
204271
const plugin = new WebpackCodeInspectorPlugin({
@@ -216,6 +283,108 @@ describe('WebpackCodeInspectorPlugin', () => {
216283
);
217284
expect(codeInspectorRule.use[0].options.vueLoader).toBeUndefined();
218285
});
286+
287+
it('should skip string vue-loader entries while traversing nested rules', async () => {
288+
vi.mocked(isDev).mockReturnValueOnce(true);
289+
const vueLoaderOptions = { compilerOptions: { nodeTransforms: [] } };
290+
mockCompiler.options.module.rules.push({
291+
oneOf: [
292+
{
293+
rules: [
294+
{
295+
use: [
296+
'vue-loader',
297+
{
298+
loader: '/test/node_modules/vue-loader/dist/index.js',
299+
options: vueLoaderOptions,
300+
},
301+
],
302+
},
303+
],
304+
},
305+
],
306+
});
307+
308+
const plugin = new WebpackCodeInspectorPlugin({
309+
bundler: 'webpack',
310+
output: '/test',
311+
vueLoader: 'internal',
312+
});
313+
314+
await plugin.apply(mockCompiler);
315+
316+
expect(vueLoaderOptions.compilerOptions.nodeTransforms).toHaveLength(1);
317+
});
318+
319+
it('should create compilerOptions when vue-loader options are missing', async () => {
320+
vi.mocked(isDev).mockReturnValueOnce(true);
321+
const useItem: any = {
322+
loader: '/test/node_modules/vue-loader/dist/index.js',
323+
};
324+
mockCompiler.options.module.rules.push({
325+
loader: '/test/node_modules/vue-loader/dist/index.js',
326+
use: [useItem],
327+
});
328+
329+
const plugin = new WebpackCodeInspectorPlugin({
330+
bundler: 'webpack',
331+
output: '/test',
332+
vueLoader: 'internal',
333+
});
334+
335+
await plugin.apply(mockCompiler);
336+
337+
expect(useItem.options.compilerOptions.nodeTransforms).toHaveLength(1);
338+
});
339+
340+
it('should initialize nodeTransforms when compilerOptions is empty', async () => {
341+
vi.mocked(isDev).mockReturnValueOnce(true);
342+
const vueLoaderOptions = { compilerOptions: {} };
343+
mockCompiler.options.module.rules.push({
344+
test: /\.vue$/,
345+
use: [
346+
{
347+
loader: '/test/node_modules/vue-loader/dist/index.js',
348+
options: vueLoaderOptions,
349+
},
350+
],
351+
});
352+
353+
const plugin = new WebpackCodeInspectorPlugin({
354+
bundler: 'webpack',
355+
output: '/test',
356+
vueLoader: 'internal',
357+
});
358+
359+
await plugin.apply(mockCompiler);
360+
361+
expect(Array.isArray(vueLoaderOptions.compilerOptions.nodeTransforms)).toBe(
362+
true,
363+
);
364+
expect(vueLoaderOptions.compilerOptions.nodeTransforms).toHaveLength(1);
365+
});
366+
367+
it('should handle rule.loader shorthand and ignore falsy rules', async () => {
368+
vi.mocked(isDev).mockReturnValueOnce(true);
369+
const vueLoaderOptions = { compilerOptions: { nodeTransforms: [] } };
370+
mockCompiler.options.module.rules.push(
371+
null,
372+
{
373+
loader: '/test/node_modules/vue-loader/dist/index.js',
374+
options: vueLoaderOptions,
375+
},
376+
);
377+
378+
const plugin = new WebpackCodeInspectorPlugin({
379+
bundler: 'webpack',
380+
output: '/test',
381+
vueLoader: 'internal',
382+
});
383+
384+
await plugin.apply(mockCompiler);
385+
386+
expect(vueLoaderOptions.compilerOptions.nodeTransforms).toHaveLength(1);
387+
});
219388
});
220389

221390
describe('filesystem cache handling', () => {
@@ -346,6 +515,19 @@ describe('WebpackCodeInspectorPlugin', () => {
346515
expect(cb).toHaveBeenCalled();
347516
});
348517

518+
it('should skip htmlScript injection when disabled', async () => {
519+
vi.mocked(isDev).mockReturnValueOnce(true);
520+
const plugin = new WebpackCodeInspectorPlugin({
521+
bundler: 'webpack',
522+
output: '/test',
523+
skipSnippets: ['htmlScript'],
524+
});
525+
526+
await plugin.apply(mockCompiler);
527+
528+
expect(mockCompiler.hooks.emit.tapAsync).not.toHaveBeenCalled();
529+
});
530+
349531
it('should skip non-HTML files', async () => {
350532
vi.mocked(isDev).mockReturnValueOnce(true);
351533
const plugin = new WebpackCodeInspectorPlugin({

0 commit comments

Comments
 (0)