refactor: simplify sfc script transform usage
This commit is contained in:
@@ -1,10 +1,9 @@
|
||||
import { parse, compileScriptSetup, SFCScriptCompileOptions } from '../src'
|
||||
import { parse, SFCScriptCompileOptions } from '../src'
|
||||
import { parse as babelParse } from '@babel/parser'
|
||||
import { babelParserDefautPlugins } from '@vue/shared'
|
||||
|
||||
function compile(src: string, options?: SFCScriptCompileOptions) {
|
||||
const { descriptor } = parse(src)
|
||||
return compileScriptSetup(descriptor, options)
|
||||
return parse(src, options).descriptor.scriptTransformed!
|
||||
}
|
||||
|
||||
function assertCode(code: string) {
|
||||
@@ -23,17 +22,19 @@ function assertCode(code: string) {
|
||||
|
||||
describe('SFC compile <script setup>', () => {
|
||||
test('should hoist imports', () => {
|
||||
assertCode(compile(`<script setup>import { ref } from 'vue'</script>`).code)
|
||||
assertCode(
|
||||
compile(`<script setup>import { ref } from 'vue'</script>`).content
|
||||
)
|
||||
})
|
||||
|
||||
test('explicit setup signature', () => {
|
||||
assertCode(
|
||||
compile(`<script setup="props, { emit }">emit('foo')</script>`).code
|
||||
compile(`<script setup="props, { emit }">emit('foo')</script>`).content
|
||||
)
|
||||
})
|
||||
|
||||
test('import dedupe between <script> and <script setup>', () => {
|
||||
const code = compile(`
|
||||
const { content } = compile(`
|
||||
<script>
|
||||
import { x } from './x'
|
||||
</script>
|
||||
@@ -41,30 +42,30 @@ describe('SFC compile <script setup>', () => {
|
||||
import { x } from './x'
|
||||
x()
|
||||
</script>
|
||||
`).code
|
||||
assertCode(code)
|
||||
expect(code.indexOf(`import { x }`)).toEqual(
|
||||
code.lastIndexOf(`import { x }`)
|
||||
`)
|
||||
assertCode(content)
|
||||
expect(content.indexOf(`import { x }`)).toEqual(
|
||||
content.lastIndexOf(`import { x }`)
|
||||
)
|
||||
})
|
||||
|
||||
describe('exports', () => {
|
||||
test('export const x = ...', () => {
|
||||
const { code, bindings } = compile(
|
||||
const { content, bindings } = compile(
|
||||
`<script setup>export const x = 1</script>`
|
||||
)
|
||||
assertCode(code)
|
||||
assertCode(content)
|
||||
expect(bindings).toStrictEqual({
|
||||
x: 'setup'
|
||||
})
|
||||
})
|
||||
|
||||
test('export const { x } = ... (destructuring)', () => {
|
||||
const { code, bindings } = compile(`<script setup>
|
||||
const { content, bindings } = compile(`<script setup>
|
||||
export const [a = 1, { b } = { b: 123 }, ...c] = useFoo()
|
||||
export const { d = 2, _: [e], ...f } = useBar()
|
||||
</script>`)
|
||||
assertCode(code)
|
||||
assertCode(content)
|
||||
expect(bindings).toStrictEqual({
|
||||
a: 'setup',
|
||||
b: 'setup',
|
||||
@@ -76,34 +77,34 @@ describe('SFC compile <script setup>', () => {
|
||||
})
|
||||
|
||||
test('export function x() {}', () => {
|
||||
const { code, bindings } = compile(
|
||||
const { content, bindings } = compile(
|
||||
`<script setup>export function x(){}</script>`
|
||||
)
|
||||
assertCode(code)
|
||||
assertCode(content)
|
||||
expect(bindings).toStrictEqual({
|
||||
x: 'setup'
|
||||
})
|
||||
})
|
||||
|
||||
test('export class X() {}', () => {
|
||||
const { code, bindings } = compile(
|
||||
const { content, bindings } = compile(
|
||||
`<script setup>export class X {}</script>`
|
||||
)
|
||||
assertCode(code)
|
||||
assertCode(content)
|
||||
expect(bindings).toStrictEqual({
|
||||
X: 'setup'
|
||||
})
|
||||
})
|
||||
|
||||
test('export { x }', () => {
|
||||
const { code, bindings } = compile(
|
||||
const { content, bindings } = compile(
|
||||
`<script setup>
|
||||
const x = 1
|
||||
const y = 2
|
||||
export { x, y }
|
||||
</script>`
|
||||
)
|
||||
assertCode(code)
|
||||
assertCode(content)
|
||||
expect(bindings).toStrictEqual({
|
||||
x: 'setup',
|
||||
y: 'setup'
|
||||
@@ -111,12 +112,12 @@ describe('SFC compile <script setup>', () => {
|
||||
})
|
||||
|
||||
test(`export { x } from './x'`, () => {
|
||||
const { code, bindings } = compile(
|
||||
const { content, bindings } = compile(
|
||||
`<script setup>
|
||||
export { x, y } from './x'
|
||||
</script>`
|
||||
)
|
||||
assertCode(code)
|
||||
assertCode(content)
|
||||
expect(bindings).toStrictEqual({
|
||||
x: 'setup',
|
||||
y: 'setup'
|
||||
@@ -124,52 +125,52 @@ describe('SFC compile <script setup>', () => {
|
||||
})
|
||||
|
||||
test(`export default from './x'`, () => {
|
||||
const { code, bindings } = compile(
|
||||
const { content, bindings } = compile(
|
||||
`<script setup>
|
||||
export default from './x'
|
||||
</script>`,
|
||||
{
|
||||
parserPlugins: ['exportDefaultFrom']
|
||||
babelParserPlugins: ['exportDefaultFrom']
|
||||
}
|
||||
)
|
||||
assertCode(code)
|
||||
assertCode(content)
|
||||
expect(bindings).toStrictEqual({})
|
||||
})
|
||||
|
||||
test(`export { x as default }`, () => {
|
||||
const { code, bindings } = compile(
|
||||
const { content, bindings } = compile(
|
||||
`<script setup>
|
||||
import x from './x'
|
||||
const y = 1
|
||||
export { x as default, y }
|
||||
</script>`
|
||||
)
|
||||
assertCode(code)
|
||||
assertCode(content)
|
||||
expect(bindings).toStrictEqual({
|
||||
y: 'setup'
|
||||
})
|
||||
})
|
||||
|
||||
test(`export { x as default } from './x'`, () => {
|
||||
const { code, bindings } = compile(
|
||||
const { content, bindings } = compile(
|
||||
`<script setup>
|
||||
export { x as default, y } from './x'
|
||||
</script>`
|
||||
)
|
||||
assertCode(code)
|
||||
assertCode(content)
|
||||
expect(bindings).toStrictEqual({
|
||||
y: 'setup'
|
||||
})
|
||||
})
|
||||
|
||||
test(`export * from './x'`, () => {
|
||||
const { code, bindings } = compile(
|
||||
const { content, bindings } = compile(
|
||||
`<script setup>
|
||||
export * from './x'
|
||||
export const y = 1
|
||||
</script>`
|
||||
)
|
||||
assertCode(code)
|
||||
assertCode(content)
|
||||
expect(bindings).toStrictEqual({
|
||||
y: 'setup'
|
||||
// in this case we cannot extract bindings from ./x so it falls back
|
||||
@@ -178,7 +179,7 @@ describe('SFC compile <script setup>', () => {
|
||||
})
|
||||
|
||||
test('export default in <script setup>', () => {
|
||||
const { code, bindings } = compile(
|
||||
const { content, bindings } = compile(
|
||||
`<script setup>
|
||||
export default {
|
||||
props: ['foo']
|
||||
@@ -186,7 +187,7 @@ describe('SFC compile <script setup>', () => {
|
||||
export const y = 1
|
||||
</script>`
|
||||
)
|
||||
assertCode(code)
|
||||
assertCode(content)
|
||||
expect(bindings).toStrictEqual({
|
||||
y: 'setup'
|
||||
})
|
||||
@@ -195,18 +196,18 @@ describe('SFC compile <script setup>', () => {
|
||||
|
||||
describe('<script setup lang="ts">', () => {
|
||||
test('hoist type declarations', () => {
|
||||
const { code, bindings } = compile(`
|
||||
const { content, bindings } = compile(`
|
||||
<script setup lang="ts">
|
||||
export interface Foo {}
|
||||
type Bar = {}
|
||||
export const a = 1
|
||||
</script>`)
|
||||
assertCode(code)
|
||||
assertCode(content)
|
||||
expect(bindings).toStrictEqual({ a: 'setup' })
|
||||
})
|
||||
|
||||
test('extract props', () => {
|
||||
const { code } = compile(`
|
||||
const { content } = compile(`
|
||||
<script setup="myProps" lang="ts">
|
||||
interface Test {}
|
||||
|
||||
@@ -237,59 +238,57 @@ describe('SFC compile <script setup>', () => {
|
||||
intersection: Test & {}
|
||||
}
|
||||
</script>`)
|
||||
assertCode(code)
|
||||
expect(code).toMatch(`string: { type: String, required: true }`)
|
||||
expect(code).toMatch(`number: { type: Number, required: true }`)
|
||||
expect(code).toMatch(`boolean: { type: Boolean, required: true }`)
|
||||
expect(code).toMatch(`object: { type: Object, required: true }`)
|
||||
expect(code).toMatch(`objectLiteral: { type: Object, required: true }`)
|
||||
expect(code).toMatch(`fn: { type: Function, required: true }`)
|
||||
expect(code).toMatch(`functionRef: { type: Function, required: true }`)
|
||||
expect(code).toMatch(`objectRef: { type: Object, required: true }`)
|
||||
expect(code).toMatch(`array: { type: Array, required: true }`)
|
||||
expect(code).toMatch(`arrayRef: { type: Array, required: true }`)
|
||||
expect(code).toMatch(`tuple: { type: Array, required: true }`)
|
||||
expect(code).toMatch(`set: { type: Set, required: true }`)
|
||||
expect(code).toMatch(`literal: { type: String, required: true }`)
|
||||
expect(code).toMatch(`optional: { type: null, required: false }`)
|
||||
expect(code).toMatch(`recordRef: { type: Object, required: true }`)
|
||||
expect(code).toMatch(`interface: { type: Object, required: true }`)
|
||||
expect(code).toMatch(`alias: { type: Array, required: true }`)
|
||||
expect(code).toMatch(`union: { type: [String, Number], required: true }`)
|
||||
expect(code).toMatch(
|
||||
assertCode(content)
|
||||
expect(content).toMatch(`string: { type: String, required: true }`)
|
||||
expect(content).toMatch(`number: { type: Number, required: true }`)
|
||||
expect(content).toMatch(`boolean: { type: Boolean, required: true }`)
|
||||
expect(content).toMatch(`object: { type: Object, required: true }`)
|
||||
expect(content).toMatch(`objectLiteral: { type: Object, required: true }`)
|
||||
expect(content).toMatch(`fn: { type: Function, required: true }`)
|
||||
expect(content).toMatch(`functionRef: { type: Function, required: true }`)
|
||||
expect(content).toMatch(`objectRef: { type: Object, required: true }`)
|
||||
expect(content).toMatch(`array: { type: Array, required: true }`)
|
||||
expect(content).toMatch(`arrayRef: { type: Array, required: true }`)
|
||||
expect(content).toMatch(`tuple: { type: Array, required: true }`)
|
||||
expect(content).toMatch(`set: { type: Set, required: true }`)
|
||||
expect(content).toMatch(`literal: { type: String, required: true }`)
|
||||
expect(content).toMatch(`optional: { type: null, required: false }`)
|
||||
expect(content).toMatch(`recordRef: { type: Object, required: true }`)
|
||||
expect(content).toMatch(`interface: { type: Object, required: true }`)
|
||||
expect(content).toMatch(`alias: { type: Array, required: true }`)
|
||||
expect(content).toMatch(
|
||||
`union: { type: [String, Number], required: true }`
|
||||
)
|
||||
expect(content).toMatch(
|
||||
`literalUnion: { type: [String, String], required: true }`
|
||||
)
|
||||
expect(code).toMatch(
|
||||
expect(content).toMatch(
|
||||
`literalUnionMixed: { type: [String, Number, Boolean], required: true }`
|
||||
)
|
||||
expect(code).toMatch(`intersection: { type: Object, required: true }`)
|
||||
expect(content).toMatch(`intersection: { type: Object, required: true }`)
|
||||
})
|
||||
|
||||
test('extract emits', () => {
|
||||
const { code } = compile(`
|
||||
const { content } = compile(`
|
||||
<script setup="_, { emit: myEmit }" lang="ts">
|
||||
declare function myEmit(e: 'foo' | 'bar'): void
|
||||
declare function myEmit(e: 'baz', id: number): void
|
||||
</script>
|
||||
`)
|
||||
assertCode(code)
|
||||
expect(code).toMatch(`declare function __emit__(e: 'foo' | 'bar'): void`)
|
||||
expect(code).toMatch(
|
||||
assertCode(content)
|
||||
expect(content).toMatch(
|
||||
`declare function __emit__(e: 'foo' | 'bar'): void`
|
||||
)
|
||||
expect(content).toMatch(
|
||||
`declare function __emit__(e: 'baz', id: number): void`
|
||||
)
|
||||
expect(code).toMatch(
|
||||
expect(content).toMatch(
|
||||
`emits: ["foo", "bar", "baz"] as unknown as undefined`
|
||||
)
|
||||
})
|
||||
})
|
||||
|
||||
describe('errors', () => {
|
||||
test('must have <script setup>', () => {
|
||||
expect(() => compile(`<script>foo()</script>`)).toThrow(
|
||||
`SFC has no <script setup>`
|
||||
)
|
||||
})
|
||||
|
||||
test('<script> and <script setup> must have same lang', () => {
|
||||
expect(() =>
|
||||
compile(`<script>foo()</script><script setup lang="ts">bar()</script>`)
|
||||
@@ -342,7 +341,7 @@ describe('SFC compile <script setup>', () => {
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>`).code
|
||||
</script>`).content
|
||||
)
|
||||
})
|
||||
|
||||
@@ -358,7 +357,7 @@ describe('SFC compile <script setup>', () => {
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>`).code
|
||||
</script>`).content
|
||||
)
|
||||
})
|
||||
|
||||
@@ -373,7 +372,7 @@ describe('SFC compile <script setup>', () => {
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>`).code
|
||||
</script>`).content
|
||||
)
|
||||
})
|
||||
|
||||
|
||||
Reference in New Issue
Block a user