feat: vite-plugin-icons

This commit is contained in:
Anthony Fu 2020-12-24 17:26:37 +08:00
parent 8f18c8cc69
commit bbb1392db8
12 changed files with 67 additions and 145 deletions

View File

@ -52,7 +52,7 @@
### Icons
- [Iconify](https://iconify.design) - use icons from any icon sets [🔍Icônes](https://icones.netlify.app/)
- [PurgeIcons](https://github.com/antfu/purge-icons) - bundles only the icons that you use
- [vite-plugin-icons](https://github.com/antfu/vite-plugin-icons) - icons as Vue components
### Plugins

View File

@ -5,7 +5,6 @@
"build": "cross-env NODE_ENV=production vite-ssg build --script async"
},
"dependencies": {
"@iconify/iconify": "^2.0.0-rc.4",
"@vueuse/core": "^4.0.0",
"nprogress": "^0.2.0",
"vue": "^3.0.4",
@ -14,7 +13,7 @@
},
"devDependencies": {
"@antfu/eslint-config-vue": "^0.4.3",
"@iconify/json": "^1.1.275",
"@iconify/json": "^1.1.276",
"@purge-icons/generated": "^0.4.1",
"@tailwindcss/typography": "^0.3.1",
"@types/nprogress": "^0.2.0",
@ -26,17 +25,17 @@
"cross-env": "^7.0.3",
"eslint": "^7.16.0",
"markdown-it-shiki": "^0.0.2",
"pnpm": "^5.13.7",
"pnpm": "^5.14.1",
"postcss-nested": "^5.0.3",
"tailwindcss": "^2.0.2",
"typescript": "^4.1.3",
"vite": "^1.0.0-rc.13",
"vite-plugin-components": "^0.5.0",
"vite-plugin-components": "^0.5.5",
"vite-plugin-icons": "^0.1.0",
"vite-plugin-md": "^0.1.5",
"vite-plugin-purge-icons": "^0.4.5",
"vite-plugin-pwa": "^0.1.7",
"vite-plugin-voie": "^0.4.1",
"vite-ssg": "^0.0.12",
"vite-ssg": "^0.1.0",
"voie-pages": "^0.4.0"
},
"pnpm": {

View File

@ -1,5 +1,4 @@
dependencies:
'@iconify/iconify': 2.0.0-rc.4
'@vueuse/core': 4.0.0_vue@3.0.4
nprogress: 0.2.0
vue: 3.0.4
@ -7,7 +6,7 @@ dependencies:
vue-router: 4.0.1_vue@3.0.4
devDependencies:
'@antfu/eslint-config-vue': 0.4.3_eslint@7.16.0+typescript@4.1.3
'@iconify/json': 1.1.275
'@iconify/json': 1.1.276
'@purge-icons/generated': 0.4.1
'@tailwindcss/typography': 0.3.1_tailwindcss@2.0.2
'@types/nprogress': 0.2.0
@ -19,17 +18,17 @@ devDependencies:
cross-env: 7.0.3
eslint: 7.16.0
markdown-it-shiki: 0.0.2
pnpm: 5.13.7
pnpm: 5.14.1
postcss-nested: 5.0.3
tailwindcss: 2.0.2_autoprefixer@10.1.0
typescript: 4.1.3
vite: 1.0.0-rc.13
vite-plugin-components: 0.5.0
vite-plugin-components: 0.5.5
vite-plugin-icons: 0.1.0_78438b9b9e7d51ac05d4f12c7eddfe12
vite-plugin-md: 0.1.5_@vue+compiler-sfc@3.0.4
vite-plugin-purge-icons: 0.4.5
vite-plugin-pwa: 0.1.7
vite-plugin-voie: 0.4.1_b4f890ebcd2c7fb57691a875170d0d78
vite-ssg: 0.0.12_fc727f10f0d17e293defdef0a51ff799
vite-ssg: 0.1.0_fc727f10f0d17e293defdef0a51ff799
voie-pages: 0.4.0_vue@3.0.4
lockfileVersion: 5.2
overrides:
@ -1066,22 +1065,18 @@ packages:
dev: true
resolution:
integrity: sha512-tAag0jEcjwH+P2quUfipd7liWCNX2F8NvYjQp2wtInsZxnMlypdw0FtAOLxtvvkO+GSRRbmNi8m/5y42PQJYCQ==
/@iconify/iconify/2.0.0-rc.1:
dev: true
resolution:
integrity: sha512-ji5H04VjYtR4seIEgVVLPxg1KRhrFquOiyfPyLVS6vYPkuqV6bcWdssi05YSmf/OAzG4E7Qsg80/bOKyd5tYTw==
/@iconify/iconify/2.0.0-rc.2:
dev: true
resolution:
integrity: sha512-BybEHU5/I9EQ0CcwKAqmreZ2bMnAXrqLCTptAc6vPetHMbrXdZfejP5mt57e/8PNSt/qE7BHniU5PCYA+PGIHw==
/@iconify/iconify/2.0.0-rc.4:
dev: false
resolution:
integrity: sha512-YCSECbeXKFJEIVkKgKMjUzJ439ysufmL/a31B1j7dCvnHaBWsX9J4XehhJgg/aTy3yvhHaVhI6xt1kSMZP799A==
/@iconify/json/1.1.275:
/@iconify/json-tools/1.0.10:
dev: true
resolution:
integrity: sha512-Nt6tXJpZFd/gFRV24BvmlIdxnbMxgshIKFPQwOWgeVjKiOKEwiBKjXUzBE74As7/Olps/ac1gEB40N9/DGOJ3Q==
integrity: sha512-LFelJDOLZ6JHlmlAkgrvmcu4hpNPB91KYcr4f60D/exzU1eNOb4/KCVHIydGHIQFaOacIOD+Xy+B7P1z812cZg==
/@iconify/json/1.1.276:
dev: true
resolution:
integrity: sha512-Ra/mGT+n38vhi/i1cjsPYOmSR2d6rNIXZ+OsrIWp9J35zAPQ93sSTQMpTyxZdLu3QxU0vYwtcaC7h/Y1/3H3wg==
/@koa/cors/3.1.0:
dependencies:
vary: 1.1.2
@ -1114,16 +1109,6 @@ packages:
node: '>= 8'
resolution:
integrity: sha512-1V9XOY4rDW0rehzbrcqAmHnz8e7SKvX27gh8Gt2WgB0+pdzdiLV83p72kZPU+jvMbS1qU5mauP2iOvO8rhmurQ==
/@purge-icons/core/0.4.5:
dependencies:
'@iconify/iconify': 2.0.0-rc.1
axios: 0.21.0_debug@4.3.1
debug: 4.3.1
fast-glob: 3.2.4
fs-extra: 9.0.1
dev: true
resolution:
integrity: sha512-8YMtl343dFA+dyslxwrvN7zx5uGf8ezFbBjtLOocR638ozUNJY1+cnYRcbbiM2hFkwrptPyyzzEFhdgYeGZhSQ==
/@purge-icons/generated/0.4.1:
dependencies:
'@iconify/iconify': 2.0.0-rc.2
@ -1975,14 +1960,6 @@ packages:
dev: true
resolution:
integrity: sha512-xh1Rl34h6Fi1DC2WWKfxUTVqRsNnr6LsKz2+hfwDxQJWmrx8+c7ylaqBMcHfl1U1r2dsifOvKX3LQuLNZ+XSvA==
/axios/0.21.0_debug@4.3.1:
dependencies:
follow-redirects: 1.13.1_debug@4.3.1
dev: true
peerDependencies:
debug: '*'
resolution:
integrity: sha512-fmkJBknJKoZwem3/IKSSLpkdNXZeBu5Q7GA/aRsr2btgrptmSCxi2oFjZHqGdK9DoTil9PIHlPIZw2EcRJXRvw==
/babel-eslint/10.1.0_eslint@7.16.0:
dependencies:
'@babel/code-frame': 7.10.4
@ -4798,13 +4775,13 @@ packages:
node: '>=4'
resolution:
integrity: sha512-Nc3IT5yHzflTfbjgqWcCPpo7DaKy4FnpB0l/zCAW0Tc7jxAiuqSxHasntB3D7887LSrA93kDJ9IXovxJYxyLCA==
/pnpm/5.13.7:
/pnpm/5.14.1:
dev: true
engines:
node: '>=10.16'
hasBin: true
resolution:
integrity: sha512-ejYJR8iK+IkN4HsHtwal9EB3K4N5AllQ86X6DwCaGWMrzDZNEwfAQYvyeqY35ElCvOd/M5W3ewvnrGpilGEgGQ==
integrity: sha512-zxdmGEMcvJq5JU4lb3s48xbDnT9C7PHk/aOO7kefgA2LklOuEakRx2sKyGyWRykyQMtOS7h1rD4kdCWsOrh6Hg==
/postcss-discard-comments/4.0.2:
dependencies:
postcss: 8.2.1
@ -5282,15 +5259,6 @@ packages:
rollup: '*'
resolution:
integrity: sha512-C1avEmnXC8cC4aAQ5dB63O9oQf7IrhEHc98bQw9Qd6H36FxtZooLCvVfcO4SNYrqaNrzH3ErucQt/zdFSLPHNw==
/rollup-plugin-purge-icons/0.4.5:
dependencies:
'@purge-icons/core': 0.4.5
'@purge-icons/generated': 0.4.1
dev: true
engines:
node: '>= 12'
resolution:
integrity: sha512-rbc32qXlFSOoiMgC+e38KgLo6+trl+hIafxJc4fDNakCIaixRhk8tsFIIuy4q3P2R3/lLHQYYGu5IJhI8223Bg==
/rollup-plugin-terser/5.3.1_rollup@1.32.1:
dependencies:
'@babel/code-frame': 7.10.4
@ -6062,14 +6030,25 @@ packages:
'0': node >=0.6.0
resolution:
integrity: sha1-OhBcoXBTr1XW4nDB+CiGguGNpAA=
/vite-plugin-components/0.5.0:
/vite-plugin-components/0.5.5:
dependencies:
debug: 4.3.1
fast-glob: 3.2.4
minimatch: 3.0.4
dev: true
resolution:
integrity: sha512-9IVhnZKhKPvbTtFDvl5jNkgUQ/ZKTQiDPvnEjBdOnkdXkOiW6thP1lqs09EZbECwR5eMKL0euCJVW5n9oUK50Q==
integrity: sha512-5yItxOvFCp9GFgX/NaN8r91W0IyG1rX1m2QPCsq4tnPy5PWpE83oz8ZyU8Q7twocffuBgpk93KxZ3r24Kx2lOg==
/vite-plugin-icons/0.1.0_78438b9b9e7d51ac05d4f12c7eddfe12:
dependencies:
'@iconify/json': 1.1.276
'@iconify/json-tools': 1.0.10
'@vue/compiler-sfc': 3.0.4_vue@3.0.4
dev: true
peerDependencies:
'@iconify/json': '*'
'@vue/compiler-sfc': ^3.0.2
resolution:
integrity: sha512-bnAuaBCF3YxS4S+npPG65jakYyJXShltldJt1UC1yJL/u6dwLd2P43xlqc6p6HhWaP077/SOm0/hurSUFPKRpA==
/vite-plugin-md/0.1.5_@vue+compiler-sfc@3.0.4:
dependencies:
'@vue/compiler-sfc': 3.0.4_vue@3.0.4
@ -6080,16 +6059,6 @@ packages:
'@vue/compiler-sfc': ^3.0.2
resolution:
integrity: sha512-aF75Nm6AydNLTlcEh/tcTxE6qyasvAk896oBj80+4JxsaR9mvygu7rp0KApBPprtFM08gtVhO8LUewTfztYRzg==
/vite-plugin-purge-icons/0.4.5:
dependencies:
'@purge-icons/core': 0.4.5
'@purge-icons/generated': 0.4.1
rollup-plugin-purge-icons: 0.4.5
dev: true
engines:
node: '>= 12'
resolution:
integrity: sha512-56Jj+mJXsZJpHrQ89D/mYJFFvYalV6rLnAdj7Q7q0w9PVFHBHa2E2zdQBOC0fHB+VM/QLgzVqT7gJd0PTuj3Ag==
/vite-plugin-pwa/0.1.7:
dependencies:
debug: 4.3.1
@ -6111,7 +6080,7 @@ packages:
vue-router: ^4.0.0-beta.4
resolution:
integrity: sha512-oGynRoj+CwQ4bcXPDDI9l18GgFl1yyjc8u3nmrDhMzWdu3EY8BTL9NLxA028tkbRGMvs/lUJJXnFzp//yApY2Q==
/vite-ssg/0.0.12_fc727f10f0d17e293defdef0a51ff799:
/vite-ssg/0.1.0_fc727f10f0d17e293defdef0a51ff799:
dependencies:
'@vue/compiler-sfc': 3.0.4_vue@3.0.4
'@vue/server-renderer': 3.0.4_vue@3.0.4
@ -6130,7 +6099,7 @@ packages:
vue: ^3.0.4
vue-router: ^4.0.1
resolution:
integrity: sha512-AcwzLodEA4SxCeTGXH/ABpTO8MAmLr+oe5UYOoPTXtpf2XsUHPi029JyJRhNqH+7R18dCdP/SUlh1+RFGEVKUw==
integrity: sha512-SjioOdKnGZ/ka0Qbn8QT0QQaSmF7nlhxCW+EBNkb887OaoIcnIg+z69KfxMcF+qe1jBDCnJ6iTacmfWOdLiktg==
/vite/1.0.0-rc.13:
dependencies:
'@babel/parser': 7.12.10
@ -6595,8 +6564,7 @@ packages:
integrity: sha512-faQrqNMzcPCHGVC2aaOINk13K+aaBDUPjGWl0teOXywElLjyVAB6Oe2jj62jHYtwsU49jXhScYbvPENK+6zAvQ==
specifiers:
'@antfu/eslint-config-vue': ^0.4.3
'@iconify/iconify': ^2.0.0-rc.4
'@iconify/json': ^1.1.275
'@iconify/json': ^1.1.276
'@purge-icons/generated': ^0.4.1
'@tailwindcss/typography': ^0.3.1
'@types/nprogress': ^0.2.0
@ -6610,17 +6578,17 @@ specifiers:
eslint: ^7.16.0
markdown-it-shiki: ^0.0.2
nprogress: ^0.2.0
pnpm: ^5.13.7
pnpm: ^5.14.1
postcss-nested: ^5.0.3
tailwindcss: ^2.0.2
typescript: ^4.1.3
vite: ^1.0.0-rc.13
vite-plugin-components: ^0.5.0
vite-plugin-components: ^0.5.5
vite-plugin-icons: ^0.1.0
vite-plugin-md: ^0.1.5
vite-plugin-purge-icons: ^0.4.5
vite-plugin-pwa: ^0.1.7
vite-plugin-voie: ^0.4.1
vite-ssg: ^0.0.12
vite-ssg: ^0.1.0
voie-pages: ^0.4.0
vue: ^3.0.4
vue-i18n: 9.0.0-beta.8

View File

@ -1,23 +1,24 @@
<template>
<nav class="text-xl mt-6">
<router-link class="icon-btn mx-2" to="/" :title="t('button.home')">
<Icon icon="carbon:campsite" class="inline-block" />
<carbon-campsite />
</router-link>
<a class="icon-btn mx-2" @click="isDark = !isDark" :title="t('button.toggle_dark')">
<Icon :icon="isDark ? 'carbon:moon' : 'carbon:sun'" class="inline-block" />
<a class="icon-btn mx-2" :title="t('button.toggle_dark')" @click="isDark = !isDark">
<carbon-moon v-if="isDark" />
<carbon-sun v-else />
</a>
<a class="icon-btn mx-2" @click="toggleLocales" :title="t('button.toggle_langs')">
<Icon icon="carbon:language" class="inline-block" />
<a class="icon-btn mx-2" :title="t('button.toggle_langs')" @click="toggleLocales">
<carbon-language />
</a>
<router-link class="icon-btn mx-2" to="/about" :title="t('button.about')">
<Icon icon="carbon:dicom-overlay" class="inline-block" />
<carbon-dicom-overlay />
</router-link>
<a class="icon-btn mx-2" rel="noreferrer" href="https://github.com/antfu/vitesse" target="_blank" title="GitHub">
<Icon icon="carbon:logo-github" class="inline-block" />
<carbon-logo-github />
</a>
</nav>
</template>

View File

@ -1,49 +0,0 @@
<template>
<div ref="el" :class="$attrs.class" style="vertical-align: text-bottom" />
</template>
<script setup="props" lang="ts">
import { watch, ref, onMounted, nextTick, defineProps } from 'vue'
import Iconify from '@purge-icons/generated'
const props = defineProps({
icon: {
type: String,
required: true,
},
})
const el = ref<HTMLElement | null>(null)
const update = async() => {
if (el.value) {
await nextTick()
const svg = Iconify.renderSVG(props.icon, {})
if (svg) {
el.value.textContent = ''
el.value.appendChild(svg)
}
else {
const span = document.createElement('span')
span.className = 'iconify'
span.dataset.icon = props.icon
el.value.textContent = ''
el.value.appendChild(span)
}
}
}
watch(() => props.icon, update, { flush: 'post' })
onMounted(update)
</script>
<style>
span.iconify {
background: #5551;
border-radius: 100%;
min-width: 1em;
min-height: 1em;
display: block;
}
</style>

View File

@ -3,12 +3,8 @@
Components in this dir will be auto-registered and on-demand, powered by [`vite-plugin-components`](https://github.com/antfu/vite-plugin-components).
### `Icon.vue`
### Icons
You can uses Icons with the following syntax
You can uses icons from almost any icon sets by the power of [Iconify](https://iconify.design/).
```html
<Icon icon='mdi:account'/>
```
The icon id follows the rules in [Iconify](https://iconify.design/) which you can use any icons from the supported icon sets. It will only bundles the icons you use, check out [PurgeIcons](https://github.com/antfu/purge-icons) for more details.
It will only bundles the icons you use, check out [vite-plugin-icons](https://github.com/antfu/vite-plugin-icons) for more details.

View File

@ -42,6 +42,7 @@ html.dark {
@apply inline-block cursor-pointer select-none
opacity-75 transition duration-200 ease-in-out
hover:opacity-100 hover:text-teal-600;
font-size: 0.9em;
}
.shiki {

View File

@ -1,6 +1,6 @@
<div class="text-4xl text-center">
<div class="text-4xl text-center -mb-4">
<!-- You can use Vue components inside markdown -->
<Icon class="iconify inline-block" icon="carbon:dicom-overlay" />
<carbon-dicom-overlay class="inline-block" />
</div>
### About

View File

@ -1,7 +1,7 @@
<template>
<div>
<p class="text-4xl">
<Icon class="iconify inline-block" icon="carbon:campsite" />
<carbon-campsite class="inline-block" />
</p>
<p>
<a rel="noreferrer" href="https://github.com/antfu/vitesse" target="_blank">
@ -24,7 +24,7 @@
style="width: 250px"
@keydown.enter="go"
>
<label class="hidden" for="input">{{t('intro.whats-your-name')}}</label>
<label class="hidden" for="input">{{ t('intro.whats-your-name') }}</label>
<div>
<button

View File

@ -1,2 +0,0 @@
// import icons data generated by PurgeIcons
import '@purge-icons/generated'

View File

@ -1,6 +1,5 @@
import { App } from 'vue'
import installI18n from './i18n'
import './icons'
export default (app: App) => {
installI18n(app)

View File

@ -1,7 +1,7 @@
import path from 'path'
import { UserConfig } from 'vite'
import Voie from 'vite-plugin-voie'
import PurgeIcons from 'vite-plugin-purge-icons'
import ViteIcons, { ViteIconsResolver } from 'vite-plugin-icons'
import ViteComponents from 'vite-plugin-components'
import Markdown from 'vite-plugin-md'
import Shiki from 'markdown-it-shiki'
@ -52,10 +52,19 @@ const config: UserConfig = {
customLoaderMatcher({ path }) {
return path.endsWith('.md')
},
// auto import icons
customComponentResolvers: [
// https://github.com/antfu/vite-plugin-icons
ViteIconsResolver({
componentPrefix: '',
// enabledCollections: ['carbon']
}),
],
}),
// https://github.com/antfu/purge-icons
PurgeIcons(),
// https://github.com/antfu/vite-plugin-icons
ViteIcons(),
// https://github.com/antfu/vite-plugin-pwa
VitePWA({