Skip to content

Commit

Permalink
feat: generate svg-icon-global.d.ts
Browse files Browse the repository at this point in the history
  • Loading branch information
Jevon617 committed Oct 19, 2022
1 parent 127da15 commit 9a0ce2a
Show file tree
Hide file tree
Showing 12 changed files with 88 additions and 55 deletions.
1 change: 0 additions & 1 deletion playground/App.vue
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,6 @@ import { useRouter } from 'vue-router'
<div>
<SvgIcon name="icon-addUser" style="margin-right: 20px;" />
<SvgIcon name="icon-card2" style="margin-right: 20px;" />
<SvgIcon name="common-icon-add3" style="margin-right: 20px;" />
</div>
</template>

Expand Down
2 changes: 1 addition & 1 deletion playground/components/test.vue
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ import SvgIcon from 'virtual:svg-component'
<div>
test1
<SvgIcon name="icon-card2" style="margin-right: 20px;" />
<SvgIcon name="common-icon-card" style="margin-right: 20px;" />
<SvgIcon name="icon-addUser" style="margin-right: 20px;" />
</div>
</template>

Expand Down
2 changes: 1 addition & 1 deletion playground/components/test2.vue
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
<script setup lang='ts'>
import SvgIcon from 'virtual:svg-component'
import SvgIcon1 from 'virtual:svg-component'
</script>

<template>
Expand Down
2 changes: 1 addition & 1 deletion playground/main.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,4 +3,4 @@ import SvgIcon from 'virtual:svg-component'
import App from './App.vue'
import router from './router'

createApp(App).use({ name: 'svg-icon', SvgIcon }).use(router).mount('#app')
createApp(App).component('SvgIcon', SvgIcon).use(router).mount('#app')
22 changes: 22 additions & 0 deletions playground/svg-icon-global.d.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@

import '@vue/runtime-core'
declare module '@vue/runtime-core' {
import type { PropType } from 'vue';
export interface GlobalComponents {
SvgIcon: import("vue").DefineComponent<{
name: {
type: PropType<"icon-addUser" | "icon-barCode" | "icon-card2" | "common-icon-add" | "common-icon-add3" | "common-icon-addUser" | "common-icon-addUsers" | "common-icon-addx" | "common-icon-apple" | "common-icon-banner">;
default: string;
required: true;
};
}, {}, unknown, {}, {}, import("vue").ComponentOptionsMixin, import("vue").ComponentOptionsMixin, {}, string, import("vue").VNodeProps & import("vue").AllowedComponentProps & import("vue").ComponentCustomProps, Readonly<import("vue").ExtractPropTypes<{
name: {
type: PropType<"icon-addUser" | "icon-barCode" | "icon-card2" | "common-icon-add" | "common-icon-add3" | "common-icon-addUser" | "common-icon-addUsers" | "common-icon-addx" | "common-icon-apple" | "common-icon-banner">;
default: string;
required: true;
};
}>>, {
name: "icon-addUser" | "icon-barCode" | "icon-card2" | "common-icon-add" | "common-icon-add3" | "common-icon-addUser" | "common-icon-addUsers" | "common-icon-addx" | "common-icon-apple" | "common-icon-banner";
}>;
}
}
22 changes: 0 additions & 22 deletions playground/svg-icon.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -18,25 +18,3 @@ declare module 'virtual:svg-component' {
}>;
export default SvgIcon;
}

declare module '@vue/runtime-core' {
import type { PropType } from 'vue';
const SvgIcon: import("vue").DefineComponent<{
name: {
type: PropType<"icon-addUser" | "icon-barCode" | "icon-card2" | "common-icon-add" | "common-icon-add3" | "common-icon-addUser" | "common-icon-addUsers" | "common-icon-addx" | "common-icon-apple" | "common-icon-banner">;
default: string;
required: true;
};
}, {}, unknown, {}, {}, import("vue").ComponentOptionsMixin, import("vue").ComponentOptionsMixin, {}, string, import("vue").VNodeProps & import("vue").AllowedComponentProps & import("vue").ComponentCustomProps, Readonly<import("vue").ExtractPropTypes<{
name: {
type: PropType<"icon-addUser" | "icon-barCode" | "icon-card2" | "common-icon-add" | "common-icon-add3" | "common-icon-addUser" | "common-icon-addUsers" | "common-icon-addx" | "common-icon-apple" | "common-icon-banner">;
default: string;
required: true;
};
}>>, {
name: "icon-addUser" | "icon-barCode" | "icon-card2" | "common-icon-add" | "common-icon-add3" | "common-icon-addUser" | "common-icon-addUsers" | "common-icon-addx" | "common-icon-apple" | "common-icon-banner";
}>;
export interface GlobalComponents {
SvgIcon: SvgIcon;
}
}
2 changes: 1 addition & 1 deletion playground/vite.config.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ import path from 'path'
import { defineConfig } from 'vite'
import Inspect from 'vite-plugin-inspect'
import vue from '@vitejs/plugin-vue'
import Unplugin from '../src/vite'
import Unplugin from '../dist/vite'

