Skip to content

Commit 7ef0acf

Browse files
committed
test: vue src imports
1 parent 03f24f2 commit 7ef0acf

File tree

3 files changed

+47
-35
lines changed

3 files changed

+47
-35
lines changed

packages/plugin-vue/src/index.ts

+6-26
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,7 @@ import {
1717
SFCTemplateCompileOptions
1818
} from '@vue/compiler-sfc'
1919
import { parseVueRequest } from './utils/query'
20-
import { getDescriptor, setDescriptor } from './utils/descriptorCache'
20+
import { getDescriptor } from './utils/descriptorCache'
2121
import { getResolvedScript } from './script'
2222
import { transformMain } from './main'
2323
import { handleHotUpdate } from './handleHotUpdate'
@@ -90,34 +90,15 @@ export default function vuePlugin(rawOptions: Options = {}): Plugin {
9090
},
9191

9292
async resolveId(id, importer) {
93-
const { filename, query } = parseVueRequest(id)
9493
// serve subpart requests (*?vue) as virtual modules
95-
if (query.vue) {
96-
if (query.src) {
97-
const resolved = await this.resolve(filename, importer, {
98-
skipSelf: true
99-
})
100-
if (resolved) {
101-
// associate this imported file to the importer SFC's descriptor
102-
// so that we can retrieve it in transform()
103-
setDescriptor(resolved.id, getDescriptor(importer!))
104-
const [, originalQuery] = id.split('?', 2)
105-
resolved.id += `?${originalQuery}`
106-
return resolved
107-
}
108-
} else if (!filter(filename)) {
109-
return null
110-
}
94+
if (parseVueRequest(id).query.vue) {
11195
return id
11296
}
11397
},
11498

11599
load(id) {
116100
const { filename, query } = parseVueRequest(id)
117-
if (!filter(filename)) {
118-
return
119-
}
120-
// serve subpart virtual modules
101+
// select corresponding block for subpart virtual modules
121102
if (query.vue) {
122103
if (query.src) {
123104
return fs.readFileSync(filename, 'utf-8')
@@ -145,16 +126,15 @@ export default function vuePlugin(rawOptions: Options = {}): Plugin {
145126

146127
transform(code, id) {
147128
const { filename, query } = parseVueRequest(id)
148-
if (!filter(filename)) {
129+
if (!query.vue && !filter(filename)) {
149130
return
150131
}
151132

152133
if (!query.vue) {
153134
// main request
154135
return transformMain(code, filename, options, this)
155-
}
156-
157-
if (query.vue) {
136+
} else {
137+
// sub block request
158138
const descriptor = getDescriptor(filename)
159139
if (query.type === 'template') {
160140
return transformTemplateAsModule(code, descriptor, options, this)

packages/plugin-vue/src/main.ts

+37-8
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,12 @@
11
import qs from 'querystring'
2+
import path from 'path'
23
import { rewriteDefault, SFCBlock, SFCDescriptor } from '@vue/compiler-sfc'
34
import { ResolvedOptions } from '.'
4-
import { createDescriptor, getPrevDescriptor } from './utils/descriptorCache'
5+
import {
6+
createDescriptor,
7+
getPrevDescriptor,
8+
setDescriptor
9+
} from './utils/descriptorCache'
510
import { PluginContext, TransformPluginContext } from 'rollup'
611
import { resolveScript } from './script'
712
import { transformTemplateInMain } from './template'
@@ -162,14 +167,16 @@ function genTemplateCode(
162167
pluginContext
163168
)
164169
} else {
170+
if (template.src) {
171+
linkSrcToDescriptor(template.src, descriptor)
172+
}
165173
const src = template.src || descriptor.filename
166174
const srcQuery = template.src ? `&src` : ``
167175
const attrsQuery = attrsToQuery(template.attrs, 'js', true)
168176
const query = `?vue&type=template${srcQuery}${attrsQuery}`
177+
const request = JSON.stringify(src + query)
169178
return {
170-
code: `import { ${renderFnName} as _sfc_${renderFnName} } from ${JSON.stringify(
171-
src + query
172-
)}`,
179+
code: `import { ${renderFnName} as _sfc_${renderFnName} } from ${request}`,
173180
map: undefined
174181
}
175182
}
@@ -205,14 +212,17 @@ async function genScriptCode(
205212
map = result.map
206213
}
207214
} else {
215+
if (script.src) {
216+
linkSrcToDescriptor(script.src, descriptor)
217+
}
208218
const src = script.src || descriptor.filename
209-
const attrsQuery = attrsToQuery(script.attrs, 'js')
219+
const langFallback = (script.src && path.extname(src).slice(1)) || 'js'
220+
const attrsQuery = attrsToQuery(script.attrs, langFallback)
210221
const srcQuery = script.src ? `&src` : ``
211222
const query = `?vue&type=script${srcQuery}${attrsQuery}`
212-
const scriptRequest = JSON.stringify(src + query)
223+
const request = JSON.stringify(src + query)
213224
scriptCode =
214-
`import _sfc_main from ${scriptRequest}\n` +
215-
`export * from ${scriptRequest}` // support named exports
225+
`import _sfc_main from ${request}\n` + `export * from ${request}` // support named exports
216226
}
217227
}
218228
return {
@@ -226,6 +236,9 @@ function genStyleCode(descriptor: SFCDescriptor) {
226236
let hasCSSModules = false
227237
if (descriptor.styles.length) {
228238
descriptor.styles.forEach((style, i) => {
239+
if (style.src) {
240+
linkSrcToDescriptor(style.src, descriptor)
241+
}
229242
const src = style.src || descriptor.filename
230243
// do not include module in default query, since we use it to indicate
231244
// that the module needs to export the modules json
@@ -251,6 +264,9 @@ function genStyleCode(descriptor: SFCDescriptor) {
251264
function genCustomBlockCode(descriptor: SFCDescriptor) {
252265
let code = ''
253266
descriptor.customBlocks.forEach((block, index) => {
267+
if (block.src) {
268+
linkSrcToDescriptor(block.src, descriptor)
269+
}
254270
const src = block.src || descriptor.filename
255271
const attrsQuery = attrsToQuery(block.attrs, block.type)
256272
const srcQuery = block.src ? `&src` : ``
@@ -277,6 +293,19 @@ function genCSSModulesCode(
277293
)
278294
}
279295

296+
/**
297+
* For blocks with src imports, it is important to link the imported file
298+
* with its owner SFC descriptor so that we can get the information about
299+
* the owner SFC when compiling that file in the transform phase.
300+
*/
301+
function linkSrcToDescriptor(src: string, descriptor: SFCDescriptor) {
302+
const srcFile = path.posix.resolve(
303+
path.posix.dirname(descriptor.filename),
304+
src
305+
)
306+
setDescriptor(srcFile, descriptor)
307+
}
308+
280309
// these are built-in query parameters so should be ignored
281310
// if the user happen to add them as attrs
282311
const ignoreList = ['id', 'index', 'src', 'type', 'lang', 'module']

packages/plugin-vue/src/utils/query.ts

+4-1
Original file line numberDiff line numberDiff line change
@@ -2,8 +2,8 @@ import qs from 'querystring'
22

33
export interface VueQuery {
44
vue?: boolean
5+
src?: boolean
56
type?: 'script' | 'template' | 'style' | 'custom'
6-
src?: string
77
index?: number
88
lang?: string
99
}
@@ -14,6 +14,9 @@ export function parseVueRequest(id: string) {
1414
if (query.vue != null) {
1515
query.vue = true
1616
}
17+
if (query.src != null) {
18+
query.src = true
19+
}
1720
if (query.index != null) {
1821
query.index = Number(query.index)
1922
}

0 commit comments

Comments
 (0)