]> git.ipfire.org Git - thirdparty/vuejs/core.git/commitdiff
wip: fix useCssVars helper call + tests
authorEvan You <yyx990803@gmail.com>
Mon, 16 Nov 2020 16:35:30 +0000 (11:35 -0500)
committerEvan You <yyx990803@gmail.com>
Mon, 16 Nov 2020 16:35:38 +0000 (11:35 -0500)
packages/compiler-sfc/__tests__/__snapshots__/compileScript.spec.ts.snap
packages/compiler-sfc/__tests__/compileScript.spec.ts
packages/compiler-sfc/src/compileScript.ts
packages/compiler-sfc/src/genCssVars.ts

index a6db4207344b334765bafa6786bfbbe1f7cf92be..baac4d5815ddbc65d079314037c55dd0a7fe9fea 100644 (file)
@@ -2,9 +2,9 @@
 
 exports[`SFC compile <script setup> CSS vars injection <script> w/ default export 1`] = `
 "const __default__ = { setup() {} }
-import { useCssVars as __useCssVars__ } from 'vue'
+import { useCssVars as _useCssVars } from 'vue'
 const __injectCSSVars__ = () => {
-__useCssVars__(_ctx => ({ color: _ctx.color }))
+_useCssVars(_ctx => ({ color: _ctx.color }))
 }
 const __setup__ = __default__.setup
 __default__.setup = __setup__
@@ -18,9 +18,9 @@ exports[`SFC compile <script setup> CSS vars injection <script> w/ default expor
           // export default {}
           const __default__ = {}
         
-import { useCssVars as __useCssVars__ } from 'vue'
+import { useCssVars as _useCssVars } from 'vue'
 const __injectCSSVars__ = () => {
-__useCssVars__(_ctx => ({ color: _ctx.color }))
+_useCssVars(_ctx => ({ color: _ctx.color }))
 }
 const __setup__ = __default__.setup
 __default__.setup = __setup__
@@ -32,9 +32,9 @@ export default __default__"
 exports[`SFC compile <script setup> CSS vars injection <script> w/ no default export 1`] = `
 "const a = 1
 const __default__ = {}
-import { useCssVars as __useCssVars__ } from 'vue'
+import { useCssVars as _useCssVars } from 'vue'
 const __injectCSSVars__ = () => {
-__useCssVars__(_ctx => ({ color: _ctx.color }))
+_useCssVars(_ctx => ({ color: _ctx.color }))
 }
 const __setup__ = __default__.setup
 __default__.setup = __setup__
@@ -44,12 +44,13 @@ export default __default__"
 `;
 
 exports[`SFC compile <script setup> CSS vars injection w/ <script setup> 1`] = `
-"import { useCssVars } from 'vue'
+"import { useCssVars as _useCssVars } from 'vue'
 
 export default {
+  expose: [],
   setup() {
 const color = 'red'
-__useCssVars__(_ctx => ({ color }))
+_useCssVars(_ctx => ({ color }))
 return { color }
 }
 
@@ -58,6 +59,7 @@ return { color }
 
 exports[`SFC compile <script setup> defineOptions() 1`] = `
 "export default {
+  expose: [],
   props: {
     foo: String
   },
