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__
// 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__
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__
`;
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 }
}
exports[`SFC compile <script setup> defineOptions() 1`] = `
"export default {
+ expose: [],
props: {
foo: String
},
"import { bar } from './bar'
export default {
+ expose: [],
props: {
foo: {
default: () => bar
exports[`SFC compile <script setup> errors should allow defineOptions() referencing scope var 1`] = `
"export default {
+ expose: [],
props: {
foo: {
default: bar => bar + 1
`;
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 }
}
"import { x } from './x'
export default {
+ expose: [],
setup() {
x()
import b from 'b'
export default {
+ expose: [],
setup() {
exports[`SFC compile <script setup> imports should hoist and expose imports 1`] = `
"import { ref } from 'vue'
export default {
+ expose: [],
setup() {
return { ref }
import other from './util'
export default {
+ expose: [],
setup() {
const count = ref(0)
import { ref } from 'vue'
export default {
+ expose: [],
setup() {
const count = ref(0)
`;
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
`;
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 }
`;
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 = () => {}
`;
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
})
`;
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
`;
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 }
`;
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 }
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 = {
`;
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
"import { x } from './x'
export default {
+ expose: [],
setup() {
let a = 1
`;
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 }) {
`;
exports[`SFC compile <script setup> with TypeScript defineOptions w/ type / extract emits (union) 1`] = `
-"import { Slots, defineComponent } 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: {},
`;
exports[`SFC compile <script setup> with TypeScript defineOptions w/ type / extract emits 1`] = `
-"import { Slots, defineComponent } 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: {},
`;
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 },
`;
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() {
expect(content).toMatch(`setup(__props, { props, emit }) {`)
// should include context options in default export
expect(content).toMatch(`export default {
+ expose: [],
props: {
foo: String
},
</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 }) {`)
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
})
`)
}
</script>`)
expect(content).toMatch(`
- const a = ref(1), b = ref(2), c = ref({
+ const a = _ref(1), b = _ref(2), c = _ref({
count: 0
})
`)
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)`
)
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({
</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',
} 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'
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,
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
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)
}
// 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});`
)
}
}
// 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});`
)
}
}
// 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') {
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},` : ``
// 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`
)
}
// 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()
import { rewriteDefault } from './rewriteDefault'
import { ParserPlugin } from '@babel/parser'
+export const CSS_VARS_HELPER = `useCssVars`
+
export function genCssVarsCode(
varsExp: string,
scoped: boolean,
})
.join('')
- return `__useCssVars__(_ctx => (${transformedString})${
+ return `_${CSS_VARS_HELPER}(_ctx => (${transformedString})${
scoped ? `, true` : ``
})`
}
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` +