Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

fix(auto-import-plugin): support functional components #2511

Open
wants to merge 1 commit into
base: dev
Choose a base branch
from
Open
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
52 changes: 50 additions & 2 deletions examples/sites/demos/pc/webdoc/import-components.md
Original file line number Diff line number Diff line change
Expand Up @@ -55,7 +55,7 @@ import { TinyVueResolver } from '@opentiny/unplugin-tiny-vue'
export default {
plugins: [
Components({
resolvers: [TinyVueResolver]
resolvers: [TinyVueResolver()]
})
]
}
Expand All @@ -73,7 +73,55 @@ module.exports = defineConfig({
configureWebpack: {
plugins: [
Components({
resolvers: [TinyVueResolver]
resolvers: [TinyVueResolver()]
})
]
}
})
```

#### 关于函数式组件

TinyModal,TinyNotify,TinyLoading 可使用函数形式调用,在使用时,需使用 `unplugin-auto-import` 实现自动导入。

Vite

```js
// vite.config.js
import Components from 'unplugin-vue-components/vite'
import AutoImport from 'unplugin-auto-import/vite'
import { TinyVueResolver } from '@opentiny/unplugin-tiny-vue'

module.exports = defineConfig({
configureWebpack: {
plugins: [
Components({
resolvers: [TinyVueResolver()]
}),
AutoImport({
resolvers: [TinyVueResolver({ autoImport: true })]
})
]
}
})
```
Comment on lines +89 to +107
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue

Maintain consistency in configuration examples.

The Vite example uses export default while the Webpack example uses module.exports. Additionally, the Vite example incorrectly uses configureWebpack which is a Vue CLI concept, not a Vite concept.

Apply this diff to fix the Vite configuration:

// vite.config.js
import Components from 'unplugin-vue-components/vite'
import AutoImport from 'unplugin-auto-import/vite'
import { TinyVueResolver } from '@opentiny/unplugin-tiny-vue'

-module.exports = defineConfig({
-  configureWebpack: {
-    plugins: [
+export default {
+  plugins: [
      Components({
        resolvers: [TinyVueResolver()]
      }),
      AutoImport({
        resolvers: [TinyVueResolver({ autoImport: true })]
      })
-    ]
-  }
-})
+  ]
+}

Also applies to: 111-124


Webpack

```js
// webpack.config.js
const Components = require('unplugin-vue-components/webpack').default
const AutoImport = require('unplugin-auto-import/webpack').default
const TinyVueResolver = require('@opentiny/unplugin-tiny-vue').TinyVueResolver

