feat(compiler-sfc): transform asset url (#500)

This commit is contained in:
likui 2019-12-02 01:02:53 +08:00 committed by Evan You
parent 22957436e8
commit 810b3a3e2a
10 changed files with 294 additions and 19 deletions

View File

@ -51,6 +51,7 @@ Object {
"directives": Array [],
"helpers": Array [],
"hoists": Array [],
"imports": Array [],
"loc": Object {
"end": Object {
"column": 27,
@ -119,6 +120,7 @@ Object {
"directives": Array [],
"helpers": Array [],
"hoists": Array [],
"imports": Array [],
"loc": Object {
"end": Object {
"column": 28,
@ -187,6 +189,7 @@ Object {
"directives": Array [],
"helpers": Array [],
"hoists": Array [],
"imports": Array [],
"loc": Object {
"end": Object {
"column": 29,
@ -272,6 +275,7 @@ Object {
"directives": Array [],
"helpers": Array [],
"hoists": Array [],
"imports": Array [],
"loc": Object {
"end": Object {
"column": 35,
@ -357,6 +361,7 @@ Object {
"directives": Array [],
"helpers": Array [],
"hoists": Array [],
"imports": Array [],
"loc": Object {
"end": Object {
"column": 34,
@ -442,6 +447,7 @@ Object {
"directives": Array [],
"helpers": Array [],
"hoists": Array [],
"imports": Array [],
"loc": Object {
"end": Object {
"column": 36,
@ -527,6 +533,7 @@ Object {
"directives": Array [],
"helpers": Array [],
"hoists": Array [],
"imports": Array [],
"loc": Object {
"end": Object {
"column": 35,
@ -595,6 +602,7 @@ Object {
"directives": Array [],
"helpers": Array [],
"hoists": Array [],
"imports": Array [],
"loc": Object {
"end": Object {
"column": 27,
@ -663,6 +671,7 @@ Object {
"directives": Array [],
"helpers": Array [],
"hoists": Array [],
"imports": Array [],
"loc": Object {
"end": Object {
"column": 26,
@ -731,6 +740,7 @@ Object {
"directives": Array [],
"helpers": Array [],
"hoists": Array [],
"imports": Array [],
"loc": Object {
"end": Object {
"column": 28,
@ -799,6 +809,7 @@ Object {
"directives": Array [],
"helpers": Array [],
"hoists": Array [],
"imports": Array [],
"loc": Object {
"end": Object {
"column": 27,
@ -867,6 +878,7 @@ Object {
"directives": Array [],
"helpers": Array [],
"hoists": Array [],
"imports": Array [],
"loc": Object {
"end": Object {
"column": 39,
@ -959,6 +971,7 @@ Object {
"directives": Array [],
"helpers": Array [],
"hoists": Array [],
"imports": Array [],
"loc": Object {
"end": Object {
"column": 50,
@ -1027,6 +1040,7 @@ Object {
"directives": Array [],
"helpers": Array [],
"hoists": Array [],
"imports": Array [],
"loc": Object {
"end": Object {
"column": 32,
@ -1095,6 +1109,7 @@ Object {
"directives": Array [],
"helpers": Array [],
"hoists": Array [],
"imports": Array [],
"loc": Object {
"end": Object {
"column": 29,
@ -1163,6 +1178,7 @@ Object {
"directives": Array [],
"helpers": Array [],
"hoists": Array [],
"imports": Array [],
"loc": Object {
"end": Object {
"column": 28,
@ -1306,6 +1322,7 @@ Object {
"directives": Array [],
"helpers": Array [],
"hoists": Array [],
"imports": Array [],
"loc": Object {
"end": Object {
"column": 45,
@ -1380,6 +1397,7 @@ Object {
"directives": Array [],
"helpers": Array [],
"hoists": Array [],
"imports": Array [],
"loc": Object {
"end": Object {
"column": 39,
@ -1454,6 +1472,7 @@ Object {
"directives": Array [],
"helpers": Array [],
"hoists": Array [],
"imports": Array [],
"loc": Object {
"end": Object {
"column": 34,
@ -1522,6 +1541,7 @@ Object {
"directives": Array [],
"helpers": Array [],
"hoists": Array [],
"imports": Array [],
"loc": Object {
"end": Object {
"column": 12,
@ -1590,6 +1610,7 @@ Object {
"directives": Array [],
"helpers": Array [],
"hoists": Array [],
"imports": Array [],
"loc": Object {
"end": Object {
"column": 13,
@ -1664,6 +1685,7 @@ Object {
"directives": Array [],
"helpers": Array [],
"hoists": Array [],
"imports": Array [],
"loc": Object {
"end": Object {
"column": 25,
@ -1756,6 +1778,7 @@ Object {
"directives": Array [],
"helpers": Array [],
"hoists": Array [],
"imports": Array [],
"loc": Object {
"end": Object {
"column": 30,
@ -1824,6 +1847,7 @@ Object {
"directives": Array [],
"helpers": Array [],
"hoists": Array [],
"imports": Array [],
"loc": Object {
"end": Object {
"column": 13,
@ -1892,6 +1916,7 @@ Object {
"directives": Array [],
"helpers": Array [],
"hoists": Array [],
"imports": Array [],
"loc": Object {
"end": Object {
"column": 14,
@ -1960,6 +1985,7 @@ Object {
"directives": Array [],
"helpers": Array [],
"hoists": Array [],
"imports": Array [],
"loc": Object {
"end": Object {
"column": 15,
@ -2028,6 +2054,7 @@ Object {
"directives": Array [],
"helpers": Array [],
"hoists": Array [],
"imports": Array [],
"loc": Object {
"end": Object {
"column": 22,
@ -2096,6 +2123,7 @@ Object {
"directives": Array [],
"helpers": Array [],
"hoists": Array [],
"imports": Array [],
"loc": Object {
"end": Object {
"column": 16,
@ -2164,6 +2192,7 @@ Object {
"directives": Array [],
"helpers": Array [],
"hoists": Array [],
"imports": Array [],
"loc": Object {
"end": Object {
"column": 33,
@ -2232,6 +2261,7 @@ Object {
"directives": Array [],
"helpers": Array [],
"hoists": Array [],
"imports": Array [],
"loc": Object {
"end": Object {
"column": 29,
@ -2306,6 +2336,7 @@ Object {
"directives": Array [],
"helpers": Array [],
"hoists": Array [],
"imports": Array [],
"loc": Object {
"end": Object {
"column": 16,
@ -2380,6 +2411,7 @@ Object {
"directives": Array [],
"helpers": Array [],
"hoists": Array [],
"imports": Array [],
"loc": Object {
"end": Object {
"column": 15,
@ -2473,6 +2505,7 @@ Object {
"directives": Array [],
"helpers": Array [],
"hoists": Array [],
"imports": Array [],
"loc": Object {
"end": Object {
"column": 19,
@ -2566,6 +2599,7 @@ Object {
"directives": Array [],
"helpers": Array [],
"hoists": Array [],
"imports": Array [],
"loc": Object {
"end": Object {
"column": 20,
@ -2659,6 +2693,7 @@ Object {
"directives": Array [],
"helpers": Array [],
"hoists": Array [],
"imports": Array [],
"loc": Object {
"end": Object {
"column": 18,
@ -2768,6 +2803,7 @@ Object {
"directives": Array [],
"helpers": Array [],
"hoists": Array [],
"imports": Array [],
"loc": Object {
"end": Object {
"column": 23,
@ -2877,6 +2913,7 @@ Object {
"directives": Array [],
"helpers": Array [],
"hoists": Array [],
"imports": Array [],
"loc": Object {
"end": Object {
"column": 24,
@ -2986,6 +3023,7 @@ Object {
"directives": Array [],
"helpers": Array [],
"hoists": Array [],
"imports": Array [],
"loc": Object {
"end": Object {
"column": 25,
@ -3095,6 +3133,7 @@ Object {
"directives": Array [],
"helpers": Array [],
"hoists": Array [],
"imports": Array [],
"loc": Object {
"end": Object {
"column": 23,
@ -3204,6 +3243,7 @@ Object {
"directives": Array [],
"helpers": Array [],
"hoists": Array [],
"imports": Array [],
"loc": Object {
"end": Object {
"column": 24,
@ -3313,6 +3353,7 @@ Object {
"directives": Array [],
"helpers": Array [],
"hoists": Array [],
"imports": Array [],
"loc": Object {
"end": Object {
"column": 25,
@ -3422,6 +3463,7 @@ Object {
"directives": Array [],
"helpers": Array [],
"hoists": Array [],
"imports": Array [],
"loc": Object {
"end": Object {
"column": 24,
@ -3531,6 +3573,7 @@ Object {
"directives": Array [],
"helpers": Array [],
"hoists": Array [],
"imports": Array [],
"loc": Object {
"end": Object {
"column": 22,
@ -3599,6 +3642,7 @@ Object {
"directives": Array [],
"helpers": Array [],
"hoists": Array [],
"imports": Array [],
"loc": Object {
"end": Object {
"column": 37,
@ -3643,6 +3687,7 @@ Object {
"directives": Array [],
"helpers": Array [],
"hoists": Array [],
"imports": Array [],
"loc": Object {
"end": Object {
"column": 16,
@ -3711,6 +3756,7 @@ Object {
"directives": Array [],
"helpers": Array [],
"hoists": Array [],
"imports": Array [],
"loc": Object {
"end": Object {
"column": 25,
@ -3779,6 +3825,7 @@ Object {
"directives": Array [],
"helpers": Array [],
"hoists": Array [],
"imports": Array [],
"loc": Object {
"end": Object {
"column": 26,
@ -3847,6 +3894,7 @@ Object {
"directives": Array [],
"helpers": Array [],
"hoists": Array [],
"imports": Array [],
"loc": Object {
"end": Object {
"column": 41,
@ -3915,6 +3963,7 @@ Object {
"directives": Array [],
"helpers": Array [],
"hoists": Array [],
"imports": Array [],
"loc": Object {
"end": Object {
"column": 26,
@ -3983,6 +4032,7 @@ Object {
"directives": Array [],
"helpers": Array [],
"hoists": Array [],
"imports": Array [],
"loc": Object {
"end": Object {
"column": 25,
@ -4069,6 +4119,7 @@ Object {
"directives": Array [],
"helpers": Array [],
"hoists": Array [],
"imports": Array [],
"loc": Object {
"end": Object {
"column": 31,
@ -4137,6 +4188,7 @@ Object {
"directives": Array [],
"helpers": Array [],
"hoists": Array [],
"imports": Array [],
"loc": Object {
"end": Object {
"column": 27,
@ -4222,6 +4274,7 @@ Object {
"directives": Array [],
"helpers": Array [],
"hoists": Array [],
"imports": Array [],
"loc": Object {
"end": Object {
"column": 28,
@ -4331,6 +4384,7 @@ Object {
"directives": Array [],
"helpers": Array [],
"hoists": Array [],
"imports": Array [],
"loc": Object {
"end": Object {
"column": 39,
@ -4424,6 +4478,7 @@ Object {
"directives": Array [],
"helpers": Array [],
"hoists": Array [],
"imports": Array [],
"loc": Object {
"end": Object {
"column": 38,
@ -4517,6 +4572,7 @@ Object {
"directives": Array [],
"helpers": Array [],
"hoists": Array [],
"imports": Array [],
"loc": Object {
"end": Object {
"column": 37,
@ -4567,6 +4623,7 @@ Object {
"directives": Array [],
"helpers": Array [],
"hoists": Array [],
"imports": Array [],
"loc": Object {
"end": Object {
"column": 25,
@ -4635,6 +4692,7 @@ Object {
"directives": Array [],
"helpers": Array [],
"hoists": Array [],
"imports": Array [],
"loc": Object {
"end": Object {
"column": 26,
@ -4703,6 +4761,7 @@ Object {
"directives": Array [],
"helpers": Array [],
"hoists": Array [],
"imports": Array [],
"loc": Object {
"end": Object {
"column": 27,
@ -4771,6 +4830,7 @@ Object {
"directives": Array [],
"helpers": Array [],
"hoists": Array [],
"imports": Array [],
"loc": Object {
"end": Object {
"column": 26,
@ -4916,6 +4976,7 @@ class=\\"bar\\"></div></template>",
"directives": Array [],
"helpers": Array [],
"hoists": Array [],
"imports": Array [],
"loc": Object {
"end": Object {
"column": 30,
@ -5060,6 +5121,7 @@ Object {
"directives": Array [],
"helpers": Array [],
"hoists": Array [],
"imports": Array [],
"loc": Object {
"end": Object {
"column": 53,
@ -5128,6 +5190,7 @@ Object {
"directives": Array [],
"helpers": Array [],
"hoists": Array [],
"imports": Array [],
"loc": Object {
"end": Object {
"column": 20,
@ -5196,6 +5259,7 @@ Object {
"directives": Array [],
"helpers": Array [],
"hoists": Array [],
"imports": Array [],
"loc": Object {
"end": Object {
"column": 32,
@ -5264,6 +5328,7 @@ Object {
"directives": Array [],
"helpers": Array [],
"hoists": Array [],
"imports": Array [],
"loc": Object {
"end": Object {
"column": 40,
@ -5332,6 +5397,7 @@ Object {
"directives": Array [],
"helpers": Array [],
"hoists": Array [],
"imports": Array [],
"loc": Object {
"end": Object {
"column": 35,
@ -5400,6 +5466,7 @@ Object {
"directives": Array [],
"helpers": Array [],
"hoists": Array [],
"imports": Array [],
"loc": Object {
"end": Object {
"column": 31,
@ -5468,6 +5535,7 @@ Object {
"directives": Array [],
"helpers": Array [],
"hoists": Array [],
"imports": Array [],
"loc": Object {
"end": Object {
"column": 30,
@ -5536,6 +5604,7 @@ Object {
"directives": Array [],
"helpers": Array [],
"hoists": Array [],
"imports": Array [],
"loc": Object {
"end": Object {
"column": 29,
@ -5604,6 +5673,7 @@ Object {
"directives": Array [],
"helpers": Array [],
"hoists": Array [],
"imports": Array [],
"loc": Object {
"end": Object {
"column": 30,
@ -5713,6 +5783,7 @@ Object {
"directives": Array [],
"helpers": Array [],
"hoists": Array [],
"imports": Array [],
"loc": Object {
"end": Object {
"column": 41,
@ -5822,6 +5893,7 @@ Object {
"directives": Array [],
"helpers": Array [],
"hoists": Array [],
"imports": Array [],
"loc": Object {
"end": Object {
"column": 41,
@ -5931,6 +6003,7 @@ Object {
"directives": Array [],
"helpers": Array [],
"hoists": Array [],
"imports": Array [],
"loc": Object {
"end": Object {
"column": 41,
@ -6040,6 +6113,7 @@ Object {
"directives": Array [],
"helpers": Array [],
"hoists": Array [],
"imports": Array [],
"loc": Object {
"end": Object {
"column": 42,
@ -6149,6 +6223,7 @@ Object {
"directives": Array [],
"helpers": Array [],
"hoists": Array [],
"imports": Array [],
"loc": Object {
"end": Object {
"column": 42,
@ -6258,6 +6333,7 @@ Object {
"directives": Array [],
"helpers": Array [],
"hoists": Array [],
"imports": Array [],
"loc": Object {
"end": Object {
"column": 45,
@ -6367,6 +6443,7 @@ Object {
"directives": Array [],
"helpers": Array [],
"hoists": Array [],
"imports": Array [],
"loc": Object {
"end": Object {
"column": 45,
@ -6476,6 +6553,7 @@ Object {
"directives": Array [],
"helpers": Array [],
"hoists": Array [],
"imports": Array [],
"loc": Object {
"end": Object {
"column": 42,
@ -6569,6 +6647,7 @@ Object {
"directives": Array [],
"helpers": Array [],
"hoists": Array [],
"imports": Array [],
"loc": Object {
"end": Object {
"column": 35,
@ -6678,6 +6757,7 @@ Object {
"directives": Array [],
"helpers": Array [],
"hoists": Array [],
"imports": Array [],
"loc": Object {
"end": Object {
"column": 42,
@ -6746,6 +6826,7 @@ Object {
"directives": Array [],
"helpers": Array [],
"hoists": Array [],
"imports": Array [],
"loc": Object {
"end": Object {
"column": 29,
@ -6857,6 +6938,7 @@ Object {
"directives": Array [],
"helpers": Array [],
"hoists": Array [],
"imports": Array [],
"loc": Object {
"end": Object {
"column": 37,
@ -6925,6 +7007,7 @@ Object {
"directives": Array [],
"helpers": Array [],
"hoists": Array [],
"imports": Array [],
"loc": Object {
"end": Object {
"column": 31,
@ -6993,6 +7076,7 @@ Object {
"directives": Array [],
"helpers": Array [],
"hoists": Array [],
"imports": Array [],
"loc": Object {
"end": Object {
"column": 30,
@ -7061,6 +7145,7 @@ Object {
"directives": Array [],
"helpers": Array [],
"hoists": Array [],
"imports": Array [],
"loc": Object {
"end": Object {
"column": 25,
@ -7111,6 +7196,7 @@ Object {
"directives": Array [],
"helpers": Array [],
"hoists": Array [],
"imports": Array [],
"loc": Object {
"end": Object {
"column": 34,
@ -7161,6 +7247,7 @@ Object {
"directives": Array [],
"helpers": Array [],
"hoists": Array [],
"imports": Array [],
"loc": Object {
"end": Object {
"column": 28,
@ -7247,6 +7334,7 @@ Object {
"directives": Array [],
"helpers": Array [],
"hoists": Array [],
"imports": Array [],
"loc": Object {
"end": Object {
"column": 34,
@ -7315,6 +7403,7 @@ Object {
"directives": Array [],
"helpers": Array [],
"hoists": Array [],
"imports": Array [],
"loc": Object {
"end": Object {
"column": 28,
@ -7422,6 +7511,7 @@ Object {
"directives": Array [],
"helpers": Array [],
"hoists": Array [],
"imports": Array [],
"loc": Object {
"end": Object {
"column": 25,
@ -7496,6 +7586,7 @@ Object {
"directives": Array [],
"helpers": Array [],
"hoists": Array [],
"imports": Array [],
"loc": Object {
"end": Object {
"column": 16,
@ -7570,6 +7661,7 @@ Object {
"directives": Array [],
"helpers": Array [],
"hoists": Array [],
"imports": Array [],
"loc": Object {
"end": Object {
"column": 27,
@ -7614,6 +7706,7 @@ Object {
"directives": Array [],
"helpers": Array [],
"hoists": Array [],
"imports": Array [],
"loc": Object {
"end": Object {
"column": 3,
@ -7658,6 +7751,7 @@ Object {
"directives": Array [],
"helpers": Array [],
"hoists": Array [],
"imports": Array [],
"loc": Object {
"end": Object {
"column": 7,
@ -7720,6 +7814,7 @@ Object {
"directives": Array [],
"helpers": Array [],
"hoists": Array [],
"imports": Array [],
"loc": Object {
"end": Object {
"column": 5,
@ -7797,6 +7892,7 @@ Object {
"directives": Array [],
"helpers": Array [],
"hoists": Array [],
"imports": Array [],
"loc": Object {
"end": Object {
"column": 8,
@ -7987,6 +8083,7 @@ Object {
"directives": Array [],
"helpers": Array [],
"hoists": Array [],
"imports": Array [],
"loc": Object {
"end": Object {
"column": 37,
@ -8196,6 +8293,7 @@ Object {
"directives": Array [],
"helpers": Array [],
"hoists": Array [],
"imports": Array [],
"loc": Object {
"end": Object {
"column": 7,

View File

@ -34,6 +34,7 @@ function createRoot(options: Partial<RootNode> = {}): RootNode {
helpers: [],
components: [],
directives: [],
imports: [],
hoists: [],
cached: 0,
codegenNode: createSimpleExpression(`null`, false),

View File

@ -11,6 +11,7 @@ import {
FRAGMENT
} from './runtimeHelpers'
import { PropsExpression } from './transforms/transformElement'
import { ImportsOption } from './transform'
// Vue template is a platform-agnostic superset of HTML (syntax only).
// More namespaces like SVG and MathML are declared by platform specific
@ -94,6 +95,7 @@ export interface RootNode extends Node {
components: string[]
directives: string[]
hoists: JSChildNode[]
imports: ImportsOption[]
cached: number
codegenNode: TemplateChildNode | JSChildNode | undefined
}

View File

@ -38,6 +38,7 @@ import {
CREATE_COMMENT,
CREATE_TEXT
} from './runtimeHelpers'
import { ImportsOption } from './transform'
type CodegenNode = TemplateChildNode | JSChildNode
@ -229,6 +230,10 @@ export function generate(
if (hasHelpers) {
push(`import { ${ast.helpers.map(helper).join(', ')} } from "vue"\n`)
}
if (ast.imports.length) {
genImports(ast.imports, context)
newline()
}
genHoists(ast.hoists, context)
newline()
push(`export default `)
@ -327,6 +332,18 @@ function genHoists(hoists: JSChildNode[], context: CodegenContext) {
})
}
function genImports(importsOptions: ImportsOption[], context: CodegenContext) {
if (!importsOptions.length) {
return
}
importsOptions.forEach(imports => {
context.push(`import `)
genNode(imports.exp, context)
context.push(` from '${imports.path}'`)
context.newline()
})
}
function isText(n: string | CodegenNode) {
return (
isString(n) ||

View File

@ -103,6 +103,7 @@ export function parse(content: string, options: ParserOptions = {}): RootNode {
components: [],
directives: [],
hoists: [],
imports: [],
cached: 0,
codegenNode: undefined,
loc: getSelection(context, start)

View File

@ -75,12 +75,18 @@ export interface TransformOptions {
onError?: (error: CompilerError) => void
}
export interface ImportsOption {
exp: string | ExpressionNode
path: string
}
export interface TransformContext extends Required<TransformOptions> {
root: RootNode
helpers: Set<symbol>
components: Set<string>
directives: Set<string>
hoists: JSChildNode[]
imports: Set<ImportsOption>
cached: number
identifiers: { [name: string]: number | undefined }
scopes: {
@ -121,6 +127,7 @@ function createTransformContext(
components: new Set(),
directives: new Set(),
hoists: [],
imports: new Set(),
cached: 0,
identifiers: {},
scopes: {
@ -296,6 +303,7 @@ function finalizeRoot(root: RootNode, context: TransformContext) {
root.helpers = [...context.helpers]
root.components = [...context.components]
root.directives = [...context.directives]
root.imports = [...context.imports]
root.hoists = context.hoists
root.cached = context.cached
}

View File

@ -0,0 +1,39 @@
// Jest Snapshot v1, https://goo.gl/fbAQLP
exports[`compiler sfc: transform asset url support uri fragment 1`] = `
"import { createVNode, createBlock, openBlock } from \\"vue\\"
import _imports_0 from '@svg/file.svg'
const _hoisted_1 = _imports_0 + '#fragment'
export default function render() {
const _ctx = this
return (openBlock(), createBlock(\\"use\\", { href: _hoisted_1 }))
}"
`;
exports[`compiler sfc: transform asset url support uri is empty 1`] = `
"import { createVNode, createBlock, openBlock } from \\"vue\\"
export default function render() {
const _ctx = this
return (openBlock(), createBlock(\\"use\\", { href: '' }))
}"
`;
exports[`compiler sfc: transform asset url transform assetUrls 1`] = `
"import { createVNode, createBlock, Fragment, openBlock } from \\"vue\\"
import _imports_0 from './logo.png'
import _imports_1 from 'fixtures/logo.png'
export default function render() {
const _ctx = this
return (openBlock(), createBlock(Fragment, null, [
createVNode(\\"img\\", { src: _imports_0 }),
createVNode(\\"img\\", { src: _imports_1 }),
createVNode(\\"img\\", { src: _imports_1 })
]))
}"
`;

View File

@ -0,0 +1,47 @@
import { generate, parse, transform } from '@vue/compiler-core'
import { transformAssetUrl } from '../src/templateTransformAssetUrl'
import { transformElement } from '../../compiler-core/src/transforms/transformElement'
import { transformBind } from '../../compiler-core/src/transforms/vBind'
function compileWithAssetUrls(template: string) {
const ast = parse(template)
transform(ast, {
nodeTransforms: [transformAssetUrl, transformElement],
directiveTransforms: {
bind: transformBind
}
})
return generate(ast, { mode: 'module' })
}
describe('compiler sfc: transform asset url', () => {
test('transform assetUrls', () => {
const result = compileWithAssetUrls(`
<img src="./logo.png"/>
<img src="~fixtures/logo.png"/>
<img src="~/fixtures/logo.png"/>
`)
expect(result.code).toMatchSnapshot()
})
/**
* vuejs/component-compiler-utils#22 Support uri fragment in transformed require
*/
test('support uri fragment', () => {
const result = compileWithAssetUrls(
'<use href="~@svg/file.svg#fragment"></use>'
)
expect(result.code).toMatchSnapshot()
})
/**
* vuejs/component-compiler-utils#22 Support uri fragment in transformed require
*/
test('support uri is empty', () => {
const result = compileWithAssetUrls('<use href="~"></use>')
expect(result.code).toMatchSnapshot()
})
})

View File

@ -1,5 +1,81 @@
import { NodeTransform } from '@vue/compiler-core'
import {
AttributeNode,
createSimpleExpression,
ExpressionNode,
NodeTransform,
NodeTypes,
SourceLocation,
TransformContext
} from '@vue/compiler-core'
import { parseUrl } from './templateUtils'
export const transformAssetUrl: NodeTransform = () => {
// TODO
export interface AssetURLOptions {
[name: string]: string[]
}
const assetURLOptions: AssetURLOptions = {
video: ['src', 'poster'],
source: ['src'],
img: ['src'],
image: ['xlink:href', 'href'],
use: ['xlink:href', 'href']
}
export const transformAssetUrl: NodeTransform = (node, context) => {
if (node.type === NodeTypes.ELEMENT) {
for (const tag in assetURLOptions) {
if ((tag === '*' || node.tag === tag) && node.props.length) {
const attributes = assetURLOptions[tag]
attributes.forEach(item => {
node.props.forEach((attr: AttributeNode, index) => {
if (attr.type !== NodeTypes.ATTRIBUTE) return
if (attr.name !== item) return
if (!attr.value) return
const url = parseUrl(attr.value.content)
const exp = getImportsExpressionExp(
url.path,
url.hash,
attr.loc,
context
)
node.props[index] = {
type: NodeTypes.DIRECTIVE,
name: 'bind',
arg: createSimpleExpression(item, true, attr.loc),
exp,
modifiers: [],
loc: attr.loc
}
})
})
}
}
}
}
function getImportsExpressionExp(
path: string | undefined,
hash: string | undefined,
loc: SourceLocation,
context: TransformContext
): ExpressionNode {
if (path) {
const importsArray = Array.from(context.imports)
const existing = importsArray.find(i => i.path === path)
if (existing) {
return existing.exp as ExpressionNode
}
const name = `_imports_${importsArray.length}`
const exp = createSimpleExpression(name, false, loc, true)
context.imports.add({ exp, path })
if (hash && path) {
return context.hoist(
createSimpleExpression(`${name} + '${hash}'`, false, loc, true)
)
} else {
return exp
}
} else {
return createSimpleExpression(`''`, false, loc, true)
}
}

View File

@ -1,30 +1,16 @@
import { UrlWithStringQuery, parse as uriParse } from 'url'
// TODO use imports instead.
// We need an extra transform context API for injecting arbitrary import
// statements.
export function urlToRequire(url: string): string {
const returnValue = `"${url}"`
export function parseUrl(url: string): UrlWithStringQuery {
const firstChar = url.charAt(0)
if (firstChar === '.' || firstChar === '~' || firstChar === '@') {
if (firstChar === '~') {
const secondChar = url.charAt(1)
url = url.slice(secondChar === '/' ? 2 : 1)
}
const uriParts = parseUriParts(url)
if (!uriParts.hash) {
return `require("${url}")`
} else {
// support uri fragment case by excluding it from
// the require and instead appending it as string;
// assuming that the path part is sufficient according to
// the above caseing(t.i. no protocol-auth-host parts expected)
return `require("${uriParts.path}") + "${uriParts.hash}"`
}
}
return returnValue
return parseUriParts(url)
}
/**