]> git.ipfire.org Git - thirdparty/vuejs/core.git/commitdiff
feat(compiler-sfc): transform asset url (#500)
authorlikui <2218301630@qq.com>
Sun, 1 Dec 2019 17:02:53 +0000 (01:02 +0800)
committerEvan You <yyx990803@gmail.com>
Sun, 1 Dec 2019 17:02:53 +0000 (12:02 -0500)
packages/compiler-core/__tests__/__snapshots__/parse.spec.ts.snap
packages/compiler-core/__tests__/codegen.spec.ts
packages/compiler-core/src/ast.ts
packages/compiler-core/src/codegen.ts
packages/compiler-core/src/parse.ts
packages/compiler-core/src/transform.ts
packages/compiler-sfc/__tests__/__snapshots__/templateTransformAssetUrl.spec.ts.snap [new file with mode: 0644]
packages/compiler-sfc/__tests__/templateTransformAssetUrl.spec.ts [new file with mode: 0644]
packages/compiler-sfc/src/templateTransformAssetUrl.ts
packages/compiler-sfc/src/templateUtils.ts

index 40f635ff4359c77bdd971610507ed148e3a2182f..d2ec37c611b823f3a488b07bd2b089d344396cca 100644 (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,
index c356dbac71fa4c0de416578260fa98481b578570..2a116bb771fa210e1a29bdff6636e15099bb5c4c 100644 (file)
@@ -34,6 +34,7 @@ function createRoot(options: Partial<RootNode> = {}): RootNode {
     helpers: [],
     components: [],
     directives: [],
+    imports: [],
     hoists: [],
     cached: 0,
     codegenNode: createSimpleExpression(`null`, false),
index ebd7a605c83e2a2b47579742eb3e63ddb3404a18..7cbbd275323f1a458b5167d65fd4e764a7fcb9a8 100644 (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
 }
index d903d023cb82cd4f9f232d730217b03701ef20c9..649b5f623fd8432561356d5ae4826d09e826581f 100644 (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) ||
index a18675499fd54fbed89c2ff789e180b5fc02c1b9..99008e01b6e2fd86691065d9d659aec979b38a18 100644 (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)
index bfc69ee4f6fbf79af39ec49464242afc73c2c961..5038cee1c3ab28f28c582533ebbe43ac19a105f8 100644 (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
 }
diff --git a/packages/compiler-sfc/__tests__/__snapshots__/templateTransformAssetUrl.spec.ts.snap b/packages/compiler-sfc/__tests__/__snapshots__/templateTransformAssetUrl.spec.ts.snap
new file mode 100644 (file)
index 0000000..4004ddb
--- /dev/null
@@ -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 })
+  ]))
+}"
+`;
diff --git a/packages/compiler-sfc/__tests__/templateTransformAssetUrl.spec.ts b/packages/compiler-sfc/__tests__/templateTransformAssetUrl.spec.ts
new file mode 100644 (file)
index 0000000..a5e6405
--- /dev/null
@@ -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()
+  })
+})
index 3025bfa4817fc60cb1973940fa14631295f9696e..982c1981102013b781ec152333ed094d56e691a0 100644 (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)
+  }
 }
index 1ebb28946dec1d9ce66da970031633afefd961c3..7099b2841bf025c319a0a989be6f09a08fa53c5b 100644 (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)
 }
 
 /**