├── .prettierignore ├── .eslintignore ├── pnpm-workspace.yaml ├── src ├── index.ts ├── live2d │ ├── components │ │ ├── live2d.ts │ │ └── Live2dComponent.vue │ └── index.ts └── waline │ ├── index.ts │ └── components │ └── Waline.ts ├── docs ├── public │ ├── logo.png │ └── logo.svg ├── package.json ├── .vitepress │ ├── theme │ │ └── index.js │ └── config.js ├── index.md └── guide │ ├── index.md │ └── card.md ├── .editorconfig ├── .gitignore ├── .github └── workflows │ └── release.yml ├── .prettierrc ├── tsconfig.json ├── scripts ├── verifyCommit.ts └── rollup.config.js ├── LICENSE ├── CHANGELOG.md ├── .eslintrc.cjs ├── README.md └── package.json /.prettierignore: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /.eslintignore: -------------------------------------------------------------------------------- 1 | node_modules 2 | -------------------------------------------------------------------------------- /pnpm-workspace.yaml: -------------------------------------------------------------------------------- 1 | packages: 2 | - docs 3 | -------------------------------------------------------------------------------- /src/index.ts: -------------------------------------------------------------------------------- 1 | export * from './waline' 2 | export * from './live2d' 3 | -------------------------------------------------------------------------------- /docs/public/logo.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/xinlei3166/vitepress-theme-website/HEAD/docs/public/logo.png -------------------------------------------------------------------------------- /.editorconfig: -------------------------------------------------------------------------------- 1 | # http://editorconfig.org 2 | root = true 3 | 4 | [*] 5 | indent_style = space 6 | indent_size = 2 7 | end_of_line = lf 8 | charset = utf-8 9 | trim_trailing_whitespace = true 10 | insert_final_newline = true 11 | 12 | [*.md] 13 | trim_trailing_whitespace = false 14 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | node_modules 2 | .DS_Store 3 | dist 4 | dist-ssr 5 | *.local 6 | .cache 7 | .temp 8 | docs/.vitepress/cache 9 | 10 | # local env files 11 | .env.local 12 | .env.*.local 13 | 14 | # Log files 15 | npm-debug.log* 16 | yarn-debug.log* 17 | yarn-error.log* 18 | pnpm-debug.log* 19 | 20 | # Editor directories and files 21 | .idea 22 | .vscode 23 | *.suo 24 | *.ntvs* 25 | *.njsproj 26 | *.sln 27 | *.sw? 28 | -------------------------------------------------------------------------------- /docs/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "vitepress-theme-website-docs", 3 | "version": "0.1.0", 4 | "private": true, 5 | "type": "module", 6 | "scripts": { 7 | "docs:dev": "vitepress dev --host", 8 | "docs:build": "vitepress build", 9 | "docs:serve": "vitepress serve --host" 10 | }, 11 | "dependencies": {}, 12 | "devDependencies": { 13 | "vue": "^3.4.21", 14 | "vitepress": "^1.0.2", 15 | "vitepress-theme-website": "workspace:*" 16 | } 17 | } 18 | -------------------------------------------------------------------------------- /docs/.vitepress/theme/index.js: -------------------------------------------------------------------------------- 1 | import DefaultTheme from 'vitepress/theme' 2 | import { useWaline, useLive2d } from 'vitepress-theme-website' 3 | 4 | export default { 5 | ...DefaultTheme, 6 | // Layout() { 7 | // return h(DefaultTheme.Layout, null, { 8 | // 'home-features-after': () => h(HomeSponsors), 9 | // }) 10 | // }, 11 | enhanceApp(ctx) {}, 12 | setup() { 13 | useWaline({ 14 | serverURL: 'https://waline.xinlei3166.com' 15 | }) 16 | useLive2d() 17 | } 18 | } 19 | -------------------------------------------------------------------------------- /.github/workflows/release.yml: -------------------------------------------------------------------------------- 1 | name: Release 2 | 3 | permissions: 4 | contents: write 5 | 6 | on: 7 | push: 8 | tags: 9 | - 'v*' 10 | 11 | jobs: 12 | release: 13 | runs-on: ubuntu-latest 14 | steps: 15 | - uses: actions/checkout@v3 16 | with: 17 | fetch-depth: 0 18 | 19 | - uses: actions/setup-node@v3 20 | with: 21 | node-version: 16.x 22 | 23 | - run: npx changelogithub 24 | env: 25 | GITHUB_TOKEN: ${{secrets.GITHUB_TOKEN}} 26 | -------------------------------------------------------------------------------- /.prettierrc: -------------------------------------------------------------------------------- 1 | printWidth: 100 2 | semi: false 3 | singleQuote: true 4 | proseWrap: "never" 5 | arrowParens: "avoid" 6 | bracketSpacing: true 7 | #disableLanguages": ["custom"] 8 | endOfLine: "auto" 9 | eslintIntegration: true 10 | htmlWhitespaceSensitivity: "ignore" # 属性标签格式化符合预期 11 | ignorePath: ".prettierignore" 12 | jsxBracketSameLine: false 13 | jsxSingleQuote: false 14 | #parser: vue 15 | stylelintIntegration: true 16 | trailingComma: "none" 17 | tslintIntegration: false 18 | vueIndentScriptAndStyle: false 19 | embeddedLanguageFormatting: "auto" 20 | -------------------------------------------------------------------------------- /tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "compilerOptions": { 3 | "target": "esnext", 4 | "module": "esnext", 5 | "moduleResolution": "node", 6 | "strict": true, 7 | "jsx": "preserve", 8 | "sourceMap": true, 9 | "resolveJsonModule": true, 10 | "esModuleInterop": true, 11 | "allowJs": true, 12 | "noImplicitAny": true, 13 | "lib": [ 14 | "esnext", 15 | "dom" 16 | ], 17 | "types": ["node"] 18 | // "baseUrl": ".", 19 | // "paths": { 20 | // "@/*": ["./src/*"] 21 | // } 22 | }, 23 | "include": ["src/**/*.ts", "src/**/*.d.ts", "src/**/*.tsx", "src/**/*.vue"], 24 | "exclude": ["node_modules"] 25 | } 26 | -------------------------------------------------------------------------------- /src/live2d/components/live2d.ts: -------------------------------------------------------------------------------- 1 | import { createApp, h } from 'vue' 2 | import Live2d from './Live2dComponent.vue' 3 | 4 | Live2d.init = (props: any) => { 5 | const container = document.createElement('div') 6 | container.classList.add('live2d-wrap') 7 | const parent = document.querySelector('#app') 8 | if (!parent) return 9 | parent.appendChild(container) 10 | 11 | const app = createApp({ 12 | render() { 13 | return h(Live2d, { 14 | ...props 15 | }) 16 | } 17 | }) 18 | 19 | app.mount(container) 20 | 21 | return { 22 | destroy() { 23 | app.unmount() 24 | if (container.parentNode) { 25 | container.parentNode.removeChild(container) 26 | } 27 | } 28 | } 29 | } 30 | 31 | export default Live2d 32 | -------------------------------------------------------------------------------- /src/waline/index.ts: -------------------------------------------------------------------------------- 1 | import type { WalineInitOptions, WalineInstance } from '@waline/client' 2 | import { onMounted, onBeforeUnmount, watch } from 'vue' 3 | import { useRoute } from 'vitepress' 4 | import Waline from './components/Waline' 5 | 6 | export interface WalineOptions extends WalineInitOptions { 7 | selector?: string // 非Waline参数,el挂载的容器,默认.VPDoc .content-container。 8 | } 9 | 10 | export const useWaline = (walineOptions: WalineOptions) => { 11 | let waline: WalineInstance 12 | const route = useRoute() 13 | 14 | onMounted(() => { 15 | updateWaline() 16 | }) 17 | 18 | onBeforeUnmount(() => waline?.destroy()) 19 | 20 | function updateWaline() { 21 | if (waline) { 22 | waline?.destroy() 23 | } 24 | setTimeout(() => { 25 | if (!document) return 26 | waline = Waline.newInstance({ walineOptions }) 27 | }, 500) 28 | } 29 | 30 | watch(() => route.path, updateWaline) 31 | } 32 | 33 | export default useWaline 34 | -------------------------------------------------------------------------------- /scripts/verifyCommit.ts: -------------------------------------------------------------------------------- 1 | // Invoked on the commit-msg git hook by simple-git-hooks. 2 | 3 | import { readFileSync } from 'fs' 4 | import colors from 'picocolors' 5 | 6 | // get $1 from commit-msg script 7 | const msgPath = process.argv[2] 8 | const msg = readFileSync(msgPath, 'utf-8').trim() 9 | 10 | // Merge branch 11 | const mergeRE = /^Merge branch.*/ 12 | const commitRE = 13 | /^(revert: )?(feat|fix|docs|style|refactor|perf|test|chore|revert|release)(\(.+\))?: .{1,50}/ 14 | 15 | if (!mergeRE.test(msg) && !commitRE.test(msg)) { 16 | console.log() 17 | console.error( 18 | ` ${colors.bgRed(colors.white(' ERROR '))} ${colors.red( 19 | `invalid commit message format.` 20 | )}\n\n` + 21 | colors.red( 22 | ` Proper commit message format is required for automated changelog generation. Examples:\n\n` 23 | ) + 24 | ` ${colors.green(`feat: add 'comments' option`)}\n` + 25 | ` ${colors.green(`fix: handle events on blur (close #28)`)}\n` 26 | ) 27 | process.exit(1) 28 | } 29 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | The MIT License (MIT) 2 | 3 | Copyright (c) 2023-present, 君惜 (xinlei3166) 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in 13 | all copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 21 | THE SOFTWARE. 22 | -------------------------------------------------------------------------------- /src/live2d/index.ts: -------------------------------------------------------------------------------- 1 | import { onBeforeUnmount, onMounted, watch } from 'vue' 2 | import Live2d from './components/live2d' 3 | import { useRoute } from 'vitepress' 4 | 5 | const defaultLive2dOptions = { 6 | enable: true, 7 | model: { 8 | url: 'https://raw.githubusercontent.com/iCharlesZ/vscode-live2d-models/master/model-library/hibiki/hibiki.model.json' 9 | }, 10 | display: { 11 | position: 'right', 12 | width: '135px', 13 | height: '300px', 14 | xOffset: '35px', 15 | yOffset: '5px' 16 | }, 17 | mobile: { 18 | show: true 19 | }, 20 | react: { 21 | opacity: 0.8 22 | } 23 | } 24 | 25 | export type Live2dOptions = Partial 26 | 27 | export const useLive2d = (live2dOptions: Live2dOptions = {}) => { 28 | let live2d: any 29 | const route = useRoute() 30 | 31 | onMounted(() => { 32 | init() 33 | }) 34 | 35 | onBeforeUnmount(() => live2d?.destroy()) 36 | 37 | function init() { 38 | if (live2d) return 39 | setTimeout(() => { 40 | if (!document) return 41 | live2d = Live2d.init({ live2dOptions: { ...defaultLive2dOptions, ...live2dOptions } }) 42 | }, 500) 43 | } 44 | 45 | watch(() => route.path, init) 46 | } 47 | 48 | export default useLive2d 49 | -------------------------------------------------------------------------------- /CHANGELOG.md: -------------------------------------------------------------------------------- 1 | ## [1.0.8](https://github.com/xinlei3166/vitepress-theme-website/compare/v1.0.7...v1.0.8) (2024-04-03) 2 | 3 | 4 | 5 | ## [1.0.7](https://github.com/xinlei3166/vitepress-theme-website/compare/v1.0.6...v1.0.7) (2024-04-03) 6 | 7 | 8 | ### Bug Fixes 9 | 10 | * 修复 live2d 打包后模型显示不全问题; ([ae8297e](https://github.com/xinlei3166/vitepress-theme-website/commit/ae8297eaa115519cf2eb00bc26278568e5e1a8f4)) 11 | 12 | 13 | 14 | ## [1.0.6](https://github.com/xinlei3166/vitepress-theme-website/compare/v1.0.5...v1.0.6) (2023-08-01) 15 | 16 | 17 | ### Features 18 | 19 | * optimized code ([b13cfa1](https://github.com/xinlei3166/vitepress-theme-website/commit/b13cfa1fea29a506cbd5bbdd1cd3280f3872bfc5)) 20 | 21 | 22 | 23 | ## [1.0.5](https://github.com/xinlei3166/vitepress-theme-website/compare/v1.0.4...v1.0.5) (2023-05-19) 24 | 25 | 26 | 27 | ## [1.0.4](https://github.com/xinlei3166/vitepress-theme-website/compare/v1.0.3...v1.0.4) (2023-05-17) 28 | 29 | 30 | 31 | ## [1.0.3](https://github.com/xinlei3166/vitepress-theme-website/compare/v1.0.2...v1.0.3) (2023-05-17) 32 | 33 | 34 | 35 | ## [1.0.2](https://github.com/xinlei3166/vitepress-theme-website/compare/v1.0.1...v1.0.2) (2023-05-17) 36 | 37 | 38 | 39 | ## 1.0.1 (2023-05-17) 40 | 41 | 42 | 43 | -------------------------------------------------------------------------------- /docs/index.md: -------------------------------------------------------------------------------- 1 | --- 2 | layout: home 3 | 4 | title: Vitepress Theme Website 5 | titleTemplate: 一个基于 Vitepress 的主题插件,集成评论 Waline、Live2D 看板娘。 6 | 7 | hero: 8 | name: Vitepress 9 | # text: Vitepress Theme Website。 10 | tagline: 一个基于 Vitepress 的主题插件,集成评论 Waline、Live2D 看板娘。 11 | image: 12 | src: /logo.svg 13 | alt: heroImage 14 | actions: 15 | - theme: brand 16 | text: Get Started 17 | link: /guide/ 18 | - theme: alt 19 | text: Learn More 20 | link: /guide/ 21 | 22 | features: 23 | - icon: ⚡️ 24 | title: "Vite: The DX that can't be beat" 25 | details: Feel the speed of Vite. Instant server start and lightning fast HMR that stays fast regardless of the app size. 26 | - icon: 💡 27 | title: Designed to be simplicity first 28 | details: With Markdown-centered content, it's built to help you focus on writing and deployed with minimum configuration. 29 | - icon: 🛠️ 30 | title: Power of Vue meets Markdown 31 | details: Enhance your content with all the features of Vue in Markdown, while being able to customize your site with Vue. 32 | - icon: 🔑 33 | title: Fully static yet still dynamic 34 | details: Go wild with true SSG + SPA architecture. Static on page load, but engage users with 100% interactivity from there. 35 | --- 36 | -------------------------------------------------------------------------------- /src/waline/components/Waline.ts: -------------------------------------------------------------------------------- 1 | import { createApp, ref, defineComponent, h, onMounted } from 'vue' 2 | import { init } from '@waline/client' 3 | import '@waline/client/waline.css' 4 | 5 | export const WalineComponent = defineComponent({ 6 | name: 'WalineComment', 7 | props: { 8 | walineOptions: { type: Object, default: () => ({}) } 9 | }, 10 | setup(props) { 11 | const walineRef = ref() 12 | onMounted(() => { 13 | init({ 14 | el: '#waline', 15 | serverURL: props.walineOptions.serverURL, 16 | login: props.walineOptions.login || 'force' 17 | }) 18 | }) 19 | 20 | return () => h('div', { id: 'waline', ref: el => (walineRef.value = el) }) 21 | } 22 | }) 23 | 24 | WalineComponent.newInstance = (props: any) => { 25 | const { selector = '.VPDoc .content-container' } = props.walineOptions 26 | 27 | const container = document.createElement('div') 28 | container.classList.add('waline-wrap') 29 | container.style.paddingTop = '48px' 30 | const parent = document.querySelector(selector) 31 | if (!parent) return 32 | parent.appendChild(container) 33 | 34 | const app = createApp({ 35 | render() { 36 | return h(WalineComponent, { 37 | ...props 38 | }) 39 | } 40 | }) 41 | 42 | app.mount(container) 43 | 44 | return { 45 | destroy() { 46 | app.unmount() 47 | if (container.parentNode) { 48 | container.parentNode.removeChild(container) 49 | } 50 | } 51 | } 52 | } 53 | 54 | export default WalineComponent 55 | -------------------------------------------------------------------------------- /docs/public/logo.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | -------------------------------------------------------------------------------- /docs/guide/index.md: -------------------------------------------------------------------------------- 1 | # Card 2 | 3 | 常用的卡片布局。 4 | 5 | ## 基础用法 6 | 7 | 基础的卡片用法。 8 | 9 | :::demo 10 | 11 | ```vue 12 | 17 | 18 | 29 | 30 | 48 | ``` 49 | 50 | ::: 51 | 52 | 53 | ## Setup TypeScript 54 | 55 | setup typescript 用法。 56 | 57 | :::demo 58 | 59 | ```vue 60 | 65 | 66 | 75 | 76 | 94 | ``` 95 | 96 | ::: 97 | -------------------------------------------------------------------------------- /docs/guide/card.md: -------------------------------------------------------------------------------- 1 | # Card 2 | 3 | 常用的卡片布局。 4 | 5 | ## 基础用法 6 | 7 | 基础的卡片用法。 8 | 9 | :::demo 使用`size`、`style`属性来定义 Card 的样式。 10 | 11 | ```vue 12 | 17 | 18 | 29 | 30 | 47 | ``` 48 | 49 | ::: 50 | 51 | 52 | ## Setup TypeScript 53 | 54 | setup typescript 用法。 55 | 56 | :::demo 使用`size`、`style`属性来定义 Card 的样式。 57 | 58 | ```vue 59 | 64 | 65 | 74 | 75 | 92 | ``` 93 | 94 | ::: 95 | -------------------------------------------------------------------------------- /docs/.vitepress/config.js: -------------------------------------------------------------------------------- 1 | import { defineConfig } from 'vitepress' 2 | 3 | export default defineConfig({ 4 | // lang: 'en-US', 5 | title: 'Vitepress', 6 | description: '一个基于 Vitepress 的主题插件,集成评论Waline、Live2D看板娘。', 7 | 8 | lastUpdated: true, 9 | cleanUrls: 'without-subfolders', 10 | 11 | // base: '/', 12 | head: [ 13 | ['link', { rel: 'icon', type: 'image/svg+xml', href: '/logo.svg' }], 14 | ['script', { src: '/live2d.js' }], 15 | // ['link', { rel: 'icon', type: 'image/png', href: '/logo.png' }] 16 | ], 17 | 18 | markdown: { 19 | headers: { 20 | level: [0, 0] 21 | }, 22 | 23 | // options for markdown-it-anchor 24 | anchor: { permalink: false }, 25 | 26 | // options for markdown-it-toc 27 | toc: { includeLevel: [1, 2] }, 28 | }, 29 | 30 | vite: { 31 | build: { 32 | commonjsOptions: { 33 | transformMixedEsModules: true, 34 | }, 35 | } 36 | }, 37 | 38 | themeConfig: { 39 | outlineTitle: '本页目录', 40 | lastUpdatedText: '上次更新', 41 | logo: '/logo.svg', 42 | 43 | // nav 44 | nav: [ 45 | { text: '文档', link: '/guide/' } 46 | ], 47 | 48 | // sidebar 49 | sidebar: { '/guide/': [ 50 | { 51 | text: '文档', 52 | collapsible: false, 53 | items: [ 54 | { 55 | text: '指南', 56 | link: '/guide/' 57 | }, 58 | { 59 | text: '组件', 60 | link: '/guide/card' 61 | } 62 | ] 63 | } 64 | ] 65 | }, 66 | 67 | editLink: { 68 | pattern: 'https://github.com/xinlei3166/vitepress-theme-website/edit/main/docs/:path', 69 | text: '在 GitHub 上编辑此页' 70 | }, 71 | 72 | socialLinks: [ 73 | { icon: 'github', link: 'https://github.com/xinlei3166/vitepress-theme-website' } 74 | ], 75 | 76 | footer: { 77 | message: 'Released under the MIT License.', 78 | copyright: 'Copyright © 2023-present 君惜' 79 | } 80 | } 81 | }) 82 | -------------------------------------------------------------------------------- /.eslintrc.cjs: -------------------------------------------------------------------------------- 1 | module.exports = { 2 | parser: 'vue-eslint-parser', 3 | parserOptions: { 4 | parser: '@typescript-eslint/parser', // Specifies the ESLint parser 5 | ecmaVersion: 2020, // Allows for the parsing of modern ECMAScript features 6 | sourceType: 'module', // Allows for the use of imports 7 | ecmaFeatures: { 8 | tsx: true, 9 | jsx: true 10 | } 11 | }, 12 | env: { 13 | node: true, 14 | browser: true 15 | }, 16 | plugins: ['@typescript-eslint'], 17 | extends: [ 18 | 'plugin:@typescript-eslint/recommended', // Uses the recommended rules from the @typescript-eslint/eslint-plugin 19 | 'plugin:vue/vue3-recommended', 20 | 'plugin:prettier/recommended' // Enables eslint-plugin-prettier and eslint-config-prettier. This will display prettier errors as ESLint errors. Make sure this is always the last configuration in the extends array. 21 | ], 22 | rules: { 23 | // js 24 | 'no-console': process.env.NODE_ENV === 'production' ? 'warn' : 'off', 25 | 'no-debugger': process.env.NODE_ENV === 'production' ? 'warn' : 'off', 26 | 'no-alert': process.env.NODE_ENV === 'production' ? 'error' : 'off', 27 | 'no-tabs': 2, // 禁止使用tabs 28 | 'no-useless-escape': 0, 29 | 'no-var': 2, // 使用let和const代替var 30 | 'no-mixed-spaces-and-tabs': 2, // 不允许混用tab和空格 31 | 'no-useless-return': 0, 32 | 'arrow-parens': 0, 33 | 'prefer-const': 2, // 优先使用const 34 | eqeqeq: 2, // 必须使用全等 35 | camelcase: 0, // 禁用驼峰命名检测 36 | // ts 37 | '@typescript-eslint/no-explicit-any': 0, 38 | '@typescript-eslint/ban-types': 0, 39 | '@typescript-eslint/no-empty-interface': 0, 40 | '@typescript-eslint/no-empty-function': 0, 41 | '@typescript-eslint/explicit-module-boundary-types': 0, 42 | '@typescript-eslint/ban-ts-comment': 0, 43 | '@typescript-eslint/no-non-null-assertion': 0, 44 | '@typescript-eslint/no-unused-vars': 1, 45 | '@typescript-eslint/no-var-requires': 0, 46 | '@typescript-eslint/consistent-type-imports': 1 47 | } 48 | } 49 | -------------------------------------------------------------------------------- /src/live2d/components/Live2dComponent.vue: -------------------------------------------------------------------------------- 1 | 30 | 31 | 72 | -------------------------------------------------------------------------------- /scripts/rollup.config.js: -------------------------------------------------------------------------------- 1 | import path from 'path' 2 | import buble from '@rollup/plugin-buble' 3 | import commonjs from '@rollup/plugin-commonjs' 4 | import node from '@rollup/plugin-node-resolve' 5 | import babel from '@rollup/plugin-babel' 6 | import json from '@rollup/plugin-json' 7 | import replace from '@rollup/plugin-replace' 8 | import typescript from 'rollup-plugin-typescript2' 9 | import { terser } from 'rollup-plugin-terser' 10 | import pkg from '../package.json' 11 | 12 | const moduleName = pkg.name 13 | const version = process.env.VERSION || pkg.version 14 | const resolve = dir => path.resolve(__dirname, '../', dir) 15 | 16 | const banner = 17 | '/**\n' + 18 | ` * ${moduleName} v${version}\n` + 19 | ` * (c) 2021-${new Date().getFullYear()} ${pkg.author}\n` + 20 | ' * Released under the ISC License.\n' + 21 | ' */' 22 | 23 | function genConfig(input, name) { 24 | return { 25 | input: resolve(input), 26 | external: [...Object.keys(pkg.dependencies)], 27 | plugins: [ 28 | typescript({ 29 | exclude: 'node_modules/**', 30 | typescript: require('typescript'), 31 | tsconfigOverride: { 32 | compilerOptions: { 33 | module: 'esnext', 34 | target: 'es5' 35 | } 36 | } 37 | }), 38 | node(), 39 | commonjs(), 40 | json(), 41 | babel({ babelHelpers: 'bundled', exclude: 'node_modules/**' }), 42 | terser(), 43 | replace({ 44 | 'process.env.NODE_ENV': JSON.stringify('production') 45 | }), 46 | buble({ 47 | objectAssign: 'Object.assign', 48 | transforms: { 49 | arrow: true, 50 | dangerousForOf: true, 51 | asyncAwait: false, 52 | generator: false 53 | } 54 | }) 55 | ], 56 | output: { 57 | dir: resolve('dist'), 58 | entryFileNames: '[name].min.js', 59 | format: 'umd', 60 | exports: 'auto', 61 | banner, 62 | name: name || moduleName 63 | }, 64 | onwarn: (msg, warn) => { 65 | if (!/Circular/.test(msg)) { 66 | warn(msg) 67 | } 68 | } 69 | } 70 | } 71 | 72 | export default genConfig('src/index.ts') 73 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # vitepress-theme-website 2 | 3 | ## 简介 4 | 5 | `vitepress-theme-website` 是一个基于 `Vitepress` 的主题插件,集成评论[Waline](https://waline.js.org)、[Live2D看板娘](https://www.live2d.com/zh-CHS/)。 6 | 7 | [查看Demo](https://xinlei3166.github.io/about/) 8 | 9 | ## 提示 10 | 已支持 `vitepress@1.0.2` 版本 11 | 12 | ## 安装 13 | 14 | ```bash 15 | npm install -D vitepress-theme-website 16 | yarn add -D vitepress-theme-website 17 | pnpm install -D vitepress-theme-website 18 | ``` 19 | 20 | ## Waline 用法 21 | 22 | `.vitepress/theme/index.js` 文件中使用插件,`serverURL` 替换为自己的地址,更多用法详见[Waline](https://waline.js.org)。 23 | 24 | ```js 25 | import DefaultTheme from 'vitepress/theme' 26 | import { useWaline } from 'vitepress-theme-website' 27 | 28 | export default { 29 | ...DefaultTheme, 30 | enhanceApp(ctx) {}, 31 | setup() { 32 | useWaline({ 33 | serverURL: 'https://waline.xinlei3166.com' 34 | }) 35 | } 36 | } 37 | ``` 38 | 39 | ## Live2d 用法 40 | 41 | `.vitepress/theme/index.js` 文件中使用插件。 42 | 43 | ```js 44 | import DefaultTheme from 'vitepress/theme' 45 | import { useLive2d } from 'vitepress-theme-website' 46 | 47 | export default { 48 | ...DefaultTheme, 49 | enhanceApp(ctx) {}, 50 | setup() { 51 | useLive2d() 52 | } 53 | } 54 | ``` 55 | 56 | 由于 `live2d.js` 打包后会导致模型显示不全,需要用cdn方式引用。 57 | 58 | `live2d.js` [下载地址](https://github.com/xinlei3166/vitepress-theme-website/blob/main/docs/public/live2d.js),下载完成后放在和 `.vitepress` 平级的 `public` 目录中。 59 | 60 | `.vitepress/config.js` 文件中增加如下配置: 61 | 62 | ```js 63 | head: [ 64 | ['script', { src: '/live2d.js' }], 65 | ] 66 | ``` 67 | 68 | 自定义参数 69 | 70 | ```js 71 | useLive2d({ 72 | enable: true, 73 | model: { 74 | url: 'https://raw.githubusercontent.com/iCharlesZ/vscode-live2d-models/master/model-library/hibiki/hibiki.model.json' 75 | }, 76 | display: { 77 | position: 'right', 78 | width: '135px', 79 | height: '300px', 80 | xOffset: '35px', 81 | yOffset: '5px' 82 | }, 83 | mobile: { 84 | show: true 85 | }, 86 | react: { 87 | opacity: 0.8 88 | } 89 | }) 90 | ``` 91 | 92 | ### 模型 93 | 使用了 [vscode-live2d-models](https://github.com/iCharlesZ/vscode-live2d-models#url) 中的模型,把 `model.url` 改为指定的模型地址即可。 94 | 95 | 96 | ### 感谢 97 | `vitepress-theme-website@useLive2d` 参考了 [vuepress-plugin-helper-live2d](https://github.com/JoeyBling/vuepress-plugin-helper-live2d) 98 | -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "vitepress-theme-website", 3 | "version": "1.0.8", 4 | "type": "module", 5 | "description": "vitepress plugin for website", 6 | "repository": { 7 | "type": "git", 8 | "url": "https://github.com/xinlei3166/vitepress-theme-website" 9 | }, 10 | "keywords": [ 11 | "vitepress", 12 | "theme", 13 | "plugin", 14 | "waline", 15 | "live2d" 16 | ], 17 | "bugs": { 18 | "url": "https://github.com/xinlei3166/vitepress-theme-website/issues" 19 | }, 20 | "homepage": "https://github.com/xinlei3166/vitepress-theme-website#readme", 21 | "author": "君惜", 22 | "license": "MIT", 23 | "files": [ 24 | "dist" 25 | ], 26 | "main": "dist/index.mjs", 27 | "types": "dist/index.d.ts", 28 | "exports": { 29 | ".": { 30 | "types": "./dist/index.d.ts", 31 | "import": "./dist/index.mjs" 32 | }, 33 | "./dist/*": "./dist/*", 34 | "./waline": { 35 | "types": "./dist/waline/index.d.ts", 36 | "import": "./dist/waline/index.mjs" 37 | }, 38 | "./live2d": { 39 | "types": "./dist/live2d/index.d.ts", 40 | "import": "./dist/live2d/index.mjs" 41 | } 42 | }, 43 | "scripts": { 44 | "build": "unbuild", 45 | "stub": "unbuild --stub", 46 | "test": "jest", 47 | "lint": "eslint --fix --ext .js,.jsx,.ts,.tsx,.vue", 48 | "release": "yunque-release", 49 | "changelog": "conventional-changelog -p angular -i CHANGELOG.md -s -r 0" 50 | }, 51 | "dependencies": { 52 | "@waline/client": "^3.1.3" 53 | }, 54 | "devDependencies": { 55 | "@types/node": "^20.12.3", 56 | "@typescript-eslint/eslint-plugin": "^7.5.0", 57 | "@typescript-eslint/parser": "^7.5.0", 58 | "@yunquejs/release": "^0.1.9", 59 | "conventional-changelog-cli": "^4.1.0", 60 | "eslint": "^8.57.0", 61 | "eslint-config-prettier": "^9.1.0", 62 | "eslint-plugin-prettier": "^5.1.3", 63 | "eslint-plugin-vue": "^9.24.0", 64 | "lint-staged": "^15.2.2", 65 | "picocolors": "^1.0.0", 66 | "prettier": "^3.2.5", 67 | "simple-git-hooks": "^2.11.1", 68 | "tsup": "^8.0.2", 69 | "tsx": "^4.7.1", 70 | "typescript": "^5.4.3", 71 | "unbuild": "^2.0.0", 72 | "vitepress": "^1.0.2", 73 | "vitest": "^1.4.0", 74 | "vue": "^3.4.21", 75 | "vue-eslint-parser": "^9.4.2" 76 | }, 77 | "simple-git-hooks": { 78 | "pre-commit": "pnpm exec lint-staged --concurrent false", 79 | "commit-msg": "pnpm exec tsx scripts/verifyCommit.ts $1" 80 | }, 81 | "lint-staged": { 82 | "*.{js,jsx,ts,tsx,vue}": [ 83 | "eslint --fix" 84 | ] 85 | }, 86 | "engines": { 87 | "node": ">=16.0.0" 88 | }, 89 | "pnpm": { 90 | "peerDependencyRules": { 91 | "ignoreMissing": [ 92 | "@algolia/client-search" 93 | ] 94 | } 95 | } 96 | } 97 | --------------------------------------------------------------------------------