Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

fix(vue): same src file request same key #8059

Merged
merged 6 commits into from
May 11, 2022
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
43 changes: 32 additions & 11 deletions packages/plugin-vue/src/main.ts
Original file line number Diff line number Diff line change
Expand Up @@ -227,6 +227,7 @@ async function genTemplateCode(
ssr: boolean
) {
const template = descriptor.template!
const hasScoped = descriptor.styles.some((style) => style.scoped)

// If the template is not using pre-processor AND is not using external src,
// compile and inline it directly in the main module. When served in vite this
Expand All @@ -241,12 +242,22 @@ async function genTemplateCode(
)
} else {
if (template.src) {
await linkSrcToDescriptor(template.src, descriptor, pluginContext)
await linkSrcToDescriptor(
template.src,
descriptor,
pluginContext,
hasScoped
)
}
const src = template.src || descriptor.filename
const srcQuery = template.src ? `&src=${descriptor.id}` : ``
const srcQuery = template.src
? hasScoped
? `&src=${descriptor.id}`
: '&src=true'
: ''
const scopedQuery = hasScoped ? `&scoped=true` : ``
const attrsQuery = attrsToQuery(template.attrs, 'js', true)
const query = `?vue&type=template${srcQuery}${attrsQuery}`
const query = `?vue&type=template${srcQuery}${scopedQuery}${attrsQuery}`
const request = JSON.stringify(src + query)
const renderFnName = ssr ? 'ssrRender' : 'render'
return {
Expand Down Expand Up @@ -281,12 +292,12 @@ async function genScriptCode(
map = script.map
} else {
if (script.src) {
await linkSrcToDescriptor(script.src, descriptor, pluginContext)
await linkSrcToDescriptor(script.src, descriptor, pluginContext, false)
}
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=${descriptor.id}` : ``
const srcQuery = script.src ? `&src=true` : ``
const query = `?vue&type=script${srcQuery}${attrsQuery}`
const request = JSON.stringify(src + query)
scriptCode =
Expand All @@ -311,13 +322,22 @@ async function genStyleCode(
for (let i = 0; i < descriptor.styles.length; i++) {
const style = descriptor.styles[i]
if (style.src) {
await linkSrcToDescriptor(style.src, descriptor, pluginContext)
await linkSrcToDescriptor(
style.src,
descriptor,
pluginContext,
style.scoped
)
}
const src = style.src || descriptor.filename
// 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=${descriptor.id}` : ``
const srcQuery = style.src
? style.scoped
? `&src=${descriptor.id}`
: '&src=true'
: ''
const directQuery = asCustomElement ? `&inline` : ``
const query = `?vue&type=style&index=${i}${srcQuery}${directQuery}`
const styleRequest = src + query + attrsQuery
Expand Down Expand Up @@ -387,11 +407,11 @@ async function genCustomBlockCode(
for (let index = 0; index < descriptor.customBlocks.length; index++) {
const block = descriptor.customBlocks[index]
if (block.src) {
await linkSrcToDescriptor(block.src, descriptor, pluginContext)
await linkSrcToDescriptor(block.src, descriptor, pluginContext, false)
}
const src = block.src || descriptor.filename
const attrsQuery = attrsToQuery(block.attrs, block.type)
const srcQuery = block.src ? `&src` : ``
const srcQuery = block.src ? `&src=true` : ``
const query = `?vue&type=${block.type}&index=${index}${srcQuery}${attrsQuery}`
const request = JSON.stringify(src + query)
code += `import block${index} from ${request}\n`
Expand All @@ -408,13 +428,14 @@ async function genCustomBlockCode(
async function linkSrcToDescriptor(
src: string,
descriptor: SFCDescriptor,
pluginContext: PluginContext
pluginContext: PluginContext,
scoped?: boolean
) {
const srcFile =
(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.
setSrcDescriptor(srcFile.replace(/\?.*$/, ''), descriptor)
setSrcDescriptor(srcFile.replace(/\?.*$/, ''), descriptor, scoped)
}

// these are built-in query parameters so should be ignored
Expand Down
21 changes: 16 additions & 5 deletions packages/plugin-vue/src/utils/descriptorCache.ts
Original file line number Diff line number Diff line change
Expand Up @@ -69,11 +69,22 @@ export function getSrcDescriptor(
filename: string,
query: VueQuery
): SFCDescriptor {
return cache.get(`${filename}?src=${query.src}`)!
if (query.scoped) {
return cache.get(`${filename}?src=${query.src}`)!
}
return cache.get(filename)!
}

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)
export function setSrcDescriptor(
filename: string,
entry: SFCDescriptor,
scoped?: boolean
): void {
if (scoped) {
// if multiple Vue files use the same src file, they will be overwritten
// should use other key
cache.set(`${filename}?src=${entry.id}`, entry)
return
}
cache.set(filename, entry)
}
4 changes: 4 additions & 0 deletions packages/plugin-vue/src/utils/query.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ export interface VueQuery {
index?: number
lang?: string
raw?: boolean
scoped?: boolean
}

export function parseVueRequest(id: string): {
Expand All @@ -22,6 +23,9 @@ export function parseVueRequest(id: string): {
if (query.raw != null) {
query.raw = true
}
if (query.scoped != null) {
query.scoped = true
}
return {
filename,
query
Expand Down
7 changes: 7 additions & 0 deletions playground/vue/src-import/css.module.css
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
.one {
background: yellow;
}

.two {
border: solid 1px red;
}
6 changes: 5 additions & 1 deletion playground/vue/src-import/script.ts
Original file line number Diff line number Diff line change
@@ -1,11 +1,15 @@
import { defineComponent } from 'vue'
import SrcImportStyle from './srcImportStyle.vue'
import SrcImportStyle2 from './srcImportStyle2.vue'
import SrcImportModuleStyle from './srcImportModuleStyle.vue'
import SrcImportModuleStyle2 from './srcImportModuleStyle2.vue'

export default defineComponent({
components: {
SrcImportStyle,
SrcImportStyle2
SrcImportStyle2,
SrcImportModuleStyle,
SrcImportModuleStyle2
},
setup() {
return {
Expand Down
4 changes: 4 additions & 0 deletions playground/vue/src-import/srcImportModuleStyle.vue
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
<template>
<div :class="$style.one">src for import css module</div>
</template>
<style lang="scss" module src="/@/src-import/css.module.css" />
4 changes: 4 additions & 0 deletions playground/vue/src-import/srcImportModuleStyle2.vue
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
<template>
<div :class="$style.two">src for import css module</div>
</template>
<style lang="scss" module src="/@/src-import/css.module.css" />
2 changes: 2 additions & 0 deletions playground/vue/src-import/template.html
Original file line number Diff line number Diff line change
Expand Up @@ -3,3 +3,5 @@ <h2>SFC Src Imports</h2>
<div class="src-imports-style">This should be tan</div>
<SrcImportStyle></SrcImportStyle>
<SrcImportStyle2></SrcImportStyle2>
<SrcImportModuleStyle></SrcImportModuleStyle>
<SrcImportModuleStyle2></SrcImportModuleStyle2>