Skip to content
This repository was archived by the owner on Dec 25, 2024. It is now read-only.

fix: async component registration hoisting #44

Merged
merged 7 commits into from
Sep 16, 2021
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
10 changes: 0 additions & 10 deletions jest.js

This file was deleted.

6 changes: 3 additions & 3 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -49,12 +49,12 @@
"types": "index.d.ts",
"files": [
"dist",
"jest.js",
"jest-transform.js",
"*.d.ts"
],
"scripts": {
"build": "rimraf dist && tsup 'src/*.ts' --format cjs,esm --dts && esno scripts/postbuild.ts",
"dev": "tsup 'src/*.ts' --watch src",
"build": "rimraf dist && tsup \"src/*.ts\" --format cjs,esm --dts && esno scripts/postbuild.ts",
"dev": "tsup \"src/*.ts\" --watch src",
"lint": "eslint \"{src,test}/**/*.ts\"",
"lint:fix": "nr lint -- --fix",
"play": "npm -C playground run dev",
Expand Down
6 changes: 6 additions & 0 deletions playground/App.vue
Original file line number Diff line number Diff line change
@@ -1,12 +1,18 @@
<template>
<div>
<hello-world name="Vue 2" @update="onUpdate" />

<async-component />
</div>
</template>

<script setup lang="ts">
import { defineAsyncComponent } from '@vue/composition-api'

import HelloWorld from './HelloWorld.vue'

const AsyncComponent = defineAsyncComponent(() => import('./Async.vue'))

function onUpdate(e: any) {
// eslint-disable-next-line no-console
console.log(e)
Expand Down
3 changes: 3 additions & 0 deletions playground/Async.vue
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
<template>
<div>Async Component</div>
</template>
15 changes: 14 additions & 1 deletion src/core/transformScriptSetup.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,14 +7,27 @@ import { ParsedSFC, ScriptSetupTransformOptions } from '../types'
import { applyMacros } from './macros'
import { getIdentifierDeclarations } from './identifiers'

function isAsyncImport(node: any) {
if (node.type === 'VariableDeclaration') {
const declaration = node.declarations[0]

return declaration.init.callee != null
&& declaration.init.callee.name === 'defineAsyncComponent'
}

return false
}

export function transformScriptSetup(sfc: ParsedSFC, options?: ScriptSetupTransformOptions) {
const { scriptSetup, script, template } = sfc

const { nodes: body, props, expose } = applyMacros(scriptSetup.ast.body)

const [hoisted, setupBody] = partition(
body,
n => n.type === 'ImportDeclaration'
n =>
isAsyncImport(n)
|| n.type === 'ImportDeclaration'
|| n.type === 'ExportNamedDeclaration'
|| n.type.startsWith('TS'),
)
Expand Down
36 changes: 35 additions & 1 deletion test/__snapshots__/transform.test.ts.snap
Original file line number Diff line number Diff line change
Expand Up @@ -4,11 +4,15 @@ exports[`transform fixtures playground/App.vue 1`] = `
"<template>
<div>
<hello-world name=\\"Vue 2\\" @update=\\"onUpdate\\" />

<async-component />
</div>
</template>

<script lang=\\"ts\\">
import { defineAsyncComponent } from '@vue/composition-api';
import HelloWorld from './HelloWorld.vue';
const AsyncComponent = defineAsyncComponent(() => import('./Async.vue'));
const __sfc_main = {};

__sfc_main.setup = (__props, __ctx) => {
Expand All @@ -23,13 +27,21 @@ __sfc_main.setup = (__props, __ctx) => {
};

__sfc_main.components = Object.assign({
HelloWorld
HelloWorld,
AsyncComponent
}, __sfc_main.components);
export default __sfc_main;
</script>
"
`;

exports[`transform fixtures playground/Async.vue 1`] = `
"<template>
<div>Async Component</div>
</template>
"
`;

exports[`transform fixtures playground/Bar.vue 1`] = `
"<template>
<div>Bar</div>
Expand Down Expand Up @@ -146,6 +158,28 @@ export default defineConfig({
"
`;

exports[`transform fixtures test/fixtures/AsyncImport.vue 1`] = `
"<script lang=\\"ts\\">
import { defineAsyncComponent } from '@vue/composition-api';
const ScriptOnly = defineAsyncComponent(() => import('./ScriptOnly.vue'));
const __sfc_main = {};

__sfc_main.setup = (__props, __ctx) => {
return {};
};

__sfc_main.components = Object.assign({
ScriptOnly
}, __sfc_main.components);
export default __sfc_main;
</script>

<template>
<ScriptOnly />
</template>
"
`;

exports[`transform fixtures test/fixtures/DynamicStyle.vue 1`] = `
"<template>
<div :style=\\"{ color, border: '1px' }\\" />
Expand Down
8 changes: 8 additions & 0 deletions test/fixtures/AsyncImport.vue
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
<script setup lang="ts">
import { defineAsyncComponent } from '@vue/composition-api'
const ScriptOnly = defineAsyncComponent(() => import('./ScriptOnly.vue'))
</script>

<template>
<ScriptOnly />
</template>