@@ -78,6 +80,7 @@ exports[`SFC compile <script setup> errors should allow defineOptions() referenc
 "import { bar } from './bar'
           
 export default {
+  expose: [],
   props: {
               foo: {
                 default: () => bar
@@ -95,6 +98,7 @@ return { bar }
 
 exports[`SFC compile <script setup> errors should allow defineOptions() referencing scope var 1`] = `
 "export default {
+  expose: [],
   props: {
               foo: {
                 default: bar => bar + 1
@@ -112,12 +116,14 @@ return { bar }
 `;
 
 exports[`SFC compile <script setup> imports dedupe between user & helper 1`] = `
-"import { ref } from 'vue'
+"import { ref as _ref } from 'vue'
+import { ref } from 'vue'
       
 export default {
+  expose: [],
   setup() {
 
-      const foo = ref(1)
+      const foo = _ref(1)
       
 return { foo, ref }
 }
@@ -129,6 +135,7 @@ exports[`SFC compile <script setup> imports import dedupe between <script> and <
 "import { x } from './x'
         
 export default {
+  expose: [],
   setup() {
 
         x()
@@ -144,6 +151,7 @@ exports[`SFC compile <script setup> imports should extract comment for import or
         import b from 'b'
         
 export default {
+  expose: [],
   setup() {
 
         
@@ -156,6 +164,7 @@ return { a, b }
 exports[`SFC compile <script setup> imports should hoist and expose imports 1`] = `
 "import { ref } from 'vue'
 export default {
+  expose: [],
   setup() {
 
 return { ref }
@@ -172,6 +181,7 @@ import { ref } from 'vue'
         import other from './util'
         
 export default {
+  expose: [],
   setup() {
 
         const count = ref(0)
@@ -197,6 +207,7 @@ const _hoisted_1 = /*#__PURE__*/_createVNode(\\"div\\", null, \\"static\\", -1 /
 import { ref } from 'vue'
         
 export default {
+  expose: [],
   setup() {
 
         const count = ref(0)
@@ -213,12 +224,13 @@ return (_ctx, _cache, $props, $setup, $data, $options) => {
 `;
 
 exports[`SFC compile <script setup> ref: syntax sugar accessing ref binding 1`] = `
-"import { ref } from 'vue'
+"import { ref as _ref } from 'vue'
 
 export default {
+  expose: [],
   setup() {
 
-      const a = ref(1)
+      const a = _ref(1)
       console.log(a.value)
       function get() {
         return a.value + 1
@@ -231,15 +243,16 @@ return { a, get }
 `;
 
 exports[`SFC compile <script setup> ref: syntax sugar array destructure 1`] = `
-"import { ref } from 'vue'
+"import { ref as _ref } from 'vue'
 
 export default {
+  expose: [],
   setup() {
 
-      const n = ref(1), [__a, __b = 1, ...__c] = useFoo()
-const a = ref(__a);
-const b = ref(__b);
-const c = ref(__c);
+      const n = _ref(1), [__a, __b = 1, ...__c] = useFoo()
+const a = _ref(__a);
+const b = _ref(__b);
+const c = _ref(__c);
       console.log(n.value, a.value, b.value, c.value)
       
 return { n, a, b, c }
@@ -249,14 +262,15 @@ return { n, a, b, c }
 `;
 
 exports[`SFC compile <script setup> ref: syntax sugar convert ref declarations 1`] = `
-"import { ref } from 'vue'
+"import { ref as _ref } from 'vue'
 
 export default {
+  expose: [],
   setup() {
 
-      const foo = ref()
-      const a = ref(1)
-      const b = ref({
+      const foo = _ref()
+      const a = _ref(1)
+      const b = _ref({
         count: 0
       })
       let c = () => {}
@@ -269,12 +283,13 @@ return { foo, a, b, c, d }
 `;
 
 exports[`SFC compile <script setup> ref: syntax sugar multi ref declarations 1`] = `
-"import { ref } from 'vue'
+"import { ref as _ref } from 'vue'
 
 export default {
+  expose: [],
   setup() {
 
-      const a = ref(1), b = ref(2), c = ref({
+      const a = _ref(1), b = _ref(2), c = _ref({
         count: 0
       })
       
@@ -285,13 +300,14 @@ return { a, b, c }
 `;
 
 exports[`SFC compile <script setup> ref: syntax sugar mutating ref binding 1`] = `
-"import { ref } from 'vue'
+"import { ref as _ref } from 'vue'
 
 export default {
+  expose: [],
   setup() {
 
-      const a = ref(1)
-      const b = ref({ count: 0 })
+      const a = _ref(1)
+      const b = _ref({ count: 0 })
       function inc() {
         a.value++
         a.value = a.value + 1
@@ -306,16 +322,17 @@ return { a, b, inc }
 `;
 
 exports[`SFC compile <script setup> ref: syntax sugar nested destructure 1`] = `
-"import { ref } from 'vue'
+"import { ref as _ref } from 'vue'
 
 export default {
+  expose: [],
   setup() {
 
       const [{ a: { b: __b }}] = useFoo()
-const b = ref(__b);
+const b = _ref(__b);
       const { c: [__d, __e] } = useBar()
-const d = ref(__d);
-const e = ref(__e);
+const d = _ref(__d);
+const e = _ref(__e);
       console.log(b.value, d.value, e.value)
       
 return { b, d, e }
@@ -325,17 +342,18 @@ return { b, d, e }
 `;
 
 exports[`SFC compile <script setup> ref: syntax sugar object destructure 1`] = `
-"import { ref } from 'vue'
+"import { ref as _ref } from 'vue'
 
 export default {
+  expose: [],
   setup() {
 
-      const n = ref(1), { a: __a, b: __c, d: __d = 1, e: __f = 2, ...__g } = useFoo()
-const a = ref(__a);
-const c = ref(__c);
-const d = ref(__d);
-const f = ref(__f);
-const g = ref(__g);
+      const n = _ref(1), { a: __a, b: __c, d: __d = 1, e: __f = 2, ...__g } = useFoo()
+const a = _ref(__a);
+const c = _ref(__c);
+const d = _ref(__d);
+const f = _ref(__f);
+const g = _ref(__g);
       console.log(n.value, a.value, c.value, d.value, f.value, g.value)
       
 return { n, a, c, d, f, g }
@@ -346,6 +364,7 @@ return { n, a, c, d, f, g }
 
 exports[`SFC compile <script setup> ref: syntax sugar should not convert non ref labels 1`] = `
 "export default {
+  expose: [],
   setup() {
 
       foo: a = 1, b = 2, c = {
@@ -359,12 +378,13 @@ return {  }
 `;
 
 exports[`SFC compile <script setup> ref: syntax sugar using ref binding in property shorthand 1`] = `
-"import { ref } from 'vue'
+"import { ref as _ref } from 'vue'
 
 export default {
+  expose: [],
   setup() {
 
-      const a = ref(1)
+      const a = _ref(1)
       const b = { a: a.value }
       function test() {
         const { a } = b
@@ -380,6 +400,7 @@ exports[`SFC compile <script setup> should expose top level declarations 1`] = `
 "import { x } from './x'
       
 export default {
+  expose: [],
   setup() {
 
       let a = 1
@@ -394,10 +415,11 @@ return { a, b, c, d, x }
 `;
 
 exports[`SFC compile <script setup> with TypeScript defineOptions w/ runtime options 1`] = `
-"import { defineComponent } from 'vue'
+"import { defineComponent as _defineComponent } from 'vue'
 
 
-export default defineComponent({
+export default _defineComponent({
+  expose: [],
   props: { foo: String },
   emits: ['a', 'b'],
   setup(__props, { props, emit }) {
@@ -411,10 +433,11 @@ return { props, emit }
 `;
 
 exports[`SFC compile <script setup> with TypeScript defineOptions w/ type / extract emits (union) 1`] = `
-"import { SlotsdefineComponent } from 'vue'
+"import { Slots as _Slots, defineComponent as _defineComponent } from 'vue'
 
       
-export default defineComponent({
+export default _defineComponent({
+  expose: [],
   emits: [\\"foo\\", \\"bar\\", \\"baz\\"] as unknown as undefined,
   setup(__props, { emit }: {
   props: {},
@@ -432,10 +455,11 @@ return { emit }
 `;
 
 exports[`SFC compile <script setup> with TypeScript defineOptions w/ type / extract emits 1`] = `
-"import { SlotsdefineComponent } from 'vue'
+"import { Slots as _Slots, defineComponent as _defineComponent } from 'vue'
 
       
-export default defineComponent({
+export default _defineComponent({
+  expose: [],
   emits: [\\"foo\\", \\"bar\\"] as unknown as undefined,
   setup(__props, { emit }: {
   props: {},
@@ -453,14 +477,15 @@ return { emit }
 `;
 
 exports[`SFC compile <script setup> with TypeScript defineOptions w/ type / extract props 1`] = `
-"import { defineComponent } from 'vue'
+"import { defineComponent as _defineComponent } from 'vue'
 
       interface Test {}
 
       type Alias = number[]
 
       
-export default defineComponent({
+export default _defineComponent({
+  expose: [],
   props: {
     string: { type: String, required: true },
     number: { type: Number, required: true },
@@ -495,11 +520,12 @@ return {  }
 `;
 
 exports[`SFC compile <script setup> with TypeScript hoist type declarations 1`] = `
-"import { defineComponent } from 'vue'
+"import { defineComponent as _defineComponent } from 'vue'
 export interface Foo {}
         type Bar = {}
       
-export default defineComponent({
+export default _defineComponent({
+  expose: [],
   setup() {
 
         
index 958e81ec46a798cf452daf59877492d64fdf8ba3..5a8e24c4ea3c3386c43c952f6ab3fee89c60ab80 100644 (file)
@@ -66,6 +66,7 @@ const bar = 1
     expect(content).toMatch(`setup(__props, { props, emit }) {`)
     // should include context options in default export
     expect(content).toMatch(`export default {
+  expose: [],
   props: {
     foo: String
   },
@@ -194,7 +195,8 @@ const { props, emit } = defineOptions({
 </script>
       `)
       assertCode(content)
-      expect(content).toMatch(`export default defineComponent({
+      expect(content).toMatch(`export default _defineComponent({
+  expose: [],
   props: { foo: String },
   emits: ['a', 'b'],
   setup(__props, { props, emit }) {`)
@@ -410,14 +412,14 @@ const { props, emit } = defineOptions({
       let c = () => {}
       let d
       </script>`)
-      expect(content).toMatch(`import { ref } from 'vue'`)
+      expect(content).toMatch(`import { ref as _ref } from 'vue'`)
       expect(content).not.toMatch(`ref: foo`)
       expect(content).not.toMatch(`ref: a`)
       expect(content).not.toMatch(`ref: b`)
-      expect(content).toMatch(`const foo = ref()`)
-      expect(content).toMatch(`const a = ref(1)`)
+      expect(content).toMatch(`const foo = _ref()`)
+      expect(content).toMatch(`const a = _ref(1)`)
       expect(content).toMatch(`
-      const b = ref({
+      const b = _ref({
         count: 0
       })
       `)
@@ -441,7 +443,7 @@ const { props, emit } = defineOptions({
       }
       </script>`)
       expect(content).toMatch(`
-      const a = ref(1), b = ref(2), c = ref({
+      const a = _ref(1), b = _ref(2), c = _ref({
         count: 0
       })
       `)
@@ -526,15 +528,15 @@ const { props, emit } = defineOptions({
       console.log(n, a, c, d, f, g)
       </script>`)
       expect(content).toMatch(
-        `const n = ref(1), { a: __a, b: __c, d: __d = 1, e: __f = 2, ...__g } = useFoo()`
+        `const n = _ref(1), { a: __a, b: __c, d: __d = 1, e: __f = 2, ...__g } = useFoo()`
       )
-      expect(content).toMatch(`\nconst a = ref(__a);`)
-      expect(content).not.toMatch(`\nconst b = ref(__b);`)
-      expect(content).toMatch(`\nconst c = ref(__c);`)
-      expect(content).toMatch(`\nconst d = ref(__d);`)
-      expect(content).not.toMatch(`\nconst e = ref(__e);`)
-      expect(content).toMatch(`\nconst f = ref(__f);`)
-      expect(content).toMatch(`\nconst g = ref(__g);`)
+      expect(content).toMatch(`\nconst a = _ref(__a);`)
+      expect(content).not.toMatch(`\nconst b = _ref(__b);`)
+      expect(content).toMatch(`\nconst c = _ref(__c);`)
+      expect(content).toMatch(`\nconst d = _ref(__d);`)
+      expect(content).not.toMatch(`\nconst e = _ref(__e);`)
+      expect(content).toMatch(`\nconst f = _ref(__f);`)
+      expect(content).toMatch(`\nconst g = _ref(__g);`)
       expect(content).toMatch(
         `console.log(n.value, a.value, c.value, d.value, f.value, g.value)`
       )
@@ -556,11 +558,11 @@ const { props, emit } = defineOptions({
       console.log(n, a, b, c)
       </script>`)
       expect(content).toMatch(
-        `const n = ref(1), [__a, __b = 1, ...__c] = useFoo()`
+        `const n = _ref(1), [__a, __b = 1, ...__c] = useFoo()`
       )
-      expect(content).toMatch(`\nconst a = ref(__a);`)
-      expect(content).toMatch(`\nconst b = ref(__b);`)
-      expect(content).toMatch(`\nconst c = ref(__c);`)
+      expect(content).toMatch(`\nconst a = _ref(__a);`)
+      expect(content).toMatch(`\nconst b = _ref(__b);`)
+      expect(content).toMatch(`\nconst c = _ref(__c);`)
       expect(content).toMatch(`console.log(n.value, a.value, b.value, c.value)`)
       expect(content).toMatch(`return { n, a, b, c }`)
       expect(bindings).toStrictEqual({
@@ -580,11 +582,11 @@ const { props, emit } = defineOptions({
       </script>`)
       expect(content).toMatch(`const [{ a: { b: __b }}] = useFoo()`)
       expect(content).toMatch(`const { c: [__d, __e] } = useBar()`)
-      expect(content).not.toMatch(`\nconst a = ref(__a);`)
-      expect(content).not.toMatch(`\nconst c = ref(__c);`)
-      expect(content).toMatch(`\nconst b = ref(__b);`)
-      expect(content).toMatch(`\nconst d = ref(__d);`)
-      expect(content).toMatch(`\nconst e = ref(__e);`)
+      expect(content).not.toMatch(`\nconst a = _ref(__a);`)
+      expect(content).not.toMatch(`\nconst c = _ref(__c);`)
+      expect(content).toMatch(`\nconst b = _ref(__b);`)
+      expect(content).toMatch(`\nconst d = _ref(__d);`)
+      expect(content).toMatch(`\nconst e = _ref(__e);`)
       expect(content).toMatch(`return { b, d, e }`)
       expect(bindings).toStrictEqual({
         b: 'setup',
index 47420ca36a7742f99bad40f74194aaf9efdc6724..a049d205971fe1c135858c4a1c93e60e16389f9f 100644 (file)
@@ -24,7 +24,11 @@ import {
 } from '@babel/types'
 import { walk } from 'estree-walker'
 import { RawSourceMap } from 'source-map'
-import { genCssVarsCode, injectCssVarsCalls } from './genCssVars'
+import {
+  CSS_VARS_HELPER,
+  genCssVarsCode,
+  injectCssVarsCalls
+} from './genCssVars'
 import { compileTemplate, SFCTemplateCompileOptions } from './compileTemplate'
 
 const DEFINE_OPTIONS = 'defineOptions'
@@ -165,6 +169,11 @@ export function compileScript(
   const scriptStartOffset = script && script.loc.start.offset
   const scriptEndOffset = script && script.loc.end.offset
 
+  function helper(key: string): string {
+    helperImports.add(key)
+    return `_${key}`
+  }
+
   function parse(
     input: string,
     options: ParserOptions,
@@ -240,11 +249,10 @@ export function compileScript(
 
   function processRefExpression(exp: Expression, statement: LabeledStatement) {
     if (exp.type === 'AssignmentExpression') {
-      helperImports.add('ref')
       const { left, right } = exp
       if (left.type === 'Identifier') {
         registerRefBinding(left)
-        s.prependRight(right.start! + startOffset, `ref(`)
+        s.prependRight(right.start! + startOffset, `${helper('ref')}(`)
         s.appendLeft(right.end! + startOffset, ')')
       } else if (left.type === 'ObjectPattern') {
         // remove wrapping parens
@@ -272,7 +280,7 @@ export function compileScript(
       exp.expressions.forEach(e => processRefExpression(e, statement))
     } else if (exp.type === 'Identifier') {
       registerRefBinding(exp)
-      s.appendLeft(exp.end! + startOffset, ` = ref()`)
+      s.appendLeft(exp.end! + startOffset, ` = ${helper('ref')}()`)
     } else {
       error(`ref: statements can only contain assignment expressions.`, exp)
     }
@@ -326,7 +334,7 @@ export function compileScript(
         // append binding declarations after the parent statement
         s.appendLeft(
           statement.end! + startOffset,
-          `\nconst ${nameId.name} = ref(__${nameId.name});`
+          `\nconst ${nameId.name} = ${helper('ref')}(__${nameId.name});`
         )
       }
     }
@@ -360,7 +368,7 @@ export function compileScript(
         // append binding declarations after the parent statement
         s.appendLeft(
           statement.end! + startOffset,
-          `\nconst ${nameId.name} = ref(__${nameId.name});`
+          `\nconst ${nameId.name} = ${helper('ref')}(__${nameId.name});`
         )
       }
     }
@@ -744,7 +752,7 @@ export function compileScript(
 
   // 8. inject `useCssVars` calls
   if (hasCssVars) {
-    helperImports.add(`useCssVars`)
+    helperImports.add(CSS_VARS_HELPER)
     for (const style of styles) {
       const vars = style.attrs.vars
       if (typeof vars === 'string') {
@@ -829,7 +837,6 @@ export function compileScript(
   if (isTS) {
     // for TS, make sure the exported type is still valid type with
     // correct props information
-    helperImports.add(`defineComponent`)
     // we have to use object spread for types to be merged properly
     // user's TS setting should compile it down to proper targets
     const def = defaultExport ? `\n  ...${defaultTempVar},` : ``
@@ -838,7 +845,9 @@ export function compileScript(
     // this allows `import { setup } from '*.vue'` for testing purposes.
     s.prependLeft(
       startOffset,
-      `\nexport default defineComponent({${def}${runtimeOptions}\n  ${
+      `\nexport default ${helper(
+        `defineComponent`
+      )}({${def}${runtimeOptions}\n  ${
         hasAwait ? `async ` : ``
       }setup(${args}) {\n`
     )
@@ -865,11 +874,12 @@ export function compileScript(
   }
 
   // 12. finalize Vue helper imports
-  // TODO account for cases where user imports a helper with the same name
-  // from a non-vue source
-  const helpers = [...helperImports].filter(i => !userImports[i])
-  if (helpers.length) {
-    s.prepend(`import { ${helpers.join(', ')} } from 'vue'\n`)
+  if (helperImports.size > 0) {
+    s.prepend(
+      `import { ${[...helperImports]
+        .map(h => `${h} as _${h}`)
+        .join(', ')} } from 'vue'\n`
+    )
   }
 
   s.trim()
index 3d926cf593e9161339a28c7d320ea63f2dad73eb..69d1457f6ff45b1900702f7f5e3203487bfeb8a1 100644 (file)
@@ -10,6 +10,8 @@ import { SFCDescriptor } from './parse'
 import { rewriteDefault } from './rewriteDefault'
 import { ParserPlugin } from '@babel/parser'
 
+export const CSS_VARS_HELPER = `useCssVars`
+
 export function genCssVarsCode(
   varsExp: string,
   scoped: boolean,
@@ -38,7 +40,7 @@ export function genCssVarsCode(
           })
           .join('')
 
-  return `__useCssVars__(_ctx => (${transformedString})${
+  return `_${CSS_VARS_HELPER}(_ctx => (${transformedString})${
     scoped ? `, true` : ``
   })`
 }
@@ -65,7 +67,7 @@ export function injectCssVarsCalls(
 
   return (
     script +
-    `\nimport { useCssVars as __useCssVars__ } from 'vue'\n` +
+    `\nimport { ${CSS_VARS_HELPER} as _${CSS_VARS_HELPER} } from 'vue'\n` +
     `const __injectCSSVars__ = () => {\n${calls}}\n` +
     `const __setup__ = __default__.setup\n` +
     `__default__.setup = __setup__\n` +