From 41b5d76fe1d43f7d2def5a6386ebdae341d6c6d7 Mon Sep 17 00:00:00 2001 From: poyoho <36070057+poyoho@users.noreply.github.com> Date: Wed, 8 Dec 2021 22:42:42 +0800 Subject: [PATCH] fix(plugin-vue): multiple vue files using the same src file (fix #5925, #5447) (#5994) --- packages/plugin-vue/src/index.ts | 7 +++++-- packages/plugin-vue/src/main.ts | 10 +++++----- packages/plugin-vue/src/utils/descriptorCache.ts | 15 ++++++++++++--- packages/plugin-vue/src/utils/query.ts | 5 +---- 4 files changed, 23 insertions(+), 14 deletions(-) diff --git a/packages/plugin-vue/src/index.ts b/packages/plugin-vue/src/index.ts index 71ec6e7a..9862a9da 100644 --- a/packages/plugin-vue/src/index.ts +++ b/packages/plugin-vue/src/index.ts @@ -9,7 +9,7 @@ import { } from '@vue/compiler-sfc' import { compiler } from './compiler' import { parseVueRequest } from './utils/query' -import { getDescriptor } from './utils/descriptorCache' +import { getDescriptor, getSrcDescriptor } from './utils/descriptorCache' import { getResolvedScript } from './script' import { transformMain } from './main' import { handleHotUpdate } from './handleHotUpdate' @@ -223,7 +223,10 @@ export default function vuePlugin(rawOptions: Options = {}): Plugin { ) } else { // sub block request - const descriptor = getDescriptor(filename, options)! + const descriptor = query.src + ? getSrcDescriptor(filename, query)! + : getDescriptor(filename, options)! + if (query.type === 'template') { return transformTemplateAsModule(code, descriptor, options, this, ssr) } else if (query.type === 'style') { diff --git a/packages/plugin-vue/src/main.ts b/packages/plugin-vue/src/main.ts index bb307676..9df5ba44 100644 --- a/packages/plugin-vue/src/main.ts +++ b/packages/plugin-vue/src/main.ts @@ -6,7 +6,7 @@ import { ResolvedOptions } from '.' import { createDescriptor, getPrevDescriptor, - setDescriptor + setSrcDescriptor } from './utils/descriptorCache' import { PluginContext, SourceMap, TransformPluginContext } from 'rollup' import { normalizePath } from '@rollup/pluginutils' @@ -237,7 +237,7 @@ async function genTemplateCode( await linkSrcToDescriptor(template.src, descriptor, pluginContext) } const src = template.src || descriptor.filename - const srcQuery = template.src ? `&src` : `` + const srcQuery = template.src ? `&src=${descriptor.id}` : `` const attrsQuery = attrsToQuery(template.attrs, 'js', true) const query = `?vue&type=template${srcQuery}${attrsQuery}` const request = JSON.stringify(src + query) @@ -279,7 +279,7 @@ async function genScriptCode( const src = script.src || descriptor.filename const langFallback = (script.src && path.extname(src).slice(1)) || 'js' const attrsQuery = attrsToQuery(script.attrs, langFallback) - const srcQuery = script.src ? `&src` : `` + const srcQuery = script.src ? `&src=${descriptor.id}` : `` const query = `?vue&type=script${srcQuery}${attrsQuery}` const request = JSON.stringify(src + query) scriptCode = @@ -310,7 +310,7 @@ async function genStyleCode( // do not include module in default query, since we use it to indicate // that the module needs to export the modules json const attrsQuery = attrsToQuery(style.attrs, 'css') - const srcQuery = style.src ? `&src` : `` + const srcQuery = style.src ? `&src=${descriptor.id}` : `` const directQuery = asCustomElement ? `&inline` : `` const query = `?vue&type=style&index=${i}${srcQuery}${directQuery}` const styleRequest = src + query + attrsQuery @@ -397,7 +397,7 @@ async function linkSrcToDescriptor( (await pluginContext.resolve(src, descriptor.filename))?.id || src // #1812 if the src points to a dep file, the resolved id may contain a // version query. - setDescriptor(srcFile.replace(/\?.*$/, ''), descriptor) + setSrcDescriptor(srcFile.replace(/\?.*$/, ''), descriptor) } // these are built-in query parameters so should be ignored diff --git a/packages/plugin-vue/src/utils/descriptorCache.ts b/packages/plugin-vue/src/utils/descriptorCache.ts index dde91e21..432b5f8f 100644 --- a/packages/plugin-vue/src/utils/descriptorCache.ts +++ b/packages/plugin-vue/src/utils/descriptorCache.ts @@ -3,7 +3,7 @@ import path from 'path' import slash from 'slash' import hash from 'hash-sum' import { CompilerError, SFCDescriptor } from '@vue/compiler-sfc' -import { ResolvedOptions } from '..' +import { ResolvedOptions, VueQuery } from '..' import { compiler } from '../compiler' // node_modules/@vue/compiler-sfc/dist/compiler-sfc.d.ts SFCParseResult should be exported so it can be re-used @@ -66,6 +66,15 @@ export function getDescriptor( } } -export function setDescriptor(filename: string, entry: SFCDescriptor): void { - cache.set(filename, entry) +export function getSrcDescriptor( + filename: string, + query: VueQuery +): SFCDescriptor { + return cache.get(`${filename}?src=${query.src}`)! +} + +export function setSrcDescriptor(filename: string, entry: SFCDescriptor): void { + // if multiple Vue files use the same src file, they will be overwritten + // should use other key + cache.set(`${filename}?src=${entry.id}`, entry) } diff --git a/packages/plugin-vue/src/utils/query.ts b/packages/plugin-vue/src/utils/query.ts index bd99ab6f..d41cb1be 100644 --- a/packages/plugin-vue/src/utils/query.ts +++ b/packages/plugin-vue/src/utils/query.ts @@ -2,7 +2,7 @@ import qs from 'querystring' export interface VueQuery { vue?: boolean - src?: boolean + src?: string type?: 'script' | 'template' | 'style' | 'custom' index?: number lang?: string @@ -18,9 +18,6 @@ export function parseVueRequest(id: string): { if (query.vue != null) { query.vue = true } - if (query.src != null) { - query.src = true - } if (query.index != null) { query.index = Number(query.index) }