Skip to content

Commit

Permalink
fix(plugin-vue): multiple vue files using the same src file (fix #5925,
Browse files Browse the repository at this point in the history
  • Loading branch information
poyoho committed Dec 8, 2021
1 parent b625a2c commit df7aec7
Show file tree
Hide file tree
Showing 10 changed files with 47 additions and 15 deletions.
3 changes: 2 additions & 1 deletion packages/playground/vue/src-import/SrcImport.vue
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
<style src="/@/src-import/style.css" scoped></style>
<style src="/@/src-import/style2.css" scoped></style>
<template src="./template.html"></template>
<script src="./script.ts"></script>
<style src="/@/src-import/style.css" scoped></style>
6 changes: 6 additions & 0 deletions packages/playground/vue/src-import/script.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,12 @@
import { defineComponent } from 'vue'
import SrcImportStyle from './srcImportStyle.vue'
import SrcImportStyle2 from './srcImportStyle2.vue'

export default defineComponent({
components: {
SrcImportStyle,
SrcImportStyle2
},
setup() {
return {
msg: 'hello from script src!'
Expand Down
7 changes: 7 additions & 0 deletions packages/playground/vue/src-import/srcImportStyle.vue
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
<style src="/@/src-import/style.css" scoped></style>
<template>
<div class="src-imports-script">{{ msg }}</div>
</template>
<script setup>
const msg = 'hello from component A!'
</script>
4 changes: 4 additions & 0 deletions packages/playground/vue/src-import/srcImportStyle2.vue
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
<style src="/@/src-import/style2.css" scoped></style>
<template>
<div class="src-imports-style">This should be tan</div>
</template>
3 changes: 3 additions & 0 deletions packages/playground/vue/src-import/style2.css
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
.src-imports-script {
color: #0088ff;
}
2 changes: 2 additions & 0 deletions packages/playground/vue/src-import/template.html
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
<h2>SFC Src Imports</h2>
<div class="src-imports-script">{{ msg }}</div>
<div class="src-imports-style">This should be tan</div>
<SrcImportStyle></SrcImportStyle>
<SrcImportStyle2></SrcImportStyle2>
7 changes: 5 additions & 2 deletions packages/plugin-vue/src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -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'
Expand Down Expand Up @@ -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') {
Expand Down
10 changes: 5 additions & 5 deletions packages/plugin-vue/src/main.ts
Original file line number Diff line number Diff line change
Expand Up @@ -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'
Expand Down Expand Up @@ -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)
Expand Down Expand Up @@ -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 =
Expand Down Expand Up @@ -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
Expand Down Expand Up @@ -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
Expand Down
15 changes: 12 additions & 3 deletions packages/plugin-vue/src/utils/descriptorCache.ts
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down Expand Up @@ -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)
}
5 changes: 1 addition & 4 deletions packages/plugin-vue/src/utils/query.ts
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand All @@ -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)
}
Expand Down

0 comments on commit df7aec7

Please sign in to comment.