export default defineConfig({
plugins: [
Expand Down
38 changes: 20 additions & 18 deletions src/core/code.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ export const template = `
export const dts = `
declare module 'virtual:svg-component' {
import type { PropType } from 'vue';
const SvgIcon: import("vue").DefineComponent<{
const $component_name: import("vue").DefineComponent<{
name: {
type: PropType<"$svg_symbolIds">;
default: string;
Expand All @@ -21,28 +21,30 @@ declare module 'virtual:svg-component' {
}>>, {
name: "$svg_symbolIds";
}>;
export default SvgIcon;
export default $component_name;
}
`

export const golbalDts = `
import '@vue/runtime-core'
declare module '@vue/runtime-core' {
import type { PropType } from 'vue';
const SvgIcon: import("vue").DefineComponent<{
name: {
type: PropType<"$svg_symbolIds">;
default: string;
required: true;
};
}, {}, unknown, {}, {}, import("vue").ComponentOptionsMixin, import("vue").ComponentOptionsMixin, {}, string, import("vue").VNodeProps & import("vue").AllowedComponentProps & import("vue").ComponentCustomProps, Readonly<import("vue").ExtractPropTypes<{
name: {
type: PropType<"$svg_symbolIds">;
default: string;
required: true;
};
}>>, {
name: "$svg_symbolIds";
}>;
export interface GlobalComponents {
SvgIcon: SvgIcon;
$component_name: import("vue").DefineComponent<{
name: {
type: PropType<"$svg_symbolIds">;
default: string;
required: true;
};
}, {}, unknown, {}, {}, import("vue").ComponentOptionsMixin, import("vue").ComponentOptionsMixin, {}, string, import("vue").VNodeProps & import("vue").AllowedComponentProps & import("vue").ComponentCustomProps, Readonly<import("vue").ExtractPropTypes<{
name: {
type: PropType<"$svg_symbolIds">;
default: string;
required: true;
};
}>>, {
name: "$svg_symbolIds";
}>;
}
}
`
Expand Down
22 changes: 15 additions & 7 deletions src/core/component.ts
Original file line number Diff line number Diff line change
@@ -1,8 +1,10 @@
import fs from 'fs/promises'
import path from 'path'
import fs from 'fs/promises'
import { compileTemplate } from '@vue/compiler-sfc'
import { dts, template } from './code'
export function compileComponent() {
import type { Options } from '../types'
import { dts, golbalDts, template } from './code'
import { replace } from './utils'
export function compileComponent(componentName: string) {
let { code } = compileTemplate({
source: template,
id: '__svg-icon__',
Expand All @@ -12,7 +14,7 @@ export function compileComponent() {
code = code.replace(/export/g, '')
code += `
\nexport default{
name: 'SvgIcon',
name: "${componentName}",
props: {
name: {
type: String,
Expand All @@ -25,7 +27,13 @@ export function compileComponent() {
return code
}

export function genDts(symbolIds: Set<string>, dtsDir: string) {
const processedDts = dts.replace(/\$svg_symbolIds/g, Array.from(symbolIds).join('" | "'))
fs.writeFile(path.resolve(dtsDir, 'svg-icon.d.ts'), processedDts)
export function genDts(symbolIds: Set<string>, options: Options) {
fs.writeFile(
path.resolve(options.dtsDir!, './svg-icon.d.ts'),
replace(dts, symbolIds, options.componentName!),
)
fs.writeFile(
path.resolve(options.dtsDir!, './svg-icon-global.d.ts'),
replace(golbalDts, symbolIds, options.componentName!),
)
}
19 changes: 16 additions & 3 deletions src/core/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -9,10 +9,23 @@ import { LOAD_EVENT, MODULE_NAME, UPDATE_EVENT } from './constants'
let virtualModuleCode = ''
let TransformPluginContext

function resolveOptions(options: Options): Options {
const defaultOptions = {
componentName: 'SvgIcon',
dtsDir: process.cwd(),
svgSpriteDomId: '__svg__icons__dom__',
}
return {
...defaultOptions,
...options,
}
}

export default createUnplugin<Options | undefined>(options => ({
name: 'unplugin-svg-component',
async buildStart() {
virtualModuleCode = await createCode(options!, false)
options = resolveOptions(options!)
virtualModuleCode = await createCode(options, false)
},
resolveId(id: string) {
if (id === MODULE_NAME)
Expand Down Expand Up @@ -58,12 +71,12 @@ export default createUnplugin<Options | undefined>(options => ({
}))

async function createCode(options: Options, hmr: boolean) {
const componentCode = compileComponent()
const componentCode = compileComponent(options.componentName!)
await createSvgSprite(options)
const svgSpriteDomId = options.svgSpriteDomId || '__svg__icons__dom__'

if (options?.dts)
genDts(symbolIds, options.dtsDir || process.cwd())
genDts(symbolIds, options)

const hmrCode = `
if (import.meta.hot) {
Expand Down
10 changes: 10 additions & 0 deletions src/core/utils.ts
Original file line number Diff line number Diff line change
Expand Up @@ -11,3 +11,13 @@ export function debounce(fn: (...args: any) => void, delay: number) {
}, delay)
}
}

export function replace(dts: string, symbolIds: Set<string>, componentName: string) {
return dts.replace(
/\$svg_symbolIds/g,
Array.from(symbolIds).join('" | "'),
).replace(
/\$component_name/g,
componentName,
)
}
1 change: 1 addition & 0 deletions src/types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,5 +4,6 @@ export interface Options {
dts?: boolean
dtsDir?: string
svgSpriteDomId?: string
componentName?: string
}

0 comments on commit 9a0ce2a

Please sign in to comment.