module.exports = defineConfig({
configureWebpack: {
plugins: [
Components({
resolvers: [TinyVueResolver()]
}),
AutoImport({
resolvers: [TinyVueResolver({ autoImport: true })]
})
]
}
Expand Down
12 changes: 12 additions & 0 deletions internals/unplugin-tiny-vue/example/auto-imports.d.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
/* eslint-disable */
/* prettier-ignore */
// @ts-nocheck
// noinspection JSUnusedGlobalSymbols
// Generated by unplugin-auto-import
// biome-ignore lint: disable
export {}
declare global {
const TinyLoading: (typeof import('@opentiny/vue'))['TinyLoading']
const TinyModal: (typeof import('@opentiny/vue'))['TinyModal']
const TinyNotify: (typeof import('@opentiny/vue'))['TinyNotify']
}
15 changes: 15 additions & 0 deletions internals/unplugin-tiny-vue/example/components.d.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
/* eslint-disable */
/* prettier-ignore */
// @ts-nocheck
// Generated by unplugin-vue-components
// Read more: https://github.com/vuejs/core/pull/3399
export {}

declare module 'vue' {
export interface GlobalComponents {
RouterLink: (typeof import('vue-router'))['RouterLink']
RouterView: (typeof import('vue-router'))['RouterView']
TinyButton: (typeof import('@opentiny/vue'))['Button']
TinyModal: (typeof import('@opentiny/vue'))['Modal']
}
}
9 changes: 4 additions & 5 deletions internals/unplugin-tiny-vue/example/package.json
Original file line number Diff line number Diff line change
@@ -1,23 +1,22 @@
{
"name": "my-vue-app",
"version": "0.0.0",
"description": "",
"author": "",
"version": "0.0.0",
"scripts": {
"dev": "vite",
"build": "vite build",
"preview": "vite preview"
},
"dependencies": {
"@opentiny/vue": "~3.12.1",
"@opentiny/vue-alert": "~3.13.0",
"@opentiny/vue-button-group": "~3.13.0",
"@opentiny/vue": "~3.18.0",
"@opentiny/vue-icon": "^3.12.0",
"vue": "^3.3.9"
},
"devDependencies": {
"@vitejs/plugin-vue": "^4.1.0",
"vite": "link:../node_modules/vite",
"unplugin-auto-import": "^0.18.3",
"vite": "^4.3.8",
"vite-plugin-inspect": "^0.8.3"
}
}
84 changes: 69 additions & 15 deletions internals/unplugin-tiny-vue/example/src/App.vue
Original file line number Diff line number Diff line change
@@ -1,22 +1,76 @@
<template>
<div>
<tiny-button-group :data="groupData" v-model="checkedVal"></tiny-button-group>
<span>当前选中值:{{ checkedVal }}</span>
<tiny-alert description="type 为默认值 success"></tiny-alert>
<tiny-button @click="closeLoading">close Loading</tiny-button>
<div id="tiny-basic-loading1"></div>
<tiny-button @click="handleClick" :reset-time="0">弹出提示框</tiny-button>

<h2>函数式调用</h2>
<div class="content">
<span>弹窗模式:</span>
<tiny-button @click="baseClick"> 基本提示框 </tiny-button>
<tiny-button @click="successClick"> 成功提示框 </tiny-button>
<tiny-button @click="confirmClick"> 确认提示框 </tiny-button>
</div>
<div class="content">
<span>消息模式:</span>
<tiny-button @click="messageClick"> 消息提示 </tiny-button>
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue

Undefined function 'messageClick' referenced in the template

The messageClick function is called in the template but is not defined in the script section. This will cause a runtime error when the button is clicked.

Apply this diff to add the missing messageClick function:

+function messageClick() {
+  TinyNotify({
+    type: 'info',
+    title: '消息提示',
+    message: '这是一个消息提示。',
+    position: 'top-right',
+    duration: 5000
+  })
+}

Committable suggestion skipped: line range outside the PR's diff.

</div>

<h2>标签式调用</h2>
<div class="content">
<tiny-modal v-model="show1" title="基本提示框" message="窗口内容1" show-footer> </tiny-modal>
<tiny-modal v-model="show2" title="基本提示框" message="窗口内容2" status="success" show-footer> </tiny-modal>
<tiny-button @click="show1 = true"> 打开弹窗1 </tiny-button>
<tiny-button @click="show2 = true"> 打开弹窗2 </tiny-button>
</div>
</div>
</template>

<script>
export default {
data() {
return {
checkedVal: 'Button1',
groupData: [
{ text: 'Button1', value: 'Button1' },
{ text: 'Button2', value: 'Button2' },
{ text: 'Button3', value: 'Button3' }
]
}
}
<script setup>
import { ref, onMounted } from 'vue'

const loadingInstance = ref(null)

const closeLoading = () => {
loadingInstance.value.close()
}

onMounted(() => {
loadingInstance.value = TinyLoading.service({
target: document.getElementById('tiny-basic-loading1')
})
})

function handleClick() {
TinyNotify({
type: 'info',
title: '通知消息的标题',
message: '通知消息的正文,通知消息的正文,通知消息的正文,通知消息的正文,通知消息的正文,通知消息的正文',
position: 'top-right',
duration: 5000,
customClass: 'my-custom-cls'
})
}

const show1 = ref(false)
const show2 = ref(false)

function baseClick() {
const modal = TinyModal.alert('基本提示框', '标题')
setTimeout(() => modal.vm.close(), 3000)
}

function successClick() {
TinyModal.alert({ message: '成功提示框', status: 'success' })
}

function confirmClick() {
TinyModal.confirm('您确定要删除吗?').then((res) => {
TinyNotify({
type: 'info',
title: '触发回调事件',
message: `点击${res}按钮`
})
})
}
</script>
15 changes: 13 additions & 2 deletions internals/unplugin-tiny-vue/example/vite.config.js
Original file line number Diff line number Diff line change
@@ -1,11 +1,22 @@
import { defineConfig } from 'vite'
import vue from '@vitejs/plugin-vue'
import Inspect from 'vite-plugin-inspect'
import autoImportPlugin from '../dist/index.js'
import Components from 'unplugin-vue-components/vite'
import AutoImport from 'unplugin-auto-import/vite'
import { TinyVueResolver } from '../dist/index.js'
Comment on lines +4 to +6
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Codebase verification

Build required: dist directory is missing and dependency setup needs attention

  • The dist directory is missing, indicating the plugin needs to be built before the example can work
  • unplugin-auto-import is missing from both dependencies and devDependencies
  • unplugin-vue-components is correctly added as a dependency

Please ensure to:

  1. Run the build process to generate the dist directory
  2. Add unplugin-auto-import as a dependency in package.json
🔗 Analysis chain

Verify dependencies and build requirements

The new imports look good, but let's ensure the build setup is complete.

🏁 Scripts executed

The following scripts were executed for the analysis:

Script:

#!/bin/bash
# Check if the required packages are in dependencies
cat package.json | jq '.dependencies["unplugin-vue-components"], .dependencies["unplugin-auto-import"]'

# Verify if dist/index.js exists and is built
if [ -f "internals/unplugin-tiny-vue/dist/index.js" ]; then
    echo "dist/index.js exists"
else
    echo "Warning: dist/index.js not found. Build may be required."
fi

Length of output: 365


Script:

#!/bin/bash
# Check package.json in the specific plugin directory
cat internals/unplugin-tiny-vue/package.json | jq '.dependencies, .devDependencies'

# Check if the dist directory exists and list its contents
ls -la internals/unplugin-tiny-vue/dist/

# Find example usage of these plugins in the codebase
rg -l "unplugin-vue-components|unplugin-auto-import" internals/unplugin-tiny-vue/

Length of output: 752


// https://vitejs.dev/config/
export default defineConfig({
plugins: [vue(), Inspect(), autoImportPlugin()],
plugins: [
vue(),
Inspect(),
Components({
resolvers: [TinyVueResolver()]
}),
AutoImport({
resolvers: [TinyVueResolver({ autoImport: true })]
})
],
define: {
'process.env': { ...process.env, TINY_MODE: 'pc' }
},
Expand Down
34 changes: 28 additions & 6 deletions internals/unplugin-tiny-vue/src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,15 @@ import AutoRollup from 'unplugin-vue-components/rollup'
import AutoEsbuild from 'unplugin-vue-components/esbuild'
import AutoRspack from 'unplugin-vue-components/rspack'

export interface TinyVueResolverOption {
/**
* compatible with unplugin-auto-import
*
* @default false
*/
autoImport?: boolean
}

const supportMap = {
'vite': AutoVite,
'webpack': AutoWebpack,
Expand All @@ -12,11 +21,24 @@ const supportMap = {
'rspack': AutoRspack
}

export const TinyVueResolver = (componentName) => {
if (componentName.startsWith('Tiny') && !componentName.startsWith('TinyIcon')) {
return {
name: componentName.slice(4),
from: '@opentiny/vue'
const TinyVueFunc = ['TinyModal', 'TinyNotify', 'TinyLoading']

export const TinyVueResolver = (option: TinyVueResolverOption = {}) => {
return (componentName: string) => {
const { autoImport = false } = option

if (autoImport && TinyVueFunc.includes(componentName)) {
return {
name: componentName,
from: '@opentiny/vue'
}
}

if (componentName.startsWith('Tiny') && !componentName.startsWith('TinyIcon')) {
return {
name: componentName.slice(4),
from: '@opentiny/vue'
}
}
}
}
Expand All @@ -32,6 +54,6 @@ export default (name) => {
const autoPlugin = supportMap[name].default || supportMap[name]

return autoPlugin({
resolvers: [TinyVueResolver]
resolvers: [TinyVueResolver()]
})
}
Loading