├── .gitignore ├── .prettierrc.json ├── .vscode └── settings.json ├── lerna.json ├── package.json ├── packages ├── create-kira-hexo │ ├── .fatherrc.ts │ ├── .gitignore │ ├── .npmignore │ ├── bin │ │ └── index │ ├── package.json │ ├── readme.md │ ├── src │ │ └── index.ts │ ├── template │ │ ├── .github │ │ │ └── dependabot.yml │ │ ├── _config.kira.yml │ │ ├── _config.yml │ │ ├── kira.gitignore │ │ ├── package.json │ │ ├── scaffolds │ │ │ ├── draft.md │ │ │ ├── page.md │ │ │ └── post.md │ │ ├── source │ │ │ ├── _posts │ │ │ │ └── hello-world.md │ │ │ ├── about.md │ │ │ ├── archive.md │ │ │ └── friends.md │ │ └── themes │ │ │ └── .gitkeep │ └── tsconfig.json ├── kira-hexo-demo │ ├── .github │ │ └── dependabot.yml │ ├── .gitignore │ ├── _config.kira.yml │ ├── _config.yml │ ├── package.json │ ├── scaffolds │ │ ├── draft.md │ │ ├── page.md │ │ └── post.md │ ├── source │ │ ├── _posts │ │ │ ├── JavaScript │ │ │ │ ├── js原型链.md │ │ │ │ ├── js的对象.md │ │ │ │ ├── 了解js的原型.md │ │ │ │ ├── 正确区分var、let和const.md │ │ │ │ ├── 浅谈JS中的闭包.md │ │ │ │ └── 理解JS中的防抖与节流.md │ │ │ ├── Node.js │ │ │ │ ├── 【Node.js学习】初识Node.js.md │ │ │ │ ├── 【Node.js学习】简单认识express.md │ │ │ │ ├── 【Node.js学习】简单认识fs文件系统模块.md │ │ │ │ └── 【Node.js学习】简单认识http模块.md │ │ │ ├── React │ │ │ │ ├── React入门.md │ │ │ │ ├── React条件渲染.md │ │ │ │ ├── React的事件处理.md │ │ │ │ ├── React的组件.md │ │ │ │ └── 关于React18中ReactDOM.render报错的解决方法.md │ │ │ ├── Revue │ │ │ │ ├── Eutopia.md │ │ │ │ ├── Fly-Me-To-The-Star.md │ │ │ │ ├── Star-Divine-フィナーレ.md │ │ │ │ ├── 花咲か唄.md │ │ │ │ └── 誇りと驕り.md │ │ │ ├── Rust │ │ │ │ ├── Rust与所有权.md │ │ │ │ └── 初识Rust.md │ │ │ ├── TypeScript-IOC-设计模式初探.md │ │ │ ├── Unity使用Newtonsoft报错的解决方案.md │ │ │ ├── 【Fira-Code】一款为程序员量身打造的字体.md │ │ │ ├── 【VSCODE插件推荐】TODO-Highlight.md │ │ │ ├── 使用Vue和Electron开发一款简单的Markdown编辑器.md │ │ │ ├── 字节跳动西瓜视频一面面经.md │ │ │ ├── 测试文章.md │ │ │ └── 蚂蚁集团-数字金融线-体验技术部前端一面面经.md │ │ ├── about.md │ │ ├── archive.md │ │ └── friends.md │ └── themes │ │ └── .gitkeep ├── kira-hexo-docs │ ├── .gitignore │ ├── docs │ │ ├── .vitepress │ │ │ ├── config.ts │ │ │ └── theme │ │ │ │ ├── index.ts │ │ │ │ └── styles │ │ │ │ └── vars.css │ │ ├── article │ │ │ ├── archive.md │ │ │ └── front-matter.md │ │ ├── assets │ │ │ └── img │ │ │ │ ├── archive.webp │ │ │ │ ├── biliplayer.webp │ │ │ │ ├── copied.webp │ │ │ │ ├── copyable.webp │ │ │ │ └── preview.webp │ │ ├── config │ │ │ ├── colors.md │ │ │ ├── config.md │ │ │ ├── customStyles.md │ │ │ └── icon.md │ │ ├── faqs.md │ │ ├── feature │ │ │ ├── bilibili.md │ │ │ ├── codepen.md │ │ │ ├── copy-codeblock.md │ │ │ └── music.md │ │ ├── index.md │ │ └── version.md │ └── package.json ├── kira-hexo-toc │ ├── index.js │ └── package.json └── kira-hexo │ ├── .gitignore │ ├── .npmignore │ ├── LICENSE │ ├── languages │ ├── default.yml │ ├── en.yml │ ├── it.yml │ ├── ja.yml │ ├── zh-CN.yml │ ├── zh-HK.yml │ └── zh-TW.yml │ ├── layout │ ├── _widget │ │ ├── archive.ejs │ │ ├── category.ejs │ │ ├── social.ejs │ │ └── tagcloud.ejs │ ├── archives.ejs │ ├── components │ │ ├── comments │ │ │ ├── giscus.ejs │ │ │ └── gitalk.ejs │ │ ├── copyright.ejs │ │ ├── friends.ejs │ │ ├── header.ejs │ │ ├── kira-image.ejs │ │ ├── right-column.ejs │ │ └── sidebar.ejs │ ├── friends.ejs │ ├── index.ejs │ ├── layout.ejs │ └── post.ejs │ ├── package.json │ ├── preview.png │ ├── readme.md │ ├── scripts │ ├── tag │ │ ├── biliplayer.js │ │ ├── codepen.js │ │ ├── kira-player.js │ │ └── meting.js │ └── utils │ │ └── image_auto_lazyload.js │ └── source │ ├── css │ ├── archive.styl │ ├── article.styl │ ├── color.styl │ ├── constants.styl │ ├── content.styl │ ├── kira-code-copy.styl │ ├── kira-friends.styl │ ├── kira-image.styl │ ├── layout.styl │ ├── media.styl │ ├── post.styl │ ├── right-column.styl │ └── sidebar.styl │ ├── deps │ ├── css │ │ └── APlayer.min.css │ └── js │ │ ├── APlayer.min.js │ │ └── Meting.min.js │ ├── js │ ├── kira-code-copy.js │ └── kira-image.js │ └── lib │ ├── fonts │ └── roboto │ │ ├── Roboto-Bold.woff2 │ │ ├── Roboto-Medium.woff2 │ │ └── Roboto-Regular.woff2 │ ├── highlight │ ├── atom-one-dark.min.css │ └── highlight.min.js │ ├── iconfont │ ├── demo.css │ ├── demo_index.html │ ├── iconfont.css │ ├── iconfont.js │ ├── iconfont.json │ ├── iconfont.ttf │ ├── iconfont.woff │ └── iconfont.woff2 │ ├── lazysizes.js │ ├── mdui │ ├── mdui.min.css │ └── mdui.min.js │ └── smooth-scrolling.js ├── pnpm-lock.yaml ├── pnpm-workspace.yaml └── readme.md /.gitignore: -------------------------------------------------------------------------------- 1 | node_modules/ -------------------------------------------------------------------------------- /.prettierrc.json: -------------------------------------------------------------------------------- 1 | {} 2 | -------------------------------------------------------------------------------- /.vscode/settings.json: -------------------------------------------------------------------------------- 1 | { 2 | "cSpell.words": [ 3 | "aplayer", 4 | "giscus", 5 | "gitalk", 6 | "hexo", 7 | "kirameki", 8 | "vitepress", 9 | "wordcount" 10 | ] 11 | } 12 | -------------------------------------------------------------------------------- /lerna.json: -------------------------------------------------------------------------------- 1 | { 2 | "packages": [ 3 | "packages/*" 4 | ], 5 | "version": "1.4.9", 6 | "npmClient": "pnpm" 7 | } -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "kira-hexo-monorepo", 3 | "version": "1.4.9", 4 | "description": "", 5 | "private": true, 6 | "scripts": { 7 | "prepublishOnly": "lerna prepublishOnly --no-private", 8 | "publish": "lerna publish --no-private", 9 | "version": "lerna version --no-private" 10 | }, 11 | "workspaces": [ 12 | "packages/*" 13 | ], 14 | "keywords": [], 15 | "author": "", 16 | "license": "ISC", 17 | "devDependencies": { 18 | "lerna": "^8.1.9" 19 | } 20 | } 21 | -------------------------------------------------------------------------------- /packages/create-kira-hexo/.fatherrc.ts: -------------------------------------------------------------------------------- 1 | import { defineConfig } from "father"; 2 | 3 | export default defineConfig({ 4 | cjs: { 5 | output: "dist", 6 | }, 7 | }); 8 | -------------------------------------------------------------------------------- /packages/create-kira-hexo/.gitignore: -------------------------------------------------------------------------------- 1 | node_modules/ 2 | 3 | package-lock.json 4 | yarn.lock 5 | 6 | dist/ -------------------------------------------------------------------------------- /packages/create-kira-hexo/.npmignore: -------------------------------------------------------------------------------- 1 | node_modules/ 2 | src/ 3 | 4 | yarn.lock 5 | 6 | gulpfile.js 7 | 8 | tsconfig.json 9 | 10 | -------------------------------------------------------------------------------- /packages/create-kira-hexo/bin/index: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env node 2 | const main = require('../dist/index.js').default; 3 | 4 | const defaultTargetDir = 'kira-hexo-blog'; 5 | const targetDir = process.argv.slice(2).join(' '); 6 | 7 | main(targetDir ?? defaultTargetDir); 8 | -------------------------------------------------------------------------------- /packages/create-kira-hexo/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "create-kira-hexo", 3 | "version": "1.4.9", 4 | "bin": { 5 | "create-kira-hexo": "bin/index" 6 | }, 7 | "author": "德布罗煜", 8 | "license": "MIT", 9 | "description": "A kirameki ✨ hexo theme for your blog.", 10 | "keywords": [ 11 | "hexo", 12 | "theme", 13 | "kira" 14 | ], 15 | "repository": { 16 | "type": "git", 17 | "url": "https://github.com/ch1ny/kira-hexo.git" 18 | }, 19 | "homepage": "https://kira.host/hexo/", 20 | "bugs": { 21 | "url": "https://github.com/ch1ny/kira-hexo/issues" 22 | }, 23 | "publishConfig": { 24 | "registry": "https://registry.npmjs.org/" 25 | }, 26 | "scripts": { 27 | "build": "father build", 28 | "prepublishOnly": "npm run build" 29 | }, 30 | "devDependencies": { 31 | "@types/fs-extra": "^11.0.1", 32 | "@types/node": "^18.15.3", 33 | "father": "^4.5.1", 34 | "typescript": "^4.9.5" 35 | }, 36 | "dependencies": { 37 | "chalk": "4", 38 | "fs-extra": "^11.1.0" 39 | } 40 | } 41 | -------------------------------------------------------------------------------- /packages/create-kira-hexo/readme.md: -------------------------------------------------------------------------------- 1 | # create-kira-hexo 2 | 3 | 帮您快速生成基于 `hexo-theme-kira` 主题的 hexo 博客模板。 4 | 5 | With npm: 6 | ```bash 7 | npm create kira-hexo@latest my-blog 8 | ``` 9 | 10 | With yarn: 11 | ```bash 12 | yarn create kira-hexo my-blog 13 | ``` 14 | 15 | With pnpm: 16 | ```bash 17 | pnpm create kira-hexo my-blog 18 | ``` 19 | 20 | 关于本主题的使用说明,请参阅 [使用说明](https://kira.host/hexo/) 哦! 21 | -------------------------------------------------------------------------------- /packages/create-kira-hexo/src/index.ts: -------------------------------------------------------------------------------- 1 | import chalk from 'chalk'; 2 | import cp from 'child_process'; 3 | import fs from 'fs'; 4 | import fse from 'fs-extra'; 5 | import path from 'path'; 6 | 7 | const validateProjectName = (projectName: string): boolean => { 8 | const error = (errMsg: string) => { 9 | console.log(chalk.red(`× ${errMsg}`)); 10 | }; 11 | 12 | if (!projectName) { 13 | error('请输入项目名'); 14 | return false; 15 | } 16 | if (/[\\:*?"<>|]/.test(projectName)) { 17 | error('请输入合法文件名'); 18 | return false; 19 | } 20 | return true; 21 | }; 22 | 23 | const initProjectDirectory = async (projectName: string, projectDir: string) => { 24 | // 判断当前文件夹下是否有目标路径的目录 25 | if (fs.existsSync(projectDir)) { 26 | console.log(chalk.red(`Folder named '${projectName}' has already been existed`)); 27 | process.exit(-1); 28 | } 29 | 30 | // 创建文件夹 31 | await fs.promises.mkdir(projectDir, { recursive: true }); 32 | }; 33 | 34 | function pkgFromUserAgent(userAgent: string | undefined) { 35 | if (!userAgent) return undefined; 36 | const pkgSpec = userAgent.split(' ')[0]; 37 | const pkgSpecArr = pkgSpec.split('/'); 38 | return { 39 | name: pkgSpecArr[0], 40 | version: pkgSpecArr[1], 41 | }; 42 | } 43 | 44 | const copyTemplate = async (targetDir: string) => { 45 | const templateDir = path.resolve(__dirname, '..', 'template'); 46 | await fse.copy(templateDir, targetDir); 47 | 48 | /** 49 | * 重命名 .gitignore 50 | * 因为 npm 会将 .gitignore 重命名为 .npmignore 51 | */ 52 | await fse.rename( 53 | path.resolve(targetDir, 'kira.gitignore'), 54 | path.resolve(targetDir, '.gitignore') 55 | ); 56 | 57 | // 安装依赖 58 | console.log(chalk.green('正在为您安装依赖')); 59 | const pkgInfo = pkgFromUserAgent(process.env.npm_config_user_agent); 60 | const pkgManager = pkgInfo ? pkgInfo.name : 'npm'; 61 | try { 62 | cp.execSync(`${pkgManager} install`, { 63 | cwd: targetDir, 64 | stdio: 'inherit', 65 | }); 66 | } catch (e) { 67 | return; 68 | } 69 | 70 | // cSpell: disable-next-line 71 | console.log(chalk.green('Ciallo~ ( ∠·ω< )⌒★ 博客初始化完成辣!')); 72 | console.log( 73 | chalk.white('kira-hexo 使用文档请访问'), 74 | chalk.cyan('https://kira.host/hexo/'), 75 | chalk.white('哦!') 76 | ); 77 | }; 78 | 79 | export default async function (dirName: string) { 80 | if (!validateProjectName(dirName)) return; 81 | 82 | // 目标根路径,process.cwd() 为脚手架工作时的路径,将其与用户输入的项目名称拼接起来作为目标路径 83 | const blogDirPath = path.resolve(process.cwd(), dirName); 84 | await initProjectDirectory(dirName, blogDirPath); 85 | await copyTemplate(blogDirPath); 86 | } 87 | -------------------------------------------------------------------------------- /packages/create-kira-hexo/template/.github/dependabot.yml: -------------------------------------------------------------------------------- 1 | version: 2 2 | updates: 3 | - package-ecosystem: npm 4 | directory: "/" 5 | schedule: 6 | interval: daily 7 | open-pull-requests-limit: 20 8 | -------------------------------------------------------------------------------- /packages/create-kira-hexo/template/_config.kira.yml: -------------------------------------------------------------------------------- 1 | avatar: https://kira.host/assets/Pictures/Others/20220922230447.jpg # 网站 Logo 2 | background: # 既是博客的背景,又是文章默认头图 3 | path: https://kira.host/assets/Pictures/Others/-f0d5cc34c6e5aa7_compressed.jpg 4 | width: 1280 5 | height: 720 6 | favicon: 7 | href: https://kira.host/assets/Pictures/Others/116359b4ccf19917.jpg # 网站图标 8 | type: image/png # 图标类型,可能的值有(image/png, image/vnd.microsoft.icon, image/x-icon, image/gif) 9 | 10 | # 附加图标库 使用说明:https://kira.host/hexo/config/icon.html 11 | # iconlib: //at.alicdn.com/t/font_3299330_el19bsi97h8.css 12 | 13 | cdn: # 这里可以修改站点使用的库的CDN 14 | gitalk: 15 | css: https://unpkg.com/gitalk@latest/dist/gitalk.css 16 | js: https://unpkg.com/gitalk@latest/dist/gitalk.min.js 17 | giscus: 18 | js: https://giscus.app/client.js 19 | 20 | # beian: 赣ICP备2021007955号-3 # 备案号(选填,别往你们网站上挂我的备案号!!!) 21 | 22 | menu: 23 | 回到首页: 24 | - / 25 | - icon-home 26 | 文章归档: 27 | - /archive.html 28 | - icon-container 29 | 关于本人: 30 | - /about.html 31 | - icon-user 32 | 我的朋友: 33 | - /friends.html 34 | - icon-team 35 | 36 | widgets: 37 | - social 38 | - category 39 | - tagcloud 40 | - archive 41 | 42 | maxTagcloud: 0 # 标签云组件显示的标签数量,0 表示不限制 43 | 44 | social: 45 | QQ: 46 | - tencent://AddContact/?fromId=45&fromSubId=1&subcmd=all&uin=<去掉尖括号后填上你的QQ号>&website=www.oicqzone.com 47 | - icon-QQ 48 | - rgb(49, 174, 255) 49 | - rgba(49, 174, 255, .1) 50 | 哔哩哔哩: 51 | - https://space.bilibili.com/<改成你的B站uid> 52 | - icon-bilibili 53 | - rgb(231, 106, 141) 54 | - rgba(231, 106, 141, .15) 55 | GitHub: 56 | - https://github.com/<你的github id>/ 57 | - icon-github 58 | - rgb(25, 23, 23) 59 | - rgba(25, 23, 23, .15) 60 | Gitee: 61 | - https://gitee.com/<你的gitee id> 62 | - icon-gitee 63 | - rgb(165, 15, 15) 64 | - rgba(165, 15, 15, .15) 65 | 66 | color: # 配色方案,从first到seventh为优先级为1-7的颜色,默认为彩虹配色 67 | first: # 同时作为主题色 68 | r: 49 69 | g: 174 70 | b: 255 71 | second: 72 | r: 255 73 | g: 78 74 | b: 106 75 | third: 76 | r: 255 77 | g: 185 78 | b: 0 79 | fourth: 80 | r: 51 81 | g: 213 82 | b: 122 83 | fifth: 84 | r: 0 85 | g: 219 86 | b: 255 87 | sixth: 88 | r: 255 89 | g: 69 90 | b: 0 91 | seventh: 92 | r: 144 93 | g: 144 94 | b: 255 95 | 96 | # 评论区 97 | gitalk: 98 | active: false # 是否启用 gitalk 99 | admin: -your github username- # 拥有对该repo进行操作的 GitHub username 100 | owner: -your github username- # 持有该 repo 的 GitHub username 101 | repo: -issue repo name- # 存放评论的 issue 所在的 repo 102 | clientID: -id- # GitHub Client ID 103 | clientSecret: -key- # GitHub Client Secret 104 | title: '' # Gitalk Issue Title 105 | # 你们不要在这里填我的 giscus 配置项,不然你们博客下的评论会全部跑到我的仓库下面…… 106 | # https://giscus.app/zh-CN 可以在这个网站上手动选择配置填到下方对应位置 107 | giscus: 108 | active: true # 是否启用 giscus 109 | repo: -your github username-/-your giscus repo- # 存放评论的 discus 所在的 repo 110 | repoID: -your giscus repo ID- # GitHub repo ID 111 | category: Announcements # 选择新 discussions 所在的分类 112 | categoryID: -giscus category id- # 分类 ID 113 | mapping: pathname # pathname, url, title, og:title, specific, number 114 | # term: # abc 123 # specific | number 115 | theme: light 116 | lang: en 117 | 118 | copyright: '版权声明:本文采用 CC BY-NC-SA 3.0 CN 协议进行许可' 119 | copyTip: "著作权归作者所有。\n商业转载请联系作者获得授权,非商业转载请注明出处。\n来源:%url" # 自定义复制版权文案,使用 %url 代替当前页面URL, 修改为false禁用 120 | 121 | # 自定义侧边栏尾部内容 122 | sidebar: '' 123 | 124 | # 自定义样式 125 | # customStyles: 126 | # - style 127 | # - custom 128 | 129 | # 友链配置 130 | friends: 131 | # - avatar: <友链缩略图> 132 | # link: <跳转连接> 133 | # name: <名称> 134 | 135 | # 可复制的代码块 136 | copyableCodeblock: true 137 | -------------------------------------------------------------------------------- /packages/create-kira-hexo/template/_config.yml: -------------------------------------------------------------------------------- 1 | # Hexo Configuration 2 | ## Docs: https://hexo.io/docs/configuration.html 3 | ## Source: https://github.com/hexojs/hexo/ 4 | 5 | # Site 6 | title: Hexo 7 | subtitle: '' 8 | description: '' 9 | keywords: 10 | author: John Doe 11 | language: en 12 | timezone: '' 13 | 14 | # URL 15 | ## Set your site url here. For example, if you use GitHub Page, set url as 'https://username.github.io/project' 16 | url: http://example.com 17 | permalink: :year/:month/:day/:title/ 18 | permalink_defaults: 19 | pretty_urls: 20 | trailing_index: true # Set to false to remove trailing 'index.html' from permalinks 21 | trailing_html: true # Set to false to remove trailing '.html' from permalinks 22 | 23 | # Directory 24 | source_dir: source 25 | public_dir: public 26 | tag_dir: tags 27 | archive_dir: archives 28 | category_dir: categories 29 | code_dir: downloads/code 30 | i18n_dir: :lang 31 | skip_render: 32 | 33 | # Writing 34 | new_post_name: :title.md # File name of new posts 35 | default_layout: post 36 | titlecase: false # Transform title into titlecase 37 | external_link: 38 | enable: true # Open external links in new tab 39 | field: site # Apply to the whole site 40 | exclude: '' 41 | filename_case: 0 42 | render_drafts: false 43 | post_asset_folder: false 44 | relative_link: false 45 | future: true 46 | highlight: 47 | enable: true 48 | line_number: true 49 | auto_detect: false 50 | tab_replace: '' 51 | wrap: true 52 | hljs: true 53 | prismjs: 54 | enable: false 55 | preprocess: true 56 | line_number: true 57 | tab_replace: '' 58 | 59 | # Home page setting 60 | # path: Root path for your blogs index page. (default = '') 61 | # per_page: Posts displayed per page. (0 = disable pagination) 62 | # order_by: Posts order. (Order by date descending by default) 63 | index_generator: 64 | path: '' 65 | per_page: 10 66 | order_by: -date 67 | 68 | # Category & Tag 69 | default_category: uncategorized 70 | category_map: 71 | tag_map: 72 | 73 | # Metadata elements 74 | ## https://developer.mozilla.org/en-US/docs/Web/HTML/Element/meta 75 | meta_generator: true 76 | 77 | # Date / Time format 78 | ## Hexo uses Moment.js to parse and display date 79 | ## You can customize the date format as defined in 80 | ## http://momentjs.com/docs/#/displaying/format/ 81 | date_format: YYYY-MM-DD 82 | time_format: HH:mm:ss 83 | ## updated_option supports 'mtime', 'date', 'empty' 84 | updated_option: 'mtime' 85 | 86 | # Pagination 87 | ## Set per_page to 0 to disable pagination 88 | per_page: 10 89 | pagination_dir: page 90 | 91 | # Include / Exclude file(s) 92 | ## include:/exclude: options only apply to the 'source/' folder 93 | include: 94 | exclude: 95 | ignore: 96 | 97 | # Extensions 98 | ## Plugins: https://hexo.io/plugins/ 99 | ## Themes: https://hexo.io/themes/ 100 | theme: kira 101 | 102 | # Deployment 103 | ## Docs: https://hexo.io/docs/one-command-deployment 104 | deploy: 105 | type: '' 106 | 107 | aplayer: 108 | asset_inject: false # 禁止 aplayer 注入资源 109 | -------------------------------------------------------------------------------- /packages/create-kira-hexo/template/kira.gitignore: -------------------------------------------------------------------------------- 1 | .DS_Store 2 | Thumbs.db 3 | db.json 4 | *.log 5 | node_modules/ 6 | public/ 7 | .deploy*/ 8 | _multiconfig.yml -------------------------------------------------------------------------------- /packages/create-kira-hexo/template/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "kira-hexo-site", 3 | "version": "0.0.0", 4 | "private": true, 5 | "scripts": { 6 | "build": "hexo generate", 7 | "clean": "hexo clean", 8 | "deploy": "hexo deploy", 9 | "server": "hexo server" 10 | }, 11 | "hexo": { 12 | "version": "" 13 | }, 14 | "dependencies": { 15 | "hexo": "^7.3.0", 16 | "hexo-generator-archive": "^2.0.0", 17 | "hexo-generator-category": "^2.0.0", 18 | "hexo-generator-index": "^3.0.0", 19 | "hexo-generator-tag": "^2.0.0", 20 | "hexo-renderer-ejs": "^2.0.0", 21 | "hexo-renderer-marked": "^6.0.0", 22 | "hexo-renderer-stylus": "^2.1.0", 23 | "hexo-server": "^3.0.0", 24 | "hexo-theme-kira": "^1.4.9" 25 | } 26 | } 27 | -------------------------------------------------------------------------------- /packages/create-kira-hexo/template/scaffolds/draft.md: -------------------------------------------------------------------------------- 1 | --- 2 | title: {{ title }} 3 | tags: 4 | --- 5 | -------------------------------------------------------------------------------- /packages/create-kira-hexo/template/scaffolds/page.md: -------------------------------------------------------------------------------- 1 | --- 2 | title: {{ title }} 3 | date: {{ date }} 4 | --- 5 | -------------------------------------------------------------------------------- /packages/create-kira-hexo/template/scaffolds/post.md: -------------------------------------------------------------------------------- 1 | --- 2 | title: {{ title }} 3 | date: {{ date }} 4 | tags: 5 | --- 6 | -------------------------------------------------------------------------------- /packages/create-kira-hexo/template/source/_posts/hello-world.md: -------------------------------------------------------------------------------- 1 | --- 2 | title: Hello World 3 | --- 4 | Welcome to [Hexo](https://hexo.io/)! This is your very first post. Check [documentation](https://hexo.io/docs/) for more info. If you get any problems when using Hexo, you can find the answer in [troubleshooting](https://hexo.io/docs/troubleshooting.html) or you can ask me on [GitHub](https://github.com/hexojs/hexo/issues). 5 | 6 | ## Quick Start 7 | 8 | ### Create a new post 9 | 10 | ``` bash 11 | $ hexo new "My New Post" 12 | ``` 13 | 14 | More info: [Writing](https://hexo.io/docs/writing.html) 15 | 16 | ### Run server 17 | 18 | ``` bash 19 | $ hexo server 20 | ``` 21 | 22 | More info: [Server](https://hexo.io/docs/server.html) 23 | 24 | ### Generate static files 25 | 26 | ``` bash 27 | $ hexo generate 28 | ``` 29 | 30 | More info: [Generating](https://hexo.io/docs/generating.html) 31 | 32 | ### Deploy to remote sites 33 | 34 | ``` bash 35 | $ hexo deploy 36 | ``` 37 | 38 | More info: [Deployment](https://hexo.io/docs/one-command-deployment.html) 39 | -------------------------------------------------------------------------------- /packages/create-kira-hexo/template/source/about.md: -------------------------------------------------------------------------------- 1 | --- 2 | title: 关于本人 3 | layout: about 4 | --- 5 | 6 | ## 自我介绍 7 | -------------------------------------------------------------------------------- /packages/create-kira-hexo/template/source/archive.md: -------------------------------------------------------------------------------- 1 | --- 2 | title: 文章归档 3 | layout: archives 4 | --- 5 | -------------------------------------------------------------------------------- /packages/create-kira-hexo/template/source/friends.md: -------------------------------------------------------------------------------- 1 | --- 2 | title: 我的朋友 3 | layout: friends 4 | --- 5 | 6 | ## 我的朋友 7 | -------------------------------------------------------------------------------- /packages/create-kira-hexo/template/themes/.gitkeep: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ch1ny/kira-hexo/0bba396b1c70e7ba6a9f5480194b067692bfeb3f/packages/create-kira-hexo/template/themes/.gitkeep -------------------------------------------------------------------------------- /packages/kira-hexo-demo/.github/dependabot.yml: -------------------------------------------------------------------------------- 1 | version: 2 2 | updates: 3 | - package-ecosystem: npm 4 | directory: "/" 5 | schedule: 6 | interval: daily 7 | open-pull-requests-limit: 20 8 | -------------------------------------------------------------------------------- /packages/kira-hexo-demo/.gitignore: -------------------------------------------------------------------------------- 1 | .DS_Store 2 | Thumbs.db 3 | db.json 4 | *.log 5 | node_modules/ 6 | public/ 7 | .deploy*/ 8 | _multiconfig.yml 9 | .yalc/ -------------------------------------------------------------------------------- /packages/kira-hexo-demo/_config.kira.yml: -------------------------------------------------------------------------------- 1 | avatar: https://kira.host/assets/Pictures/Others/20220922230447.jpg # 网站 Logo 2 | background: # 既是博客的背景,又是文章默认头图 3 | path: https://kira.host/assets/Pictures/Others/-f0d5cc34c6e5aa7_compressed.jpg 4 | width: 1280 5 | height: 720 6 | favicon: 7 | href: https://kira.host/assets/Pictures/Others/116359b4ccf19917.jpg # 网站图标 8 | type: image/png # 图标类型,可能的值有(image/png, image/vnd.microsoft.icon, image/x-icon, image/gif) 9 | 10 | # 附加图标库 使用说明:https://kira.host/hexo/config/icon.html 11 | # iconlib: //at.alicdn.com/t/font_3299330_el19bsi97h8.css 12 | 13 | cdn: 14 | gitalk: 15 | css: https://unpkg.com/gitalk@latest/dist/gitalk.css 16 | js: https://unpkg.com/gitalk@latest/dist/gitalk.min.js 17 | giscus: 18 | js: https://giscus.app/client.js 19 | 20 | beian: 赣ICP备2021007955号-3 # 备案号(选填) 21 | 22 | menu: 23 | 回到首页: 24 | - / 25 | - icon-home 26 | 文章归档: 27 | - /archive.html 28 | - icon-container 29 | 关于本人: 30 | - /about.html 31 | - icon-user 32 | 我的朋友: 33 | - /friends.html 34 | - icon-team 35 | 36 | widgets: 37 | - social 38 | - category 39 | - tagcloud 40 | - archive 41 | 42 | maxTagcloud: 0 # 标签云组件显示的标签数量,0 表示不限制 43 | 44 | social: 45 | QQ: 46 | - tencent://AddContact/?fromId=45&fromSubId=1&subcmd=all&uin=1056317718&website=www.oicqzone.com 47 | - icon-QQ 48 | - rgb(49, 174, 255) 49 | - rgba(49, 174, 255, .1) 50 | 哔哩哔哩: 51 | - https://space.bilibili.com/27905679 52 | - icon-bilibili 53 | - rgb(231, 106, 141) 54 | - rgba(231, 106, 141, .15) 55 | GitHub: 56 | - https://github.com/ch1ny/ 57 | - icon-github 58 | - rgb(25, 23, 23) 59 | - rgba(25, 23, 23, .15) 60 | Gitee: 61 | - https://gitee.com/ch1ny 62 | - icon-gitee 63 | - rgb(165, 15, 15) 64 | - rgba(165, 15, 15, .15) 65 | 66 | color: # 配色方案,从first到seventh为优先级为1-7的颜色,默认为彩虹配色 67 | first: # 同时作为主题色 68 | r: 49 69 | g: 174 70 | b: 255 71 | second: 72 | r: 255 73 | g: 78 74 | b: 106 75 | third: 76 | r: 255 77 | g: 185 78 | b: 0 79 | fourth: 80 | r: 51 81 | g: 213 82 | b: 122 83 | fifth: 84 | r: 0 85 | g: 219 86 | b: 255 87 | sixth: 88 | r: 255 89 | g: 69 90 | b: 0 91 | seventh: 92 | r: 144 93 | g: 144 94 | b: 255 95 | 96 | # 评论区 97 | gitalk: 98 | active: false # 启用评论区 99 | giscus: 100 | active: true # 启用评论区 101 | repo: ch1ny/ch1ny.github.io # 存放评论的 issue 所在的 repo 102 | repoID: R_kgDOHGgizw # GitHub repo ID 103 | category: General 104 | categoryID: DIC_kwDOHGgiz84CU88t 105 | mapping: pathname # pathname, url, title, og:title, specific, number 106 | # term: # abc 123 # specific | number 107 | theme: light 108 | lang: en 109 | 110 | copyright: '版权声明:本文采用 CC BY-NC-SA 3.0 CN 协议进行许可' 111 | copyTip: "著作权归作者所有。\n商业转载请联系作者获得授权,非商业转载请注明出处。\n来源:%url" # 自定义复制版权文案,使用 %url 代替当前页面URL, 修改为false禁用 112 | 113 | # 自定义侧边栏尾部内容 114 | sidebar: '' 115 | 116 | # 自定义样式 117 | # customStyles: 118 | # - style 119 | # - custom 120 | 121 | # 友链配置 122 | friends: 123 | - avatar: https://www.jingtao.online/favicon.ico 124 | link: https://www.jingtao.online 125 | name: 景涛在线 126 | 127 | # 可复制的代码块 128 | copyableCodeblock: true -------------------------------------------------------------------------------- /packages/kira-hexo-demo/_config.yml: -------------------------------------------------------------------------------- 1 | # Hexo Configuration 2 | ## Docs: https://hexo.io/docs/configuration.html 3 | ## Source: https://github.com/hexojs/hexo/ 4 | 5 | # Site 6 | title: 德布罗煜 7 | subtitle: '' 8 | description: '' 9 | keywords: 10 | author: 德布罗煜 11 | language: zh_CN 12 | timezone: '' 13 | 14 | # URL 15 | ## Set your site url here. For example, if you use GitHub Page, set url as 'https://username.github.io/project' 16 | url: https://kira.host/ 17 | root: /blog/ 18 | permalink: :title/ 19 | permalink_defaults: 20 | pretty_urls: 21 | trailing_index: true # Set to false to remove trailing 'index.html' from permalinks 22 | trailing_html: true # Set to false to remove trailing '.html' from permalinks 23 | 24 | # Directory 25 | source_dir: source 26 | public_dir: public 27 | tag_dir: tags 28 | archive_dir: archives 29 | category_dir: categories 30 | code_dir: downloads/code 31 | i18n_dir: :lang 32 | skip_render: 33 | 34 | # Writing 35 | new_post_name: :title.md # File name of new posts 36 | default_layout: post 37 | titlecase: false # Transform title into titlecase 38 | external_link: 39 | enable: true # Open external links in new tab 40 | field: site # Apply to the whole site 41 | exclude: '' 42 | filename_case: 0 43 | render_drafts: false 44 | post_asset_folder: false 45 | relative_link: false 46 | future: true 47 | highlight: 48 | enable: true 49 | line_number: true 50 | auto_detect: false 51 | tab_replace: ' ' 52 | wrap: true 53 | hljs: true 54 | prismjs: 55 | enable: false 56 | preprocess: true 57 | line_number: true 58 | tab_replace: '' 59 | 60 | # Home page setting 61 | # path: Root path for your blogs index page. (default = '') 62 | # per_page: Posts displayed per page. (0 = disable pagination) 63 | # order_by: Posts order. (Order by date descending by default) 64 | index_generator: 65 | path: '' 66 | per_page: 5 67 | order_by: -date 68 | 69 | # Category & Tag 70 | default_category: uncategorized 71 | category_map: 72 | tag_map: 73 | 74 | # Metadata elements 75 | ## https://developer.mozilla.org/en-US/docs/Web/HTML/Element/meta 76 | meta_generator: true 77 | 78 | # Date / Time format 79 | ## Hexo uses Moment.js to parse and display date 80 | ## You can customize the date format as defined in 81 | ## http://momentjs.com/docs/#/displaying/format/ 82 | date_format: YYYY-MM-DD 83 | time_format: HH:mm:ss 84 | ## updated_option supports 'mtime', 'date', 'empty' 85 | updated_option: 'mtime' 86 | 87 | # Pagination 88 | ## Set per_page to 0 to disable pagination 89 | per_page: 5 90 | pagination_dir: page 91 | 92 | # Include / Exclude file(s) 93 | ## include:/exclude: options only apply to the 'source/' folder 94 | include: 95 | exclude: 96 | ignore: 97 | 98 | # Extensions 99 | ## Plugins: https://hexo.io/plugins/ 100 | ## Themes: https://hexo.io/themes/ 101 | theme: kira 102 | 103 | # Deployment 104 | ## Docs: https://hexo.io/docs/one-command-deployment 105 | deploy: 106 | - type: git 107 | repo: https://github.com/ch1ny/ch1ny.github.io 108 | 109 | # SEO 110 | sitemap: 111 | path: sitemap.xml 112 | 113 | aplayer: 114 | asset_inject: false -------------------------------------------------------------------------------- /packages/kira-hexo-demo/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "hexo-theme-kira-demo", 3 | "version": "0.0.0", 4 | "private": true, 5 | "scripts": { 6 | "prebuild": "hexo clean", 7 | "build": "hexo generate", 8 | "clean": "hexo clean", 9 | "dev": "hexo server", 10 | "predev": "npm run clean" 11 | }, 12 | "hexo": { 13 | "version": "7.3.0" 14 | }, 15 | "dependencies": { 16 | "hexo": "^7.3.0", 17 | "hexo-generator-archive": "^2.0.0", 18 | "hexo-generator-category": "^2.0.0", 19 | "hexo-generator-index": "^3.0.0", 20 | "hexo-generator-tag": "^2.0.0", 21 | "hexo-renderer-ejs": "^2.0.0", 22 | "hexo-renderer-marked": "^6.0.0", 23 | "hexo-renderer-stylus": "^2.1.0", 24 | "hexo-server": "^3.0.0", 25 | "hexo-theme-kira": "file:../kira-hexo", 26 | "hexo-theme-landscape": "^0.0.3" 27 | } 28 | } 29 | -------------------------------------------------------------------------------- /packages/kira-hexo-demo/scaffolds/draft.md: -------------------------------------------------------------------------------- 1 | --- 2 | title: {{ title }} 3 | tags: 4 | --- 5 | -------------------------------------------------------------------------------- /packages/kira-hexo-demo/scaffolds/page.md: -------------------------------------------------------------------------------- 1 | --- 2 | title: {{ title }} 3 | date: {{ date }} 4 | --- 5 | -------------------------------------------------------------------------------- /packages/kira-hexo-demo/scaffolds/post.md: -------------------------------------------------------------------------------- 1 | --- 2 | title: {{ title }} 3 | date: {{ date }} 4 | tags: 5 | --- 6 | -------------------------------------------------------------------------------- /packages/kira-hexo-demo/source/_posts/JavaScript/js原型链.md: -------------------------------------------------------------------------------- 1 | --- 2 | title: js原型链 3 | date: 2022-01-08 18:24:04 4 | tags: JavaScript 5 | categories: [编程] 6 | cover: https://pic1.zhimg.com/v2-535e92c65ddaff1a55f11df10c680c75_720w.jpg?source=172ae18b 7 | --- 8 | 9 | 在前端的面试中,JS 的原型链可谓是一个经久不衰的问题了,翻看各大厂的前端面经你几乎都能看到原型链的身影。这篇文章中我就来归纳一下这个知识点。 10 | 11 | 12 | 13 | 14 | 15 | # 认识原型链 16 | 17 | 其实在前面的文章中,我们也已经多次提到了**原型链**这个名词,所谓**原型链**其实就是一条由 JavaScript 实例向原型不断延伸从而构成的一条链状结构。 18 | 让我们来复习一下我们前两篇文章中提到的**构造函数**、**原型**和**实例**之间的关系: 19 | 每个**构造函数**都会自动地创建一个**原型对象**,这个对象有一个叫做**constructor**的属性指回**构造函数**。我们可以使用**new**操作符通过**构造函数**创建一个**实例对象**,每个**实例**内部都有一个指针(主流浏览器中可以使用 **\_\_proto\_\_** 获取这个指针)指向**原型对象**。而此时,如果**原型对象**本身也是另一种类型的实例,那么这个原型对象的 **\_\_proto\_\_** 又指向了**另一个原型对象**,而这**另一个原型对象**也有一个**constructor**指针指向**另一个构造函数**。 20 | 就这样依次不断地向上溯源,最终能构成一条链状结构,这就是**原型链**的基本思想。 21 | 光看上面的文字似乎会非常得绕,所以下面我们来通过一段代码让大家更好地感受一下什么是原型链: 22 | 23 | ```js 24 | // 构建一个父类 25 | function Father() {} 26 | Father.prototype.father = true; 27 | 28 | /** 29 | * 构建一个子类构造函数 30 | * 子类的原型对象定义为一个父类的实例 31 | */ 32 | function Son() {} 33 | Son.prototype = new Father(); 34 | 35 | // 子类实例化 36 | const instance = new Son(); 37 | ``` 38 | 39 | 在上面这个例子中,`instance` 是 `Son` 的实例,因此它们之间具有这样的关系: 40 | 41 | ```js 42 | instance.__proto__ === Son.prototype; 43 | ``` 44 | 45 | 我们看到,`Son.prototype` 是一个 `Father` 的实例,因此它们之间又具有这样的关系: 46 | 47 | ```js 48 | Son.prototype.__proto__ === Father.prototype; 49 | Son.prototype.__proto__.constructor === Father; 50 | ``` 51 | 52 | 我们把这两组关系结合起来,就能得到 `instance` 实例到我们写在代码中的最高类 `Father` 之间的关系: 53 | 54 | ```js 55 | instance.__proto__.__proto__ === Father.prototype; 56 | ``` 57 | 58 | 像这样,从**实例(instance)**向上,通过若干个 **\_\_proto\_\_** 组成的一条链,我们可以逐步建立起它到其所有父类之间的联系,这就是**原型链**。 59 | 60 | # 默认原型 61 | 62 | 实际上,原型链中还存在一环。默认情况下,所有的引用类型都继承自 Object ,这也是通过原型链实现的。所有函数的默认原型都是一个 Object 实例,这意味着这个实例的一个内部指针指向了 Object.prototype ,而 Object.prototype 的 \_\_proto\_\_ 指针最终指向了 **null** 。因此,上面的例子中,还存在了一层额外的隐式的继承关系,我们来尝试将这条原型链补全: 63 | 64 | ```js 65 | Father.prototype.__proto__ === Object.prototype; 66 | Object.prototype.__proto__ === null; 67 | instance.__proto__.__proto__.__proto__.constructor === Object; 68 | ``` 69 | 70 | # 原型链的问题 71 | 72 | 通过上面的介绍,我们发现我们可以通过原型链来实现简单的继承,但是这样实现的继承也存在着问题。 73 | 首要问题就是当原型包含引用类型的时候,引用值会在所有实例之间共享,正如我们上一篇文章中提到的那样,因此我们通常在构造函数中为属性赋值,原型中只定义函数。 74 | 而且,在我们使用原型实现继承时,原型实际上是另一个类型的实例,这意味着其他类型中原本应该是实例的属性变成了原型的属性,就像我们下面给出的这个例子一样: 75 | 76 | ```js 77 | function SuperClass() { 78 | this.arr = [0, 1, 2]; 79 | } 80 | 81 | function SubClass() {} 82 | SubClass.prototype = new SuperClass(); 83 | 84 | const instance1 = new SubClass(); 85 | console.log(instance1.arr); // [0,1,2] 86 | 87 | const instance2 = new SubClass(); 88 | instance2.arr.push(3); 89 | 90 | console.log(instance1.arr); // [0,1,2,3] 91 | console.log(instance2.arr); // [0,1,2,3] 92 | ``` 93 | 94 | 原型链的另一个问题是,子类在实例化时无法向父类的构造函数传参。即使非要传参,我们也不可能做到对不同的实例传递不同的参数。 95 | 96 | 结合上述两种问题,我们一般不会单独使用原型链来实现继承。 97 | -------------------------------------------------------------------------------- /packages/kira-hexo-demo/source/_posts/JavaScript/正确区分var、let和const.md: -------------------------------------------------------------------------------- 1 | --- 2 | title: 正确区分var、let和const 3 | date: 2021-09-12 12:35:47 4 | tags: JavaScript 5 | categories: [编程] 6 | cover: https://pic1.zhimg.com/v2-535e92c65ddaff1a55f11df10c680c75_720w.jpg?source=172ae18b 7 | --- 8 | 9 | var、let 和 const 都是 JavaScript 中用来声明变量的关键字,并且 let 和 const 关键字是在 ES6 中才新增的。既然都是用来声明变量的,那它们之间有什么区别呢? 10 | 11 | 12 | 13 | 14 | 15 | # var 和 let/const 的区别 16 | 17 | ## 作用域 18 | 19 | 对于 **var** 来说,它声明的变量的作用域是它当前的执行上下文。具体来说就是,当 **var**处于函数内部,则是该函数执行上下文;如果在函数外部,则是全局执行上下文。换句话说,对于使用**var**声明的变量,其作用域只能是函数块的或是全局的。 20 | 21 | 而使用**let、const**声明的变量,在除去全局作用域以及函数块作用域外,还新增了新的作用域限定范围,即使用 `{}` 包裹起来的代码块(被称作**块作用域**,可以是 if、while、switch 等关键字形成的代码块,也可以是单独使用`{}`形成的代码块)。 22 | 23 | ```js 24 | var varStr = 'outside'; 25 | function testVar() { 26 | var varStr = 'inside'; 27 | { 28 | var varStr = 'var不具有块作用域,我会把上面的inside覆盖掉'; 29 | console.log(varStr); // var不具有块作用域,我会把上面的inside覆盖掉 30 | } 31 | console.log(varStr); // var不具有块作用域,我会把上面的inside覆盖掉 32 | } 33 | console.log(varStr); // outside 34 | ``` 35 | 36 | ```js 37 | let letStr = 'outside'; 38 | function testLet() { 39 | let letStr = 'inside'; 40 | { 41 | let letStr = 'let存在块作用域,我只在块作用域里有效'; 42 | console.log(letStr); // let存在块作用域,我只在块作用域里有效 43 | } 44 | console.log(letStr); // inside 45 | } 46 | console.log(letStr); // outside 47 | ``` 48 | 49 | ## 重复声明 50 | 51 | 对于 **var**声明的变量可以重复声明,而**let**重复声明已存在的变量则会报错。 52 | 53 | ```js 54 | var v = 0; 55 | var v = 'str'; 56 | console.log(v); // str 57 | let l = 1; 58 | let l = 'l'; // ERROR: Identifier 'l' has already been declared 59 | console.log(l); 60 | ``` 61 | 62 | 至于为什么**var**能够重复声明变量则要提到**var**的变量提升机制了。 63 | 64 | ## 变量提升与暂时性死区 65 | 66 | 要讨论 var 和 let 的区别,这两个概念是无法绕过的。我们首先来看看什么叫做**变量提升(hoist)**。 67 | 68 | ### 变量提升 69 | 70 | 让我们先看一段代码: 71 | 72 | ```js 73 | function testVar() { 74 | console.log(v); 75 | var v = 0; 76 | } 77 | testVar(); // undefined 78 | ``` 79 | 80 | 有没有觉得很奇怪?在函数中,我们明明在`var v = 0;` 之前就访问了变量 `v`,但是这段代码并没有报错,而是打印了 `undefined`。 81 | 这是因为在 JavaScript 中,使用**var**声明变量时,会自动将声明提升到作用域的顶部。因此,在**ECMAScript**运行上面的这段代码时,它会被等价为如下代码: 82 | 83 | ```js 84 | function testVar() { 85 | var v; // 默认值为 undefined 86 | console.log(v); 87 | v = 0; 88 | } 89 | testVar(); // undefined 90 | ``` 91 | 92 | 同时,如果在作用域内某个变量被重复声明,也会把所有的声明都统一提升到顶部: 93 | 94 | ```js 95 | function func() { 96 | var a = 0; 97 | var a = 1; 98 | console.log(a); 99 | } 100 | // 其实等价于 101 | function _func() { 102 | var a; 103 | a = 0; 104 | a = 1; 105 | console.log(a); 106 | } 107 | ``` 108 | 109 | 因此,使用**var**重复声明变量也就不会造成报错。 110 | 111 | ### 暂时性死区 112 | 113 | 而对于**let**来说,是不存在所谓的“变量提升”的。那么,当我们尝试在使用**let**声明变量之前去访问变量会发生什么呢? 114 | 115 | ```js 116 | console.log(l); // ReferenceError: a is not defined 117 | let l = 5; 118 | ``` 119 | 120 | 这种情况下,毋庸置疑会甩出未定义变量的异常,因为 let 不具有变量提升的特性。那么接下来,我们再来看看另一段代码: 121 | 122 | ```js 123 | let i = 0; 124 | { 125 | console.log(i); // ReferenceError: Cannot access 'i' before initialization 126 | let i = 5; 127 | } 128 | console.log(i); 129 | ``` 130 | 131 | 在上面这段代码中,我们通过块作用域将代码分为内外两部分。当执行至第三行时,因为我们已经声明了变量 `i`,理论上是不会报错的,如果此时又没有新的用 let 声明的 i ,因此,它应该会向上寻找上一个作用域中的变量 i 。然而,在这个例子中,我们在块作用域的调用代码后面重新声明了变量`i`,JavaScript 引擎也发现了这个新的声明,因此在这个块作用域中将不会再使用上一层作用域的变量,此时第三行的这个调用就显得有点尴尬了。于是,JavaScript 引擎甩出异常:`ReferenceError: Cannot access 'i' before initialization` 132 | 提示我们不要在这个变量初始化之前去访问它。 133 | 而所谓的**暂时性死区**(**temporal dead zone**)就是指在使用**let**声明变量之前的整个执行瞬间。 134 | 135 | ## var/let 小结 136 | 137 | 在讲述了上述几个不同之后,我们来看一段代码: 138 | 139 | ```js 140 | function varLoop() { 141 | for (var i = 0; i < 5; i++) { 142 | setTimeout(() => { 143 | console.log(i); 144 | }, i * 1000); 145 | } 146 | } 147 | ``` 148 | 149 | 我们想用这段代码每隔 1s 打印一个递增的数字,但是记住我们上面说的变量提升,这段代码在**ECMAScript**看来实际上是这样的: 150 | 151 | ```js 152 | function varLoop() { 153 | var i; 154 | for (i = 0; i < 5; i++) { 155 | setTimeout(() => { 156 | console.log(i); 157 | }, i * 1000); 158 | } 159 | } 160 | ``` 161 | 162 | 它实际上做到的,是每隔 1s 打印一个5。 163 | 要进行修改,我们可以选择使用**let**来声明变量: 164 | 165 | ```js 166 | function letLoop() { 167 | for (let i = 0; i < 5; i++) { 168 | setTimeout(() => { 169 | console.log(i); 170 | }, i * 1000); 171 | } 172 | } 173 | ``` 174 | 175 | 之所以**let**能起作用是因为**let**具有块作用域,变量`i`被限制在了`for`的循环体内,同时也涉及到了一些闭包的特性。 176 | 如果用闭包理解上述两种代码,可以理解为使用**var**是创建了一个闭包被调用了 5 次,而**let**是创建了 5 个独立的闭包各自被调用一次。 177 | 最后给大家提供一个使用**var**的纯闭包解法,很多公司面试的时候可能会问到: 178 | 179 | ```js 180 | function varLoop() { 181 | for (var i = 0; i < 5; i++) { 182 | (function (i) { 183 | setTimeout(() => { 184 | console.log(i); 185 | }, i * 1000); 186 | })(i); 187 | } 188 | } 189 | ``` 190 | 191 | 至于**闭包**,以后再和大家介绍吧。 192 | 193 | # const 194 | 195 | 最后来讲讲 const。 196 | const 的行为其实和 let 是基本一致的,唯一一个重要区别是用 const 声明变量时必须同时赋值,且 const 声明的是一个常量,任何尝试修改 const 声明的变量的行为都会报错。 197 | 198 | 但是,如果 const 声明的变量指向的是一个对象的话,对象内部的属性依旧是可以修改的,这是因为此时的 const 指向的是对象的指针的地址,而对象内部的数据存在于内存的其他地方。 199 | 200 | ```js 201 | const obj = { 202 | name: '德布罗煜', 203 | age: 20, 204 | }; 205 | obj.age += 1; 206 | console.log(obj); // { name: '德布罗煜', age: 21 } 207 | obj = {}; // TypeError: Assignment to constant variable. 208 | ``` 209 | 210 | # 声明风格及最佳实践 211 | 212 | ## 不使用 var 213 | 214 | 有了 let 和 const 之后。其实很多开发者会发现不再需要 var 了。同时,由于 let 和 const 拥有了明确的、新的作用域、声明位置以及常量的不变值,限制自己在代码中只使用 let 和 const 可以显著提高代码的质量。 215 | 216 | ## const 优先 217 | 218 | 使用 const 声明变量可以让浏览器强制要求变量在运行时保持不变,也可以让静态代码分析工具提前发现非法的赋值操作。因此建议只对明确了未来会存在改变值的变量使用 let。 219 | -------------------------------------------------------------------------------- /packages/kira-hexo-demo/source/_posts/JavaScript/浅谈JS中的闭包.md: -------------------------------------------------------------------------------- 1 | --- 2 | title: 浅谈JS中的闭包 3 | date: 2021-09-28 10:36:15 4 | tags: JavaScript 5 | categories: [编程] 6 | cover: https://pic1.zhimg.com/v2-535e92c65ddaff1a55f11df10c680c75_720w.jpg?source=172ae18b 7 | --- 8 | 9 | 对于 JavaScript 初学者来说,JavaScript 有着这样一个概念十分重要,几乎是每个前端工程师面试时必然会遇到的一个问题,JS 的**闭包(closure)**。今天我们就来浅谈一下 JS 中的闭包究竟是怎样的东西。 10 | 11 | 12 | 13 | 14 | 15 | # 闭包的定义 16 | 17 | 要弄懂什么是闭包,我们需要先给闭包下一个定义。 18 | 根据 MDN 文档上的定义: 19 | 20 | > 一个函数和对其周围状态(**lexical environment,词法环境**)的引用捆绑在一起(或者说函数被引用包围),这样的组合就是**闭包**(**closure**)。也就是说,闭包让你可以在一个内层函数中访问到其外层函数的作用域。在 JavaScript 中,每当创建一个函数,闭包就会在函数创建的同时被创建出来。 21 | 22 | 可以看到,在这个定义中,我们引入了一些特殊的概念——**作用域**。已经有过编程基础的同学应该不会对这个词感到陌生,在其他的语言中也同样存在作用域的概念,那么接下来,我们将先介绍什么是 JavaScript 中的词法作用域。 23 | 24 | # 词法作用域 25 | 26 | 首先,我们来考虑这样一个例子: 27 | 28 | ```js 29 | function func() { 30 | let num = 1; 31 | const plus = function () { 32 | console.log(++num); 33 | }; 34 | plus(); 35 | } 36 | func(); 37 | ``` 38 | 39 | 在这个例子中,我们通过调用 `func` 函数,创建了一个局部变量 `num` 和一个叫做 `plus` 的函数。由于`plus`是在`func`内部创建的,因此也只能在`func`内部被调用。对于`plus`函数来说,它没有自己的局部变量,但它能够调用其父函数`func`中的局部变量`num`。 40 | 我们把这段代码执行一下就能发现,在控制台中打印了数字 2 。这个 _词法作用域_ 的例子描述了分析器如何在函数嵌套的情况下解析变量名。词法(lexical)一词指的是,词法作用域根据源代码中声明变量的位置来确定该变量在何处可用。嵌套函数可访问声明于它们外部作用域的变量。 41 | 42 | # 理解闭包 43 | 44 | 有了上面的例子,我们就能理解闭包究竟是什么样的东西了。 45 | 继承我们上面的例子,虽然我们已经能够在外部访问到`num`变量,但是每次执行`func`函数实际上都创建了新的`num`变量,我们想让`num`持续地自加,应当如何实现?其实只需要对上方的代码做一点小小的修改即可: 46 | 47 | ```js 48 | function func() { 49 | let num = 1; 50 | const plus = function () { 51 | console.log(++num); 52 | }; 53 | return plus; 54 | } 55 | 56 | const add = func(); 57 | add(); // 2 58 | add(); // 3 59 | ``` 60 | 61 | 经过修改后的`func`函数,直接返回了`plus`方法,其后我们可以直接通过调用这个方法来实现`num`的持续自加。 62 | 63 | 看到这里,相信大家其实都很明白了: 64 | 65 | > 所谓闭包,就是通过一个函数包裹局部变量,并返回一个嵌套函数,外部环境通过调用返回的嵌套函数来达到访问并操作函数内部的局部变量。 66 | 67 | 最后给大家看一个稍微复杂一点的闭包例子: 68 | 69 | ```js 70 | function Closure(step) { 71 | let num = 0; 72 | return function () { 73 | /** 74 | * 由于返回的函数中使用到了变量 step , 75 | * 因此即使 step 作为形参传入父函数也不会被当做垃圾回收 76 | */ 77 | console.log((num += step)); 78 | }; 79 | } 80 | const c5 = Closure(5); // 一步自加 5 81 | const c10 = Closure(10); // 一步自加 10 82 | c5(); // 5 83 | c10(); // 10 84 | c5(); // 10 85 | c10(); // 20 86 | ``` 87 | 88 | 相信大家也能轻松地理解上述代码的执行过程。 89 | 90 | # 闭包的实际使用 91 | 92 | 在前端开发中,闭包的使用是非常灵活的,比如说对于**防抖**(**debounce**)和**节流**(**throttle**)函数的封装: 93 | 94 | ```js 95 | /** 96 | * @description 防抖函数的封装 97 | * @param func {Function} 被封装的函数 98 | * @param delay {Number} 间隔时长(单位:ms) 99 | * @param instant {Boolean} 是否立即执行,默认为 true 100 | */ 101 | function debounce(func, delay, instant = true) { 102 | let timeout; 103 | if (instant) 104 | return function () { 105 | // 立即执行版防抖 106 | if (timeout) { 107 | clearTimeout(timeout); 108 | } 109 | timeout = setTimeout(() => { 110 | func.apply(this, arguments); 111 | timeout = null; 112 | }, delay); 113 | }; 114 | else 115 | return function () { 116 | // 非立即执行版防抖 117 | if (timeout) { 118 | clearTimeout(timeout); 119 | } else { 120 | func.apply(this, arguments); 121 | } 122 | timeout = setTimeout(() => { 123 | timeout = null; 124 | }, delay); 125 | }; 126 | } 127 | 128 | /** 129 | * @description 节流函数的封装 130 | * @param func {Function} 被封装的函数 131 | * @param delay {Number} 间隔时长(单位:ms) 132 | * @param instant {Boolean} 是否立即执行,默认为 true 133 | */ 134 | function throttle(func, delay, instant = true) { 135 | let timeout; 136 | if (instant) 137 | return function () { 138 | // 立即执行版节流 139 | if (!timeout) { 140 | func.apply(this, arguments); 141 | timeout = setTimeout(() => { 142 | timeout = null; 143 | }, delay); 144 | } 145 | }; 146 | else 147 | return function () { 148 | // 非立即执行版节流 149 | if (!timeout) { 150 | timeout = setTimeout(() => { 151 | func.apply(this, arguments); 152 | timeout = null; 153 | }, delay); 154 | } 155 | }; 156 | } 157 | ``` 158 | 159 | # 注意事项 160 | 161 | ## 性能考量 162 | 163 | 如果不是出于某些特殊目的不得不使用闭包,在其他函数中创建新的函数是不推荐的做法。因为闭包在**处理速度**和**内存消耗**方面对 JS 的性能具有负面影响。 164 | 165 | ## 内存泄漏 166 | 167 | 如果很不幸,您的代码中必须大量使用闭包,请务必注意是否有**内存泄漏**的风险。如果可能,请务必在不需要闭包后将闭包中的引用变量置为 **null** ,以便 JS 能将它们视为不再需要的垃圾回收。 168 | -------------------------------------------------------------------------------- /packages/kira-hexo-demo/source/_posts/JavaScript/理解JS中的防抖与节流.md: -------------------------------------------------------------------------------- 1 | --- 2 | title: 理解 JS 中的防抖与节流 3 | date: 2022-01-11 10:17:29 4 | tags: [JavaScript] 5 | categories: [编程] 6 | cover: https://pic1.zhimg.com/v2-535e92c65ddaff1a55f11df10c680c75_720w.jpg?source=172ae18b 7 | --- 8 | 9 | > 在前端项目开发中,在合适的地方做好**防抖**与**节流**是十分重要的。首先我们要知道,哪些地方适合采用防抖节流进行开发。一个重要的特征就是——**某个函数在短时间内被频繁持续地执行**。 10 | 11 | 12 | 13 | 下面将给大家展示一个例子,方便理解: 14 | 15 | ```html 16 | 17 | 18 | 19 | 20 | 21 | 22 | 防抖节流 23 | 43 | 44 | 45 | 46 |

未采用防抖与节流,函数被频繁触发

47 |
0
48 | 49 | 50 | 63 | 64 | ``` 65 | 66 | 通过以上代码,我们构造了一个简单的函数被频繁触发的 demo 。 67 | ![在这里插入图片描述](https://img-blog.csdnimg.cn/a9127a35ad0047789b2892135ed3bf96.png) 68 | 这是一个灰色的 `div` ,当鼠标在它里面移动时,其内容会加一,效果如下: 69 | ![在这里插入图片描述](https://img-blog.csdnimg.cn/8a0a38e3a5454aafbab6062aa9263468.gif) 70 | 可以看到,当我们对这个函数不作任何处理时,我们每滑动一次鼠标,都会频繁地触发函数。当该函数执行一次的开销变得很大时(比如发送 AJAX 请求),这样的执行方式将会给用户带来地狱般的使用体验。 71 | 下面我们来看看如何通过**防抖**(**debounce**)和**节流**(**throttle**)来解决这个问题。 72 | 73 | **防抖** 74 | 所谓防抖(debounce),是指让函数保持一定的时间间隔触发。当某函数触发过一次后,要求其等待一段时间后才能再次执行。 75 | 下面我来演示一下如何通过防抖技术解决我们上面给出的样例中出现的问题。 76 | 77 | ```html 78 | 79 | 80 |

这是防抖

81 |
0
82 | 83 | 84 | 112 | ``` 113 | 114 | 在**防抖**解决方案中,我们为函数添加了两个新的变量:`noMove` 和 `timeout` 。其中,`noMove` 是一个布尔值,用来记录在一定时间范围内函数是否没有被触发,一旦触发函数将会把 `noMove` 置为 `false` 。同时启动一个计时器,赋给 `timeout` 变量,它负责在指定时间过后将 `noMove` 的值再次恢复为 `true` ,以使函数能够正常执行。当然,每当函数在规定时长内再次被触发时,我们会移除上一轮函数执行中赋值给 `timeout` 的计时器,并重新计时。 115 | 以上便是**防抖**技术的基本思想。下面我们来看看实际效果。 116 | ![在这里插入图片描述](https://img-blog.csdnimg.cn/63e5779d43f743f7be350ff1ce7fcb4d.gif) 117 | 通过防抖的实现后,我们可以看见 demo 中的 `div` 依旧会因为鼠标的移动而使自身的内容加一,但是执行远没有最初那么频繁了。而且在函数执行一次后,只有当一段时间没有再次执行函数之后,该函数才会再次生效,否则,频繁地触发函数将会导致函数永远无法执行。 118 | 119 | **节流** 120 | 防抖与节流都能解决前端页面函数触发过于频繁的问题,但两者的基本思想并不完全相同,下面我们把**防抖**的代码修改为**节流**的解决方案: 121 | 122 | ```html 123 | 124 |

这是节流

125 |
0
126 | 127 | 128 | 151 | ``` 152 | 153 | **节流**的基本思想是让函数触发保持在一定的速率下,以免频繁地执行。在这个方案下,我们同样引入了变量 `noMove` 。当触发并执行相关函数后,我们让 `noMove` 置为 `false` ,并启动一个计时器,让它在一定时间后将 `noMove` 恢复为 `true` 。下面是**节流**的实现效果: 154 | ![在这里插入图片描述](https://img-blog.csdnimg.cn/49fd57d5bbd04aa0bd3190eacb240637.gif) 155 | 156 | 现在,我们还可以对**防抖**函数与**节流**函数做进一步封装,使其更加偏向实际开发使用。封装如下: 157 | 158 | ```javascript 159 | function debounce(func, wait) { 160 | let timeout; 161 | return function () { 162 | if (timeout) { 163 | clearTimeout(timeout); 164 | } else { 165 | func.apply(this, arguments); 166 | } 167 | timeout = setTimeout(() => { 168 | timeout = null; 169 | }, wait); 170 | }; 171 | } 172 | 173 | function throttle(func, wait) { 174 | let timeout; 175 | return function () { 176 | if (!timeout) { 177 | func.apply(this, arguments); 178 | timeout = setTimeout(() => { 179 | timeout = null; 180 | }, wait); 181 | } 182 | }; 183 | } 184 | 185 | document.querySelector('#debounce').onmousemove = debounce(() => { 186 | document.getElementById('debounce').innerText = ++document.getElementById('debounce').innerText; 187 | }, 1000); 188 | 189 | document.querySelector('#throttle').onmousemove = throttle(() => { 190 | document.getElementById('throttle').innerText = ++document.getElementById('throttle').innerText; 191 | }, 1000); 192 | ``` 193 | 194 | 以上就是**防抖**与**节流**的基本思想的介绍,读者应该根据自己开发项目中的实际需要选择不同的解决方案,同时上面给出的代码也仅供参考,真正重要的是两种解决方案的基本思想,开发者应该根据实际开发来调整具体的实现逻辑。 195 | -------------------------------------------------------------------------------- /packages/kira-hexo-demo/source/_posts/Node.js/【Node.js学习】初识Node.js.md: -------------------------------------------------------------------------------- 1 | --- 2 | title: 【Node.js学习】初识Node.js 3 | date: 2022-04-02 19:54:30 4 | tags: [Node.js] 5 | categories: [编程] 6 | cover: https://i1.wp.com/subrutin.com/wp-content/uploads/2019/01/2400%D1%851260-rw-blog-node-js.png 7 | --- 8 | 9 | 前两天接到未来在蚂蚁集团实习时的师兄的微信好友,他让我在空闲时间学习一下 Node.js,于是决定开个新坑,把我学习 Node.js 的路径记录下来。 10 | 11 | 12 | 13 | 14 | 15 | > 简单来说,Node.js 就是一个运行在服务器端的 JavaScript。 16 | > Node.js 是一个基于 Chrome JavaScript 运行时建立的一个平台。 17 | > Node.js 是一个事件驱动 I/O 服务端 JavaScript 环境,基于 Google 的 V8 引擎,V8 引擎执行 JavaScript 的速度非常快,性能非常好。 18 | 19 | # 序言 20 | 21 | 首先,我们来简单介绍一下为什么 JavaScript 可以在浏览器中被执行。 22 | 在浏览器中,存在着一个 JavaScript 解析引擎,它会去解析我们运行在浏览器端的 JavaScript 代码,并执行操作。 23 | 不同的浏览器有着不同的 JavaScript 解析引擎,在众多引擎中,Chrome 浏览器的 V8 引擎性能最好。 24 | 25 | 既然在前端,JavaScript 有着不可替代的地位,那么请问,JavaScript 能否也用于后端开发呢? 26 | 当提到后端开发,大家可能过多了解的是 **Java**、**Python**、**C++** 等语言。 27 | 而时至今日,连 JavaScript 也能作为后端开发的主要语言了,但是在服务端运行,必然是脱离了浏览器运行环境的,那么我们又应该怎样才能让我们的 JavaScript 代码运行在服务器端呢?因此,我们就必须要引入 **Node.js** 来作为我们的运行环境。这便是 **Node.js** 的作用了。 28 | 29 | # Node.js 简介 30 | 31 | ## 什么是 Node.js 32 | 33 | **Node.js** 是一个基于 Chrome V8 引擎的 **JavaScript 运行环境**。 34 | 35 | ## Node.js 中的 JavaScript 运行环境 36 | 37 | Node.js 中的 JavaScript 运行环境,由 V8 引擎及 Node 内置 API 组成。 38 | 其中,V8 引擎负责解析服务端的 JavaScript 代码并执行。 39 | 内置 API 包括 40 | 41 | - fs 42 | - path 43 | - http 44 | - JS 内置对象 45 | - querystring 46 | - etc… 47 | 48 | 后端的 JavaScript 代码可通过调用这些 API 进行业务处理。 49 | 50 | > 在 Node.js 中是无法调用 DOM 和 BOM 等**浏览器内置 API**的。 51 | 52 | ## Node.js 可以做什么 53 | 54 | Node.js 作为一个 JavaScript 的基础运行环境,它仅仅提供了最基础的功能和 API。然而,基于 Node.js 提供的这些基础功能,很多强大的工具和框架如雨后春笋般层出不穷。例如: 55 | 56 | - 基于 [Express 框架](https://expressjs.com.cn/),可以快速构建 Web 应用。 57 | - 基于 [Electron 框架](https://electronjs.org/),可以快速构建跨平台的桌面应用。 58 | - 基于 [restify 框架](https://restify.com/),可以快速构建 API 接口项目。 59 | 60 | 总之,Node.js 是**大前端时代**的利器,是辅助前端程序员提高**行业竞争力**的法宝。 61 | 62 | # Node.js 的安装 63 | 64 | 其实对于前端程序员来说,一旦涉及到了框架就必然会接触到 Node.js,因此我的电脑上是已经装好了 Node.js 的,具体的安装步骤本文也不再过多赘述,有需要的读者可以尝试如下博客:[Node.js 安装教程](https://blog.csdn.net/Small_Yogurt/article/details/104968169) 65 | 66 | # 在 Node 中执行 JavaScript 代码 67 | 68 | 在安装好 Node.js 后,我们就可以尝试通过 Node.js 环境来运行 JavaScript 代码了。 69 | 我们选择一个文件夹,在它的下面新建一个 js 文件,假设命名为 **HelloWorld.js** 。 70 | 在这个 js 文件中,我们写上如下的代码: 71 | 72 | ```js 73 | console.log('Hello World!'); 74 | console.log('Welcome to Node.js'); 75 | ``` 76 | 77 | 之后,我们在该文件夹下打开终端(命令行),输入命令(`node 要执行的文件路径`)执行这个脚本文件: 78 | 79 | ```bat 80 | node HelloWorld.js 81 | ``` 82 | 83 | ![执行结果](https://kira.host/assets/Pictures/Others/20220402205833.png) 84 | -------------------------------------------------------------------------------- /packages/kira-hexo-demo/source/_posts/Node.js/【Node.js学习】简单认识express.md: -------------------------------------------------------------------------------- 1 | --- 2 | title: 【Node.js学习】简单认识express 3 | date: 2022-04-04 20:53:00 4 | tags: [Node.js] 5 | categories: [编程] 6 | --- 7 | 8 | 在前面的学习中,我们已经学会使用 Node.js 的 http 模块来构建一个最基本的 Web 服务器了。今天,我们来学习一款新的框架——Express,并学习如何通过 express 来构建一个 web 服务器。 9 | 10 | 11 | 12 | 13 | 14 | # 初识 express 15 | 16 | ## express 简介 17 | 18 | Express 是一款高度包容、快速而极简的 Node.js Web 框架。但是我们已经有了 http 模块用以创建 Web 服务器,那么我们为什么还要学习 express 呢?因为内置的 http 模块是最基本的模块,使用起来较为复杂,开发效率低;而 Express 是基于 http 模块进一步封装出来的,能够极大地提高开发效率。 19 | 20 | ## express 能够做什么 21 | 22 | 对于前端开发者来说,服务器一般分为两种: 23 | 24 | - **web 网站服务器**:专门对外提供 web 网页资源的服务器。 25 | - **API 接口服务器**:专门对外提供 API 接口的服务器。 26 | 27 | 使用 express,我们可以方便、快速地创建 **web 网站服务器** 或 **API 接口服务器** 。 28 | 29 | # express 的基本使用 30 | 31 | ## express 的安装 32 | 33 | 在项目根目录下执行如下指令: 34 | 35 | ```bat 36 | yarn add express 37 | 或 38 | npm install express 39 | ``` 40 | 41 | ## express 的基本使用 42 | 43 | ### 创建基本的 web 服务器 44 | 45 | ```js 46 | // 1. 导入 express 47 | const express = require('express'); 48 | // 2. 创建 web 服务器 49 | const app = express(); 50 | 51 | // 3. 调用 app.listen(),启动服务器 52 | app.listen(80, () => { 53 | console.log('服务器开始监听 80 端口'); 54 | }); 55 | ``` 56 | 57 | ### 监听 GET / POST 请求 58 | 59 | 在通过 express 创建好基本的服务器后,我们可以用它来监听网络中的 GET / POST 请求,并做出相应的处理。 60 | 61 | #### 监听 GET 请求 62 | 63 | 本节我们先来学习如何监听 GET 请求。 64 | 通过 `app.get()` 方法,我们可以监听客户端的 GET 请求,具体的语法格式如下: 65 | 66 | ```js 67 | /** 68 | * @param {String} url 客户端请求的 URL 地址 69 | * @param {Function} (req,resp)=>{} 请求对应的处理函数 70 | */ 71 | app.get(url, (req, resp) => { 72 | // do something 73 | }); 74 | ``` 75 | 76 | #### 监听 POST 请求 77 | 78 | 监听 GET 请求类似,我们通过 `app.post()` 方法可以监听客户端的 POST 请求,具体语法格式如下: 79 | 80 | ```js 81 | /** 82 | * @param {String} url 客户端请求的 URL 地址 83 | * @param {Function} (req,resp)=>{} 请求对应的处理函数 84 | */ 85 | app.post(url, (req, resp) => { 86 | // do something 87 | }); 88 | ``` 89 | 90 | #### 将结果响应给客户端 91 | 92 | 在上面的代码中,我们看到两个方法的第二个入参都是一个回调函数,这个回调函数的第二个参数是一个响应对象(正如我们在 http 模块那一篇文章中提到的一样)。而我们可以通过调用 `res.send()` 方法,把处理好的内容发送给客户端: 93 | 94 | ```js 95 | const getUser = () => ({ 96 | name: '德布罗煜', 97 | age: new Date().getFullYear() - 2001, 98 | }); 99 | 100 | app.get('/user', (req, resp) => { 101 | resp.send(getUser()); 102 | }); 103 | 104 | app.post('/user', (req, resp) => { 105 | resp.send(getUser()); 106 | }); 107 | ``` 108 | 109 | 我们通过 URL 向服务器发送一条 GET 请求,下面是服务器的返回结果: 110 | ![输出样例](https://kira.host/assets/Pictures/Others/20220404223433.png) 111 | 112 | 创建上述一个 Web 服务器的完整代码如下: 113 | 114 | ```js 115 | const express = require('express'); 116 | const app = express(); 117 | 118 | const getUser = () => ({ 119 | name: '德布罗煜', 120 | age: new Date().getFullYear() - 2001, 121 | }); 122 | 123 | app.get('/user', (req, resp) => { 124 | resp.send(getUser()); 125 | }); 126 | 127 | app.post('/user', (req, resp) => { 128 | resp.send(getUser()); 129 | }); 130 | 131 | app.listen(80, () => { 132 | console.log('服务器开始监听 80 端口'); 133 | }); 134 | ``` 135 | 136 | #### 获取 URL 中携带的查询参数 137 | 138 | 在上一节中,我们成功地使用 express 监听到了客户端发出的 GET 请求,本节我们将学习如何通过 express 获取 GET 请求中 URL 携带的查询参数。 139 | 通过 `req.query` **对象**,可以访问到客户端通过**查询字符串**的形式发送到服务器的参数。 140 | 示例代码如下: 141 | 142 | ```js 143 | app.get('/', (req, resp) => { 144 | resp.send(req.query); 145 | }); 146 | ``` 147 | 148 | `req.query` 默认是一个**空对象(`{}`)** 149 | 150 | #### 获取 URL 中的动态参数 151 | 152 | 通过 `req.params` 对象,可以访问到 URL 中通过 `:` 匹配到的**动态参数**: 153 | 154 | ```js 155 | app.get('/user/:id/:name', (req, resp) => { 156 | // req.params 默认也是一个空对象 157 | // 里面存放着通过 : 动态匹配到的值 158 | // 像这里的实例代码就是匹配了多个参数 159 | resp.send(req.params); 160 | }); 161 | ``` 162 | 163 | # 托管静态资源 164 | 165 | ## express.static() 166 | 167 | express 提供了一个非常好用的函数:`express.static()` ,通过这个函数,我们可以非常方便地创建一个**静态资源服务器**。 168 | 例如,通过如下代码,我们就可以将 `public` 目录下的图片、css、js 文件对外提供静态资源访问服务了: 169 | 170 | ```js 171 | app.use(express.static('public')); 172 | ``` 173 | 174 | 假设存在这样一个目录结构: 175 | 176 | ``` 177 | ├── node.js 178 | └── public 179 | ├── images 180 | │ └── img.png 181 | ├── css 182 | │ └── style.css 183 | └── js 184 | └── test.js 185 | ``` 186 | 187 | 我们将服务器代码写在了 `node.js` 文件中,运行该脚本文件,我们便能通过如下 URL 访问到 `public` 文件夹下的静态资源: 188 | 189 | - `http://localhost/images/img.png` 190 | - `http://localhost/css/style.css` 191 | - `http://localhost/js/test.js` 192 | 193 | 我们也可以用这个函数托管多个静态资源目录,但是访问静态资源文件时,express.static() 函数会根据目录的添加顺序查找所需的文件。举个例子: 194 | 195 | ```js 196 | app.use(express.static('public')); 197 | app.use(express.static('assets')); 198 | ``` 199 | 200 | 通过这段代码我们同时添加了 `public` 文件夹和 `assets` 文件夹的静态文件资源托管。当我们请求静态资源文件时,会先去先添加的 `public` 文件夹中查找文件,如果没有查询到则会去 `assets` 文件夹中寻找。因此,当我们尝试访问 `http://localhost/index.html` 时,如果在 `public` 文件夹下和 `assets` 文件夹下都有 `index.html` 文件,最终返回给客户端的一定是 `public/index.html` 。 201 | 202 | ## 挂载路径前缀 203 | 204 | 如果我们希望在托管的**静态资源访问路径**前,**挂载路径前缀**,则可以使用如下的方式: 205 | 206 | ```js 207 | app.use('/public', express.static('public')); 208 | ``` 209 | 210 | 这样我们就可以通过 `http://localhost/public/index.html` 访问 `public` 文件夹下的 `index.html` 了。也可以避开上一小节讲的重名文件只能访问其中一个的限制。 211 | -------------------------------------------------------------------------------- /packages/kira-hexo-demo/source/_posts/Node.js/【Node.js学习】简单认识fs文件系统模块.md: -------------------------------------------------------------------------------- 1 | --- 2 | title: 【Node.js学习】简单认识fs文件系统模块 3 | date: 2022-04-02 21:03:53 4 | tags: [Node.js] 5 | categories: [编程] 6 | --- 7 | 8 | 在本文中,我们将对 Node.js 提供的 fs 文件系统模块进行初步的认识 9 | 10 | 11 | 12 | 13 | 14 | # fs 文件系统模块简介 15 | 16 | **fs 模块**是 Node.js 官方提供的、用来操作文件的模块。它提供了一系列的方法和属性,用来满足用户对文件操作的需求。 17 | 例如: 18 | 19 | - fs.readFile()方法,用来**读取**指定文件中的内容 20 | - fs.writeFile()方法,用来向指定的文件中**写入**内容 21 | 22 | 如果要在 JavaScript 代码中使用 fs 模块来操作文件,则需要使用如下方法将它引入: 23 | 24 | ```js 25 | const fs = require('fs'); 26 | ``` 27 | 28 | # 使用 fs 文件系统模块 29 | 30 | ## 读取指定文件中的内容 31 | 32 | ### fs.readFile()的语法格式 33 | 34 | 使用 fs.readFile()方法,可以读取指定文件中的内容,语法格式如下: 35 | 36 | ```js 37 | /** 38 | * @param {String} path 必选参数,字符串,表示需要读取的文件的路径 39 | * @param options 可选参数,以什么编码格式来读取文件 40 | * @param {Function} callback 必选参数,表示读取完文件后,可以通过该回调函数拿到读取的结果 41 | */ 42 | fs.readFile(path[, options], callback) 43 | ``` 44 | 45 | ### fs.readFile()的示例代码 46 | 47 | 以 utf-8 的编码格式,读取指定文件的内容,并打印 err 和 data 的值 48 | 49 | ```js 50 | const fs = require('fs'); 51 | fs.readFile('./text.txt', 'utf8', function (err, data) { 52 | console.log(err); 53 | console.log('------'); 54 | console.log(data); 55 | }); 56 | ``` 57 | 58 | ![执行结果](https://kira.host/assets/Pictures/Others/20220402212450.png) 59 | 60 | 也就是当文件读取成功时,`err`的值为`null`,而`data`则是读取的内容 61 | 那么此时我们将原本的文本文件删除,让我们尝试读取的文件并不存在,会发生什么呢? 62 | ![执行结果](https://kira.host/assets/Pictures/Others/20220402212716.png) 63 | 可以看到,当发生错误时,`err`值为一个保存了错误信息的对象,`data`的值为`undefined`。 64 | 65 | ### 判断文件是否读取成功 66 | 67 | 经过上面的示例代码,我们可以发现: 68 | 69 | - 当文件读取成功时,`err`的值为`null` 70 | - 当文件读取失败时,`err`的值为一个对象 71 | 72 | 因此,我们可以直接通过判断`err`来判断文件是否读取成功了。代码如下: 73 | 74 | ```js 75 | const fs = require('fs'); 76 | fs.readFile('./text.txt', 'utf8', function (err, data) { 77 | if (err) { 78 | console.log('文件读取失败: ' + err.message); 79 | } else { 80 | console.log('文件读取成功: ' + data); 81 | } 82 | }); 83 | ``` 84 | 85 | ## 向指定文件中写入内容 86 | 87 | ### fs.writeFile()的语法格式 88 | 89 | 使用 fs.writeFile()方法,可以向指定的文件中写入内容,语法格式如下: 90 | 91 | ```js 92 | /** 93 | * @param {String} path 必选参数,字符串,表示需要写入的文件的路径 94 | * @param data 必选参数,表示需要写入的内容 95 | * @param options 可选参数,以什么编码格式来写入数据,默认utf8 96 | * @param {Function} callback 必选参数,表示写入完成之后执行的回调函数 97 | */ 98 | fs.writeFile(path, data[, options], callback) 99 | ``` 100 | 101 | ### fs.writeFile()的示例代码 102 | 103 | 向指定文件中写入内容: 104 | 105 | ```js 106 | const fs = require('fs'); 107 | fs.writeFile('./HelloNode.txt', 'Hello Node.js!', function (err) { 108 | console.log(err); 109 | }); 110 | ``` 111 | 112 | 如果文件写入成功,则`err`的值为`null`(若文件不存在会自行创建文件并写入内容)。 113 | 如果文件写入失败(比如写入不存在的盘符),则`err`的值为一个错误对象。 114 | 115 | ### 判断文件是否写入成功 116 | 117 | 同 fs.readFile()的判断方法一样,我们只需要判断`err`的值能否转换为`true`就能判断出文件是否写入成功。 118 | 119 | ```js 120 | const fs = require('fs'); 121 | fs.writeFile('./HelloNode.txt', 'Hello Node.js!', function (err) { 122 | if (err) { 123 | console.log('文件写入失败: ' + err.message); 124 | } else { 125 | console.log('文件写入成功'); 126 | } 127 | }); 128 | ``` 129 | 130 | # 动态路径拼接问题 131 | 132 | 在使用 fs 等依赖于文件路径的模块时,我们必然会遇到动态路径拼接的问题。 133 | 当我们过度依赖诸如 `./` 或 `../` 这类相对路径时,可能会有某些文件的相对路径指向错误的情况发生。这是因为 Node.js 的相对路径依赖于执行脚本的终端执行命令时所在的位置。 134 | 135 | 举个例子,依旧是上面给出的 `fs.writeFile()` 的示例代码,假设它所在的目录为 `D:/src`。当我们在 `D:/src` 目录下打开终端,执行该脚本文件,它会在 `D:/src/HelloNode.txt` 中写入 `Hello Node.js!`。但当我们在 `D:/xxx/yyy` 目录下打开终端,执行命令如下: 136 | 137 | ```bat 138 | D:/xxx/yyy>node D:/src/writeFile.js 139 | ``` 140 | 141 | 它实际上会在 `D:/xxx/yyy` 目录下新建文件并写入内容。 142 | 143 | 因此,为了解决动态路径的拼接问题,我们可以采用绝对路径的写法来规避。但是绝对路径依旧存在相当的问题:它的可移植性和可维护性非常差,一段代码移植到其他电脑上可能就无法运行了。因此,绝对路径依旧不是解决这个问题的最好方法。 144 | 145 | 为了解决路径依赖的问题,Node.js 中引入了一个关键字`__dirname`。 146 | 它是一个字符串变量,表示当前模块所在的目录名。像上述代码,如果我们将其改为: 147 | 148 | ```js 149 | const fs = require('fs'); 150 | fs.writeFile(`${__dirname}/HelloNode.txt`, 'Hello Node.js!', function (err) { 151 | if (err) { 152 | console.log('文件写入失败: ' + err.message); 153 | } else { 154 | console.log('文件写入成功'); 155 | } 156 | }); 157 | ``` 158 | 159 | 这样便能保障无论在什么地方执行这段脚本,都能在该脚本所在目录下写入文件。 160 | -------------------------------------------------------------------------------- /packages/kira-hexo-demo/source/_posts/Node.js/【Node.js学习】简单认识http模块.md: -------------------------------------------------------------------------------- 1 | --- 2 | title: 【Node.js学习】简单认识http模块 3 | date: 2022-04-03 15:02:50 4 | tags: [Node.js] 5 | categories: [编程] 6 | --- 7 | 8 | 这里我们回顾一下我们学习 Node.js 的目的:是为了将 Node.js 作为后端开发的工具才去学习它的,那么要使它能够代替传统的后端开发语言,Node.js 必须要具备基本的 HTTP 通信的功能。要实现 HTTP 通信,就要用到我们今天介绍的这个模块—— **http 模块**了。 9 | 10 | 11 | 12 | 13 | 14 | # http 模块简介 15 | 16 | 在介绍 http 模块之前,我们先来回顾一下**客户端**和**服务器端**的概念。 17 | 18 | - **客户端**:在网络节点中,负责消费资源的计算机,叫做客户端。 19 | - **服务器端**:**负责对外提供网络资源**的计算机,叫做服务器。 20 | 21 | **http 模块**是 Node.js 官方提供的、用来**创建 web 服务器**的模块。通过 http 模块提供的 `http.createServer()` 方法,就能方便地把一台普通的计算机,变为一台 Web 服务器,从而对外提供 Web 资源服务。 22 | 23 | 如果要使用 http 模块创建 Web 服务器,首先需要导入它: 24 | 25 | ```js 26 | const http = require('http'); 27 | ``` 28 | 29 | # 进一步理解 http 模块的作用 30 | 31 | 服务器与普通计算机的**区别**在于,服务器上安装了 **web 服务器软件**,如:IIS、Apache 等。通过安装这些服务器软件,就能把一台普通的电脑变成一台 web 服务器。 32 | 33 | 而有了 Node.js,我们便不再需要 IIS、Apache 这些第三方 web 服务器软件。因为我们可以基于 Node.js 提供的 http 模块自行搭建一个 Web 服务器,对外提供 Web 服务。 34 | 35 | # 创建基本的 web 服务器 36 | 37 | ## 创建 web 服务器的基本步骤 38 | 39 | 1. 导入 http 模块 40 | 2. 创建 web 服务器实例 41 | 3. 为服务器实例绑定 **request** 事件,监听客户端的请求 42 | 4. 启动服务器 43 | 44 | ### 步骤一 - 导入 http 模块 45 | 46 | 如果希望在计算机上创建一个 web 服务器,从而对外提供 web 服务,首先需要导入 http 模块。 47 | 48 | ```js 49 | const http = require('http'); 50 | ``` 51 | 52 | ### 步骤二 - 创建 web 服务器实例 53 | 54 | 调用 `http.createServer()` 方法,即可快速创建一个 web 服务器实例。 55 | 56 | ```js 57 | const server = http.createServer(); 58 | ``` 59 | 60 | ### 步骤三 - 为服务器实例绑定 request 事件 61 | 62 | 为服务器实例绑定 request 事件,即可监听客户端发来的网络请求。 63 | 64 | ```js 65 | server.on('request', (req, resp) => { 66 | console.log('接到客户端发送请求'); 67 | console.log(req); 68 | }); 69 | ``` 70 | 71 | 我们通过 `server.on()` 绑定监听事件,监听 `request` 事件,并给第二个参数传入一个回调函数。该回调函数接收请求对象和响应对象作为形参,用于在监听到 `request` 请求后执行回调。 72 | 73 | ### 步骤四 - 启动服务器 74 | 75 | 调用服务器实例的 `listen()` 方法,即可启动当前的 web 服务器实例。 76 | 77 | ```js 78 | server.listen(80, () => { 79 | console.log('服务器开始监听 80 端口'); 80 | }); 81 | ``` 82 | 83 | ### 完整代码 84 | 85 | 创建一个基本的 web 服务器的完整代码如下: 86 | 87 | ```js 88 | // 步骤一 - 导入 http 模块 89 | const http = require('http'); 90 | 91 | // 步骤二 - 创建 web 服务器实例 92 | const server = http.createServer(); 93 | 94 | // 步骤三 - 为服务器实例绑定 request 事件 95 | server.on('request', (req, resp) => { 96 | console.log('接到客户端发送请求'); 97 | console.log(req); 98 | }); 99 | 100 | // 步骤四 - 启动服务器 101 | server.listen(80, () => { 102 | console.log('服务器开始监听 80 端口'); 103 | }); 104 | ``` 105 | 106 | ## req 对象 107 | 108 | 我们可以通过 request 请求对象提取出客户端发送的请求中的信息,示例代码: 109 | 110 | ```js 111 | const http = require('http'); 112 | const server = http.createServer(); 113 | server.on('request', (req, resp) => { 114 | const url = req.url; 115 | const method = req.method; 116 | console.log(`请求的url是${url},请求的方法是${method}`); 117 | }); 118 | ``` 119 | 120 | ## resp 对象 121 | 122 | 在服务器的 request 事件处理函数中,如果想访问与服务器相关的属性或数据可以使用 response 响应对象。 123 | 124 | ```js 125 | server.on('request', (req, resp) => { 126 | // resp.writeHead()方法介绍: 127 | // 向响应头写入内容 128 | /** 129 | * @param {Number} statusCode 三位数字,表示3位的HTTP状态码 130 | * @param {String} statusMessage 可选参数,可以输入一段人类可读的状态信息 131 | * @param {Object|Array} headers 可选参数,表示响应标头 132 | */ 133 | resp.writeHead(200, { 134 | 'content-type': 'text/html; charset=utf8', // 这里给响应设置UTF8字符集,防止中文乱码 135 | }); 136 | const res = `请求的url是${req.url},请求的方法是${req.method}`; 137 | // 这里介绍 resp.end()方法 138 | // 向客户端发送指定内容,并终止本次请求的处理过程 139 | resp.end(res); 140 | }); 141 | ``` 142 | 143 | # 根据不同的 URL 响应不同的内容 144 | 145 | 通过上面的步骤,我们已经实现了基本的 web 服务器搭建。但是这样一个简单的服务器还存在一个问题,那就是它只能监听发送到某个端口的所有请求,而不能区分发向不同地址的请求。接下来,我们将实现根据不同的 URL 返回不同的响应。 146 | 147 | 示例代码: 148 | 149 | ```js 150 | const http = require('http'); 151 | const server = http.createServer(); 152 | 153 | server.on('request', (req, resp) => { 154 | // 这里给响应设置UTF8字符集,防止中文乱码 155 | resp.setHeader('content-type', 'text/html; charset=utf8'); 156 | switch (req.url) { 157 | case '/': 158 | resp.write(`

欢迎来到首页

`); 159 | resp.end(); 160 | break; 161 | case '/about': 162 | resp.write(`

这里是简介

`); 163 | resp.end(); 164 | break; 165 | default: 166 | // 默认返回 404 167 | resp.writeHead(404); 168 | resp.end(`

404 NOT FOUND

`); 169 | break; 170 | } 171 | }); 172 | 173 | server.listen(80, () => { 174 | console.log('服务器开始运行'); 175 | }); 176 | ``` 177 | -------------------------------------------------------------------------------- /packages/kira-hexo-demo/source/_posts/React/React的事件处理.md: -------------------------------------------------------------------------------- 1 | --- 2 | title: React的事件处理 3 | date: 2022-01-02 12:54:07 4 | tags: [React, JavaScript] 5 | categories: [编程] 6 | cover: https://tse1-mm.cn.bing.net/th/id/R-C.bc71c1c1c50551a1d65e7b529ea29d08?rik=EU42gCFH4J%2bBZA&riu=http%3a%2f%2fwww.goodworklabs.com%2fwp-content%2fuploads%2f2016%2f10%2freactjs.png&ehk=qvQ5EVoUnJZ7k5L347zsU3f87YTckr1iQBzKdwXJd0w%3d&risl=&pid=ImgRaw&r=0 7 | --- 8 | 9 | 在这篇文章中,我们将会了解在 React 中如何进行事件处理。 10 | 11 | 12 | 13 | 14 | 15 | # React 中的事件处理 16 | 17 | > React 元素的事件处理和 DOM 元素的很相似,但是有一点语法上的不同: 18 | > 19 | > - React 事件命名采用驼峰写法(camelCase),而不是全部小写; 20 | > - 使用 JSX 语法时需要传入一个函数作为事件处理函数,而非字符串。 21 | 22 | 举个例子,在传统的 HTML 中,我们通常是这样给标签添加事件处理函数的: 23 | 24 | ```html 25 | 26 | ``` 27 | 28 | 而在 React 中,我们的写法则是这样的: 29 | 30 | ```js 31 | // 因为 hexo 自带的 markdown 解析器无法解析 JSX 语法 32 | // 所以这一段代码写的比较长 33 | // 重点关注其中的 ; 36 | } 37 | ``` 38 | 39 | 在 React 中另一个不同点是我们不能通过 `return false` 的方法来阻止默认行为,我们必须显式调用 `preventDefault()` 。 40 | 举个例子,在传统的 HTML 中,我们想要阻止链接默认打开一个新页面,可以采用这种写法: 41 | 42 | ```html 43 | 点击链接 44 | ``` 45 | 46 | 但在 React 中,则要通过这样的写法来阻止默认行为: 47 | 48 | ```js 49 | function Link(props) { 50 | const clickLink = (e) => { 51 | e.preventDefault(); 52 | console.log('onClick'); 53 | }; 54 | return ( 55 | 56 | 点击链接 57 | 58 | ); 59 | } 60 | ``` 61 | 62 | 在使用 React 时,开发者无需通过 `addEventListener` 为已创建的 DOM 元素添加监听器,只需要在该元素首次渲染时添加监听即可。 63 | 64 | # 事件处理示例 65 | 66 | 下面,我们通过 ES6 的 class 定义一个有状态组件,并给它添加一个点击事件调整自身状态。 67 | 68 | ```js 69 | class Switcher extends React.Component { 70 | constructor(props) { 71 | super(props); 72 | this.state = { 73 | enabled: true, 74 | }; 75 | // 由于 handleClick 中使用了 `this` ,因此必须先为它绑定好 `this` 76 | this.handleClick = this.handleClick.bind(this); 77 | } 78 | 79 | handleClick() { 80 | this.setState((state) => ({ 81 | enabled: !state.enabled, 82 | })); 83 | } 84 | 85 | render() { 86 | return ( 87 | <> 88 |
89 | 90 |
91 |
92 | 当前状态:{this.state.enabled ? '开' : '关'} 93 |
94 | 95 | ); 96 | } 97 | } 98 | ``` 99 | 100 | {% pen https://codepen.io/ch1ny/pen/OJzzYrx?editors=0010 %} 101 | 102 | ## 谨慎对待 this 103 | 104 | **注意**:开发者需要谨慎对待 JSX 回调函数中的 `this` ,在 JavaScript 中,class 的方法默认是不会绑定 `this` 的。如果你忘记绑定 `this.handleClick` 并把它传入了 `onClick`,当你调用这个函数的时候 `this` 的值为 `undefined`。 105 | 如果你觉得绑定 `bind` 很麻烦,那么还有另外两种解决办法可以使用。 106 | 107 | 如果你的项目中,有使用 `public class fields` 语法,那么可以使用 `class fields` 绑定回调函数: 108 | 109 | ```js 110 | class Switcher extends React.Component { 111 | constructor(props) { 112 | super(props); 113 | this.state = { 114 | enabled: true, 115 | }; 116 | } 117 | 118 | // 注意:这是 实验性 语法 119 | handleClick = () => { 120 | this.setState((state) => ({ 121 | enabled: !state.enabled, 122 | })); 123 | }; 124 | 125 | render() { 126 | return ( 127 | <> 128 |
129 | 130 |
131 |
132 | 当前状态:{this.state.enabled ? '开' : '关'} 133 |
134 | 135 | ); 136 | } 137 | } 138 | ``` 139 | 140 | 如果您的项目是通过 `create-react-app` 脚手架创建的,那么默认启动此语法。 141 | 如果您的项目没有使用此语法,那么你可以在回调中填入一个**箭头函数**: 142 | 143 | ```js 144 | class Switcher extends React.Component { 145 | constructor(props) { 146 | super(props); 147 | this.state = { 148 | enabled: true, 149 | }; 150 | } 151 | 152 | handleClick() { 153 | this.setState((state) => ({ 154 | enabled: !state.enabled, 155 | })); 156 | } 157 | 158 | render() { 159 | return ( 160 | <> 161 |
162 | 168 |
169 |
170 | 当前状态:{this.state.enabled ? '开' : '关'} 171 |
172 | 173 | ); 174 | } 175 | } 176 | ``` 177 | 178 | 但是这样的写法也存在问题,每渲染一次该组件都会创建一个不同的回调函数对象。在大多数情况下,这没什么问题,但如果该回调函数作为 prop 传入子组件时,这些组件可能会进行额外的重新渲染。React 官方建议在构造器中绑定或使用 class fields 语法来避免这类性能问题。 179 | -------------------------------------------------------------------------------- /packages/kira-hexo-demo/source/_posts/React/关于React18中ReactDOM.render报错的解决方法.md: -------------------------------------------------------------------------------- 1 | --- 2 | title: 关于React18中ReactDOM.render报错的解决方法 3 | date: 2022-04-08 19:00:52 4 | tags: [React] 5 | categories: [编程] 6 | cover: https://tse1-mm.cn.bing.net/th/id/R-C.bc71c1c1c50551a1d65e7b529ea29d08?rik=EU42gCFH4J%2bBZA&riu=http%3a%2f%2fwww.goodworklabs.com%2fwp-content%2fuploads%2f2016%2f10%2freactjs.png&ehk=qvQ5EVoUnJZ7k5L347zsU3f87YTckr1iQBzKdwXJd0w%3d&risl=&pid=ImgRaw&r=0 7 | --- 8 | 9 | 近日 React.js 由 React17 升级到了 React18,很多升级了项目依赖的开发者可能会遇到刚进入项目控制台就打印了这样一段错误的情况: 10 | 11 | > Warning: ReactDOM.render is no longer supported in React 18. Use createRoot instead. Until you switch to the new API, your app will behave as if it's running React 17. 12 | 13 | 我将在这篇文章中指出解决这个问题的办法。 14 | 15 | 16 | 17 | 18 | 19 | 在 React18 之前,我们渲染元素都是通过函数 `ReactDOM.render()` 来实现将 React 元素渲染到 DOM 上的。就像下面这样: 20 | 21 | ```jsx 22 | import React from 'react'; 23 | import ReactDOM from 'react-dom'; 24 | import App from './App'; 25 | 26 | ReactDOM.render(, document.getElementById('root')); 27 | ``` 28 | 29 | 但是到了 React18,已不再支持通过这样的方式渲染 React 元素了。但是 React 还是会为开发者保留余地,在开发者没有将项目源码改为最新的 API 时,项目依旧会以 React17 的表现运行。 30 | 所以即使不做改动也不会有任何问题,但是对于强迫症选手来说,控制台里一直有个错还是看着很不舒服。所以这里我就讲讲新的 API 究竟应该怎么使用。 31 | 32 | # 太长不看版 33 | 34 | 其实解决方法很简单,更换新的 API 即可。新的 API 是 `createRoot` ,我们通过下面的方式修改我们的代码: 35 | 36 | ```jsx 37 | import React from 'react'; 38 | // import ReactDOM from 'react-dom'; 原来的代码 39 | import { createRoot } from 'react-dom/client'; // 新的 API 引入方式 40 | import App from './App'; 41 | 42 | // 43 | const root = createRoot(document.getElementById('root')); 44 | root.render(); 45 | // 46 | 47 | // 原来的代码 48 | // ReactDOM.render(, document.getElementById('root')); 49 | ``` 50 | -------------------------------------------------------------------------------- /packages/kira-hexo-demo/source/_posts/Revue/Eutopia.md: -------------------------------------------------------------------------------- 1 | --- 2 | title: Eutopia 3 | date: 2022-04-07 13:38:28 4 | tags: [Revue] 5 | categories: [Revue] 6 | cover: https://kira.host/assets/Pictures/Others/Eutopia_AS.jpg 7 | coverWidth: 400 8 | coverHeight: 400 9 | --- 10 | 11 | 12 | 13 | {% krplayer %} 14 | {% aplayerlrc "Eutopia" "钟岚珠(法元明菜)" "https://kira.host/assets/Audios/565807693_nb2-1-112.mp3" "https://kira.host/assets/Pictures/Others/Eutopia_AS.jpg" %} 15 | [00:00.50] 鐘嵐珠(法元明菜) - Eutopia 16 | [00:01.00]作词:Ayaka Miyake 17 | [00:01.50]作曲、编曲:\*Luna、角野寿和 18 | [00:03.10]『大家注意!』 19 | [00:04.60]『就这么回去的话可就亏啦!』 20 | [00:08.20]『这可是学园偶像 钟岚珠的出道舞台哦』 21 | [00:12.70]『来把这传说的开幕 铭记在心吧!』 22 | [00:20.00]『露一手给你们看看』 23 | 24 | [00:24.50] Hey, it's me 准备好没? 25 | [00:29.55] もっと熱く高く 光よりも速く (飞得更炽热更高远 比光还要更快) 26 | [00:33.25] Your heart 連れてくよ Higher (带上你的心 让它飞得更高) 27 | [00:53.35] 圧倒的に Stunning  感じるはず Cuz why not? (压倒性的惊艳 感觉到了吧 Cuz why not?) 28 | [00:57.10] ドキドキをあげる Come on, it's show time. (把这份悸动送给你 Come on, it's show time.) 29 | [01:00.55] それっぽいだけじゃね 物足りないでしょう  So (光是这点程度的话 还远远不够呢 所以) 30 | [01:05.00] 欢迎来到我的天地 31 | [01:07.10] Anyone can keep up with me? Anyone? 32 | [01:11.50] 孤城 から見渡す景色 (从孤城遥望的景色) 33 | [01:15.00] 知ってるの 私だけで (只有我一人知晓) 34 | [01:19.00] 我就是那么完美 Ah~~~ 35 | 36 | [01:23.55] もっと Addicted に  Intoxicated に (更加着迷于我 更加陶醉于我) 37 | [01:27.50] 全部射抜いてあげる  oh I'm too good (让我全部击穿吧 oh I'm too good) 38 | [01:31.20] 怖いものなんてない お遊びはお終い (没什么好害怕的 游戏时间结束了) 39 | [01:35.05] ここから全てが始まってくよ (一切都从现在开始) 40 | 41 | [01:40.10] Top of the top! 42 | [01:42.20] Top of the world! 43 | [01:44.15] Top of the top! 44 | [01:45.90] 这地球就是绕着我转 45 | 46 | [01:48.00] Top of the top! 47 | [01:49.50] Top of the world! 48 | [01:51.70] Top of the top! 49 | [01:54.95]『怎样 不错吧? Huh?』 50 | {% endaplayerlrc %} 51 | {% endkrplayer %} 52 | 53 | 54 |
55 | 56 | Hey, it's me. 57 | 58 | **准备好没?** 59 | 60 | もっと熱く高く 光よりも速く 61 | Motto atsuku takaku hikari yori mo hayaku 62 | 63 | Your heart 連れてくよ Higher 64 | Your herutsu tsurete ku yo haiyā 65 | 66 | 圧倒的に Stunning  感じるはず Cuz why not? 67 | Attōteki ni Stunning kanjiru hazu Cuz why not? 68 | 69 | ドキドキをあげる 70 | Dokidoki o ageru 71 | 72 | Come on, it's show time 73 | 74 | それっぽいだけじゃね 物足りないでしょう So 75 | Sore ppoi dake ja ne monotarinaideshou So 76 | 77 | **欢迎来到我的天地** 78 | 79 | Anyone can keep up with me? Anyone? 80 | 81 | **孤城** から見渡す景色 82 | **孤城** kara miwatasu keshiki 83 | 84 | 知ってるの 私だけで 85 | Shitteru no watashi dake de 86 | 87 | **我就是那么完美** Ah~~~ 88 | 89 | もっと Addicted に  Intoxicated に 90 | Motto Addicted ni Intoxicated ni 91 | 92 | 全部射抜いてあげる  oh I'm too good 93 | Zenbu inuite ageru oh I' m too good 94 | 95 | 怖いものなんてない お遊びはお終い 96 | Kowai mono nante nai o asobi wa o shimai 97 | 98 | ここから全てが始まってくよ 99 | Koko kara subete ga hajimatte ku yo 100 | 101 | Top of the top、 102 | 103 | Top of the world、 104 | 105 | Top of the top、 106 | 107 | 这地球就是绕着我转、 108 | 109 | (I am the best) 110 | Top of the top、 111 | 112 | Top of the world、 113 | 114 | Top of the top、 115 | 116 | (Cuz I am the) best of the best、 117 | 118 | 怎样 不错吧? Huh? 119 | 120 |
121 | 122 | {% biliplayer 767884748 1 1 %} 123 | -------------------------------------------------------------------------------- /packages/kira-hexo-demo/source/_posts/Revue/Fly-Me-To-The-Star.md: -------------------------------------------------------------------------------- 1 | --- 2 | title: Fly Me To The Star 3 | date: 2022-04-02 15:00:20 4 | tags: [Revue] 5 | categories: [Revue] 6 | cover: https://p2.music.126.net/YpbmjrfGLRTAqAf6O-KtMQ==/109951163435314394.jpg 7 | --- 8 | 9 | {% krplayer %} 10 | {% aplayerlrc "Fly Me To The Star" "小山百代/三森すずこ" "https://kira.host/assets/Audios/FlyMetotheStar.mp3" "https://p2.music.126.net/YpbmjrfGLRTAqAf6O-KtMQ==/109951163435314394.jpg" %} 11 | [00:00.000]作词 : 中村彼方 12 | [00:01.000]作曲 : 寻木ヒロ 13 | [00:02.000]编曲 : 寻木ヒロ、小高光太郎 14 | [00:03.000]Strings 编曲 : 加藤達也 15 | [00:04.000]演唱者:愛城華恋【恋】(CV:小山百代),神楽ひかり【光】(CV:三森すずこ) 16 | [00:08.140]【恋】私 ずっとあなたを見てた (我一直都在注视着你) 17 | [00:16.740]【恋】孤独を置いてきたみたい (宛若将孤独置之身外而来) 18 | [00:23.960]【恋】今宵 月も笑いかける (今夜皎月也在向我微笑) 19 | [00:31.620]【恋】こっちを向いて (请看着这边) 20 | [00:34.560]【恋】oh, fly me to the star (、) 21 | [00:54.630]【光】気持ち 伝えることできなくて (无法将心绪传达) 22 | [01:02.820]【光】いろんな人生を浮かべ (浮现出诸多人生) 23 | [01:10.400]【光】演じてみるの あなたの気を惹きたいから (我试图去演绎 正因为渴求着你的思慕) 24 | [01:21.030]【光】oh, fly me to the star 25 | [01:41.780]【合】二人の鼓動 重ね合わせて (重叠了两个人的心悸) 26 | [01:56.560]【恋】たまに不安になる だって (片刻仍会不安 因为) 27 | [02:05.090]【恋】あなたがいなくなりそうで (你好似随时都将离去) 28 | [02:12.270]【恋】輝く目に 私以外映さないで (那绚丽的瞳眸请不要倒映除我之外的一切) 29 | [02:22.980]【恋】oh, fly me to the star 30 | [02:27.450]【光】明ける夜を 告げた鳥よ (宣告夜色已明的鸟儿啊) 31 | [02:36.050]【光】時計の針を今 止めて (表钟的时针在此刻停转) 32 | [02:43.250]【光】流れ星が そっと朝を滑っていく 零れ落ちて (流星悄然在朝霞中滑落) 33 | [02:53.940]【光】oh, fly me to the star 34 | [02:59.360]【合】連れてって (请带上我) 35 | [03:01.730]【合】oh, fly me to the star 36 | {% endaplayerlrc %} 37 | {% endkrplayer %} 38 | 39 | 40 |

Fly Me To The Star

41 | 42 |
43 |
44 | 45 | 我一直都在注视着你 46 | 私 ずっとあなたを見てた 47 | Watashi zutto anata o mi teta 48 | 49 | 宛若将孤独置之身外而来 50 | 孤独を置いてきたみたい 51 | Kodoku o oite kita mitai 52 | 53 | 今夜皎月也在向我微笑 54 | 今宵 月も笑いかける 55 | Koyoi tsuki mo waraikakeru 56 | 57 | 请看着这边 58 | こっちを向いて 59 | Kotchiwomuite 60 | 61 | oh, fly me to the star 62 | oh, fly me to the star 63 | oh, fly me to the star 64 | 65 |
66 | 67 |
68 | 69 | 无法将心绪传达 70 | 気持ち 伝えることできなくて 71 | Kimochi tsutaeru koto dekinakute 72 | 73 | 浮现出诸多人生 74 | いろんな人生を浮かべ 75 | Iron'na jinsei o ukabe 76 | 77 | 因为被演绎时的你的气息所吸引 78 | 演じてみるの あなたの気を引きたいから 79 | Enjite miru no anata no ki o hikitaikara 80 | 81 | oh, fly me to the star 82 | oh, fly me to the star 83 | oh, fly me to the star 84 | 85 |
86 | 87 |
88 | 重叠了两个人的心跳 89 |
90 |
91 | 二人の鼓動 重ね合わせて 92 |
93 |
94 | Futari no kodō kasaneawa sete 95 |
96 | 97 |
98 | 99 | 片刻仍会不安 因为 100 | たまに不安になる だって 101 | Tamani fuan ni naru datte 102 | 103 | 你好似随时都将离去 104 | あなたがいなくなりそうで 105 | Anata ga inaku nari-sōde 106 | 107 | 那绚丽的瞳眸请不要倒映除我之外的一切 108 | 輝く目に 私以外映さないで 109 | Kagayaku me ni watashi igai utsusanaide 110 | 111 | oh, fly me to the star 112 | oh, fly me to the star 113 | oh, fly me to the star 114 | 115 |
116 | 117 |
118 | 119 | 宣告夜色已明的鸟儿啊 120 | 明ける夜を 告げた鳥よ 121 | Akeru yoru o tsugeta toriyo 122 | 123 | 表钟的时针在此刻停转 124 | 時計の針を今 止めて 125 | Tokei no hari o ima tomete 126 | 127 | 流星悄然在朝霞中滑落 128 | 流れ星が そっと朝を滑っていく 零れ落ちて 129 | Nagareboshi ga sotto asa o subette iku koboreochite 130 | 131 | oh, fly me to the star 132 | oh, fly me to the star 133 | oh, fly me to the star 134 | 135 |
136 | 137 |
138 |
139 | 请带上我 140 |
141 |
142 | 連れてって 143 |
144 |
145 | Tsuretette 146 |
147 |
148 |
149 |
150 |
151 | oh, fly me to the star 152 |
153 |
154 | oh, fly me to the star 155 |
156 |
157 | oh, fly me to the star 158 |
159 |
160 |
161 | 162 |
163 | 164 | {% biliplayer 33053034 2 1 %} 165 | -------------------------------------------------------------------------------- /packages/kira-hexo-demo/source/_posts/Revue/花咲か唄.md: -------------------------------------------------------------------------------- 1 | --- 2 | title: 花咲か唄 3 | date: 2021-09-23 16:15:31 4 | tags: [Revue] 5 | categories: [Revue] 6 | cover: https://p2.music.126.net/KYJwgniEBAIuC5IkqbRfhw==/109951163940856502.jpg 7 | --- 8 | 9 | {% krplayer %} 10 | {% aplayerlrc "花咲か唄" "生田辉 / 伊藤彩沙" "https://kira.host/assets/Audios/60143682-1-112.mp3" "https://p2.music.126.net/KYJwgniEBAIuC5IkqbRfhw==/109951163940856502.jpg" %} 11 | [00:00.000]作词 : 中村彼方 12 | [00:01.000]作曲 : 大川茂伸 13 | [01:18.379]いつまでもそばにいると/约定永远在一起 14 | [01:21.873]幼い小指を絡めた/幼小的手指交叉相扣 15 | [01:25.626]あの時から どれくらいの月日過ぎたのでしょう/从那一天 已经过了多少岁月 16 | [01:33.125]ふいに 見上げた 花びら とても眩しかった/抬头以外看到的花瓣 是多么的耀眼 17 | [01:40.625]腕を伸ばしても 届かないような気がした/感觉即使伸出手 再也够不到 18 | [01:48.625]別々の道を行く気ならば/你想走另一条路 19 | [01:52.872]あたしは止めたりしない/我不会阻止 20 | [01:55.879]幸せがもしここにないならば/若你的幸福不在这 21 | [02:00.130]他所の場所で咲くがいいさ/到别处开花也无妨 22 | [02:03.380]咲き誇る その瞬間だけ 一番に 見たくて/只为你盛开的那一刻 我想最先看到 23 | [02:42.876]守り抜いてくれること 疑わず信じてたけど/守护到最后 我不曾怀疑 24 | [02:49.877]籠の鳥は 青い空に ずっと憧れていた/笼中之鸟 一直憧憬着蓝天 25 | [02:57.378]いつの間にやら雛鳥 凛々しく鳴いている/不知不觉 雏鸟已能发出凛凛的叫声 26 | [03:04.623]花も 翼も ゆらり揺れ風に乗る/花还是翅膀 都随风飘扬 27 | [03:13.134]さようなら うちは旅発ちます/再见 28 | [03:17.128]今すぐにあんたから/我这就马上离开你 29 | [03:20.376]思い出を忘れられぬように/为了回忆永存 30 | [03:24.382]こころ抉つて行きます/揪着心亦离去 31 | [03:53.372]瀬を早み 岩にせかるる川/急流岩上碎 无奈两离分 32 | [03:57.377]割れても末に逄はむ/早晚终相会 忧思情愈深 33 | [04:00.630]別々に分かれた花道も/分别的花道 34 | [04:04.625]やがては一本道に/也终将汇成一条 35 | [04:07.873]花咲かせ たった一人のため 限りある命を/花绽放 仅仅为了唯一的她 献上我此生 36 | {% endaplayerlrc %} 37 | {% endkrplayer %} 38 | 39 | 40 |

花咲か唄

41 | 42 |
43 | 44 | 约定永远在一起 幼小的手指交叉相扣 45 | いつまでもそばにいると 幼い小指を絡めた 46 | itsu made mo soba ni iru to osanai koyubi o karameta 47 | 48 | 从那一天 已经过了多少岁月 49 | あの時から どれくらいの月日過ぎたのでしょう 50 | ano toki kara dorekurai no tsukihi sugita nodeshou 51 | 52 | 抬头意外看到的花瓣 是多么耀眼 53 | ふいに見上げた花びら とても眩しかった 54 | fui ni miageta hanabira totemo mabushikatta 55 | 56 | 感觉即使伸出双手 也无法触及 57 | 腕を伸ばしても 届かないような気がした 58 | ude o nobashitemo todokanai yōna ki ga shita 59 | 60 | 你想走另一条道路 61 | 別々の道を行く 気ならば 62 | betsubetsu no michi o iku kinaraba 63 | 64 | 我不会阻止 65 | わたしは止めたりしない 66 | watashi wa tome tari shinai 67 | 68 | 若你的幸福不在这 69 | 幸せがもしここにないならば 70 | shiawase ga moshi koko ni nainaraba 71 | 72 | 到别处开花也无妨 73 | 他所の場所で咲くがいいさ 74 | yoso no basho de sakuga ī sa 75 | 76 | 只为你盛开的那一瞬间 我想最先看到 77 | 咲き誇るそう瞬間だけ 一番に見たくて 78 | sakihokoru sō shunkan dake ichiban ni mitakute 79 | 80 | 守护到最后 我不曾怀疑 81 | 守り抜いてくれること 疑わず信じてたけど 82 | mamori nuite kureru koto utagawazu shinji tetakedo 83 | 84 | 笼中之鸟 一直憧憬着蓝天 85 | 籠の鳥は 青い空にずっと憧れていた 86 | kago no tori wa aoi sora ni zutto akogarete ita 87 | 88 | 不知不觉 雏鸟已经能发出凛凛的叫声 89 | いつの間にやら雛鳥 凛々しく鳴いている 90 | itsunomaniyara hinadori ririshiku naite iru 91 | 92 | 花还是翅膀 都随风飘扬 93 | 花も翼も ゆらり 揺れ風に乗る 94 | hana mo tsubasa mo yurari yure kaze ni noru 95 | 96 | 再见了 我将出发旅行 97 | さようなら うちは旅発ちます 98 | sayōnara uchi wa tabi tachimasu 99 | 100 | 我这就马上离开你 101 | 今すぐにあんたから 102 | ima sugu ni annta kara 103 | 104 | 为了回忆永存 105 | 思い出を忘れられぬように 106 | omoide o wasure rarenu yō ni 107 | 108 | 揪着心也要离去 109 | こころ抉って行きます 110 | kokoro egutte ikimasu 111 | 112 | 急流岩上碎 无奈两离分 113 | 背を早み 岩にせかるる川 114 | se o haya mi iwa ni sekaruru kawa 115 | 116 | 早晚终相会 忧思情愈深 117 | 割れても 末に逢はむ 118 | warete mo-sue ni au hamu 119 | 120 | 分别的花道 121 | 別々に分かれた花道も 122 | betsubetsu ni wakareta hanamichi mo 123 | 124 | 也终将汇聚成一条 125 | やがては一本道に 126 | yagate wa ipponmichi ni 127 | 128 | 花绽放 仅仅为了唯一的她 献上我此生 129 | 花咲かせ たった一人のため 限りある命を 130 | hana sakase tatta hitonotame kagiri aru inochi o 131 | 132 |
133 | 134 | {% biliplayer 33053034 7 1 %} 135 | -------------------------------------------------------------------------------- /packages/kira-hexo-demo/source/_posts/Revue/誇りと驕り.md: -------------------------------------------------------------------------------- 1 | --- 2 | title: 誇りと驕り 3 | date: 2021-09-25 12:50:48 4 | tags: [Revue] 5 | categories: [Revue] 6 | cover: https://p2.music.126.net/cq6eYBjoH3Y89EyvBoZhCg==/109951164730429128.jpg 7 | --- 8 | 9 | {% krplayer %} 10 | {% aplayerlrc "誇りと驕り" "小山百代 / 富田麻帆" "https://kira.host/assets/Audios/M500004PPGTt3J0AQQ.mp3" "https://p2.music.126.net/cq6eYBjoH3Y89EyvBoZhCg==/109951164730429128.jpg" %} 11 | [00:00.000]誇りと驕り (movie ver.) - 小山百代/富田麻帆 12 | [00:03.650]词:中村彼方 13 | [00:05.150]曲:藤澤慶昌 14 | [00:06.980]编曲:藤澤慶昌 15 | [00:09.310]Orchestral Arrangement:藤澤慶昌 16 | [00:10.650]私にも見えるはず (我应该也可以看到) 17 | [00:16.740]いいえ 見えはしない (不 你见不到) 18 | [00:22.460]塔の頂の景色 (塔顶的景色) 19 | [00:33.330]あなたの心に何があるの? (你心中怀揣的是什么?) 20 | [00:38.370]瞬く瞳がとらえる先 (闪动的眼眸注视的前方) 21 | [00:43.190]いまだ届かぬ星でも (即使那颗星还无法触及) 22 | [00:48.170]約束のためなら (为了约定) 23 | [00:52.110]走り続けるの (我会一直向它奔跑) 24 | [01:20.330]女神の呼び声 空の玉座 (女神的呼声 天空的玉座) 25 | [01:27.180]舞い降りる星は そう一つのみ (飘落的星 是的 只有一颗) 26 | [01:48.600]登ってきなさい 意地があるなら (登上来 若你有坚强的意志) 27 | [01:53.570]切ってみなさい 怒り見せて (跨越我 让我看看你的愤怒) 28 | [01:57.590]心に巣くう大きな獣 (不要被栖居心中的) 29 | [02:02.650]振り回されてないで (巨兽摆布) 30 | [02:06.690]未完成の覚悟なんていらない (这里不需未完成的觉悟) 31 | [02:11.230]見たいのは 誇り懸け戦う (想看到的是拼上骄傲而战的) 32 | [02:15.900]その眼差し (眼神) 33 | [02:22.440]より高く より輝く (飞得更高 更为闪耀) 34 | [02:27.220]地平線 照らして (将地平线照亮) 35 | [02:32.040]一つ進んで 一つ近づく夢 (一步一步 迈向梦想) 36 | [02:37.480]それが誇り (这就是骄傲) 37 | [02:40.820]より高く より輝く (飞得更高 更为闪耀) 38 | [02:45.280]届かない場所へ (到那众人无法触及的地方) 39 | [02:50.240]それが私の誇り (这就是我的骄傲) 40 | {% endaplayerlrc %} 41 | {% endkrplayer %} 42 | 43 | 44 |

誇りと驕り

45 | 46 |
47 | 48 | 我应该也能看见 49 | 私にも見えるはず 50 | wa ta shi ni mo mi e ru ha zu 51 | 52 | 不,你看不见 53 | いいえ、見えはしない 54 | iie mi e wa shi na i 55 | 56 | 处在塔顶的景色 57 | 塔の頂きの景色  58 | to u no i ta da ki no ke shi ki 59 | 60 | 你的内心怀揣着什么 61 | あなたの心に何があるの 62 | a na ta no ko ko ro ni na ni ga a ru no 63 | 64 | 闪烁的瞳眸所凝视的前方 65 | 瞬く瞳がとらえる先 66 | ma da da ku hi to mi ga to ra e ru sa ki 67 | 68 | 即使是仍未触及的那颗星辰 69 | いまだ届かぬ星でも 70 | i ma da to do ka nu ho shi de mo 71 | 72 | 若是为了约定 73 | 約束のためなら 74 | ya ku so ku no ta me na ra 75 | 76 | 我会继续朝其奔去 77 | 走り続けるの 78 | ha shi ri tsu du ke ru no 79 | 80 | 女神的呼唤 苍穹的玉座 81 | 女神の呼び声 空の玉座 82 | me ga mi no yo bi go e so ra no gyo ku za 83 | 84 | 飘舞零落的星曜 正是如此 仅有一颗 85 | 舞い降りる星は そう 一つのみ 86 | ma i o ri ru ho shi wa so u hi to tsu no mi 87 | 88 | 登临此处 若你有坚强的意志 89 | 登ってきなさい 意地があるなら 90 | no bo te   ki na sa i   i ji ga a ru na ra 91 | 92 | 尝试突破 向我展示你的愤怒 93 | 切ってみなさい 怒り見せて 94 | ki te mi na sa i ka ri mi se te 95 | 96 | 切不为盘踞于内心的巨兽所肆意摆布 97 | 心に巣くう大きな獣 振り回されてないで 98 | ko ko ro ni su ku u o ki na ke mo no hu ri ma wa sa re te na i de 99 | 100 | 无需任何半途而废的觉悟 101 | 未完成の覚悟なんていらない 102 | mi kan se i no ga ku go nan te i ra na i 103 | 104 | 所想见到的是 赌上骄傲而战的眼神 105 | 見たいのは 誇り懸け戦う その眼差し 106 | mi ta i no wa ho ko ri ka ke ta ta ka u so no ma na za shi 107 | 108 | 愈加高远 益发璀璨 109 | より高く より輝く 110 | yo ri ta ka ku yo ri ka ga ya ku 111 | 112 | 将地平线照亮 113 | 地平線 照らして 114 | chi he i se nn te ra shi te 115 | 116 | 逐步前行 迈向梦想 117 | 一つ進んで 一つ近づく夢 118 | hi to tsu su su nn de hi to tsu chi ka du ku yu me 119 | 120 | 那就是我的骄傲 121 | それが誇り 122 | so re ga ho ko ri 123 | 124 | 愈加高远 益发璀璨 125 | より高く より輝く 126 | yo ri ta ka ku yo ri ka ga ya ku 127 | 128 | 前往所无法临近的彼岸 129 | 届かない場所へ 130 | to do ka na i ba sho he 131 | 132 | 那就是我的骄傲 133 | それが私の誇り 134 | so re ga wa ta shi no ho ko ri 135 | 136 |
137 | 138 | {% biliplayer 33053034 5 1 %} 139 | -------------------------------------------------------------------------------- /packages/kira-hexo-demo/source/_posts/Rust/Rust与所有权.md: -------------------------------------------------------------------------------- 1 | --- 2 | title: Rust与所有权 3 | date: 2023-02-19 21:08:45 4 | tags: [Rust] 5 | categories: [编程] 6 | cover: https://pic2.zhimg.com/v2-839798432500b3aec901cba0efb93bf7_720w.jpg?source=172ae18b 7 | --- 8 | 9 | 通过这篇文章,我们将来学习 Rust 最独特的特性 —— **所有权**。 10 | 11 | 12 | 13 | 14 | 15 | # 什么是所有权 16 | 17 | **所有权** 是 Rust 最独特的一个特性,它使得 `Rust` 无需 GC 也可以保证内存安全。 18 | 19 | 20 | Rust 的**核心特性**就是所有权。所有计算机程序在运行时都需要管理它们使用计算机内存的方式。 21 | 22 | - 有些语言具有垃圾收集机制,比如 Java、C#,在程序运行时,它们会不断地寻找不再使用的内存。 23 | - 在其他语言中,则需要程序员显式地分配并释放内存,比如 C、C++。 24 | 25 | 而 Rust 采用了一种新的方式:它采用了一种**所有权**系统,内存通过该系统进行管理,其中包含一组编译器在编译时进行检查的规则。由于这套系统只在编译器作用,无需运行时 GC。因此,当程序运行时,所有权系统不会减慢程序的运行速度。 26 | -------------------------------------------------------------------------------- /packages/kira-hexo-demo/source/_posts/Rust/初识Rust.md: -------------------------------------------------------------------------------- 1 | --- 2 | title: 初识Rust 3 | date: 2023-02-18 23:08:26 4 | tags: [Rust] 5 | categories: [编程] 6 | cover: https://pic2.zhimg.com/v2-839798432500b3aec901cba0efb93bf7_720w.jpg?source=172ae18b 7 | --- 8 | 9 | Rust 是目前一门较为热门的系统级编程语言,其具备着无GC、高性能、强工程性以及从语法保证的内存安全性等优势是一门非常值得学习的编程语言。我将通过这篇文章带着各位与 Rust 初次见面并学习如何通过 Rust 写出一个简单的 Hello World 程序。 10 | 11 | 12 | 13 | 14 | 15 | # 为什么要学习 Rust 16 | 17 | Rust 是一种新的编程语言,它可以让每个人编写高效且可靠的软件。它被视作 C/C++ 的替代品,因为 Rust 具有同它们一样的性能,而且很多常见 bug 在编译时即可被解决。 18 | 19 | Rust 是一种通用的编程语言,但是它更善于应付以下几种场景: 20 | 21 | - 需要运行时的速度 22 | - 需要内存安全 23 | - Rust 可以更好地利用多处理器 24 | 25 | ## 与其他热门语言比较 26 | 27 | 我们这里可以将 Rust 与其他几门热门的编程语言相比: 28 | 29 | - C/C++:它们的性能非常好,但是类型系统和内存都不太安全。 30 | - Java/C#:它们拥有GC,可以保证内存安全,但是性能相对弱。 31 | 32 | 相比来说,Rust 的优势就非常大: 33 | 34 | - 安全 35 | - 无需GC,提高性能 36 | - 易于维护、调试,代码安全高效 37 | 38 | 而 Rust 唯一的缺点就是 —— **“难学”**。 39 | Rust 有很多独有的概念,它们和大部分主流语言不同,学习阶段需要注意。 40 | 41 | ## Rust 特别擅长的领域 42 | 43 | - 高性能 Web Service 44 | - WebAssembly 45 | - 命令行工具 46 | - 网络编程 47 | - 嵌入式设备 48 | - 系统编程 49 | 50 | # 安装 Rust 51 | 52 | 首先,我们来到 [Rust 的官方网站](https://rust-lang.org/) 。 53 | 54 | Windows 用户可以根据官网的指示完成 Rust 的安装。 55 | 56 | 如果是 Linux 或是 MacOS 的用户可以直接在终端中输入 `curl https://sh.rustup.rs -sSf| sh` 安装 `rustup` 。 57 | 58 | 如果是 Windows Linux 子系统的用户可以执行 `curl --proto '=https' --tlsv1.2 -sSf https://sh.rustup.rs | sh` 完成安装。 59 | 60 | > Rust 的更新与卸载: 61 | > ```bash 62 | > rustup update # 更新 63 | > rustup self uninstall # 卸载 64 | > ``` 65 | 66 | 安装完毕后,可以在终端执行 `rustc --version` 指令打印安装的 rust 版本号来检查是否安装成功。 67 | 68 | > 博主采用的开发工具是 VS Code,需要安装 Rust 插件以提升 Rust 开发体验。插件名为:`rust-analyzer`。 69 | 70 | # 编写 Hello World 71 | 72 | ## 创建项目 73 | 74 | 当我们安装好 rust 后,来到我们的工作目录下。创建一个 `hello_world` 文件夹作为我们的 Hello World 程序的根目录,并创建好 `.rs` 文件。注意 rust 语言规范中文件及文件夹名应当采用**蛇形命名法**,即用**下划线( _ )**分割开来。 75 | 76 | ```bash 77 | mkdir hello_world 78 | cd hello_world 79 | touch hello_world.rs 80 | ``` 81 | 82 | ## 编写代码 83 | 84 | Hello World 程序的代码非常简单,如下所示: 85 | 86 | ```rust 87 | fn main() { 88 | println!("Hello World!"); 89 | } 90 | 91 | ``` 92 | 93 | 在 rust 中,程序的入口函数名为 `main` 函数,定义函数则使用 `fn` 关键字。 94 | 这里打印字符串我们使用了 `println!` 方法。这里需要注意方法名后跟了一个**感叹号**,在 rust 中这种写法被称为 **宏(macro)** 。它提供了类似函数的功能,但是没有运行时开销。我们这里不去过多解读它,未来我们将对**宏**展开进行详细的介绍。 95 | 96 | ## 编译运行 97 | 98 | 下面我们对 Hello World 进行编译并执行。 99 | 首先,在根目录下执行如下指令: 100 | 101 | ```bash 102 | rustc .\hello_world.rs 103 | ``` 104 | 105 | 在 windows 平台下,该指令会将我们的 `hello_world.rs` 文件进行编译,并在根目录下生成可执行文件 `hello_world.exe` 和一个包含调试信息的 `hello_world.pdb` 文件。 106 | 107 | > 如果是 Linux 或 MacOS,则会生成一个叫做 `hello_world` 的无后缀可执行文件。 108 | 109 | 接下来我们在终端中执行指令 `.\hello_world.exe` ,即可在控制台中输出 `Hello World!` 了。 110 | 111 | # 使用 Cargo 112 | 113 | 恭喜你!你现在已经又熟练掌握了一门语言的 Hello World 了!(bushi 114 | 115 | 但是你是否觉得这样的开发步骤较为繁琐。`rustc` 只适合较为简单的 Rust 程序,而对一些较大的项目我们必须使用一些其他的工具,比如 `Cargo`。 116 | 117 | ## 认识 Cargo 118 | 119 | Cargo 是 Rust 的构建系统以及包管理工具,它能够: 120 | - 构建代码 121 | - 下载依赖的库 122 | - 构建这些库 123 | - **...** 124 | 125 | 在安装 Rust 的时候会自动安装 Cargo 。要验证 Cargo 是否安装,可以执行 `cargo --version` 查看是否打印了 cargo 的版本号。 126 | 127 | ## 使用 Cargo 创建项目 128 | 129 | 下面,我们通过 Cargo 开发一个 **Hello Cargo** 应用。 130 | 131 | 首先执行下面的指令来创建名为 `hello_cargo` 的项目: 132 | 133 | ```bash 134 | cargo new hello_cargo 135 | ``` 136 | 137 | 上述指令将生成如下的项目目录结构: 138 | 139 | ``` 140 | hello_cargo 141 | └───src 142 | └───main.rs 143 | └───.gitignore 144 | └───Cargo.toml 145 | ``` 146 | 147 | 其中 `src` 存放着我们的源代码,默认生成的 `main.rs` 中的代码如下: 148 | 149 | ```rust 150 | fn main () { 151 | println!("Hello, world!"); 152 | } 153 | 154 | ``` 155 | 156 | ## Cargo.toml 157 | 158 | TOML(Tom's Obvious, Minimal Language) 是 Cargo 的配置格式。 159 | `[package]` 是一个区域标题,表示下方的配置是用来配置包(package)的: 160 | - name: 项目名 161 | - version: 项目版本 162 | - authors: 项目作者 163 | - edition: 使用的 Rust 版本 164 | 165 | ```toml 166 | [package] 167 | name = "hello_cargo" 168 | version = "0.1.0" 169 | authors = ["HanshinKira <1056317718@qq.com>"] 170 | edition = "2021" 171 | ``` 172 | 173 | `[dependencies]` 是另一个区域的开始,它会列出项目的依赖项。在 Rust 中,代码的**包**(或者说**库**)被称为 **crate** 。 174 | 175 | ## 修改代码并编译执行 176 | 177 | 下面我们对 `src/main.rs` 内的代码做一点调整: 178 | 179 | ```rust 180 | fn main () { 181 | println!("Hello, cargo!"); 182 | } 183 | 184 | ``` 185 | 186 | 下面我们执行 `cargo build` 创建一个可执行文件。可执行文件将会位于 `hello_cargo/target/debug/hello_cargo.exe` 。 187 | 188 | 首次运行 `cargo build` 会在顶层目录生成一个 `cargo.lock` 文件。 189 | - 该文件负责精确追踪项目依赖的具体版本 190 | - 不要手动修改该文件 191 | 192 | 运行项目则只需要执行 `cargo run` 命令,该命令会执行**构建和运行**的操作。如果之前成功编译过,且源码未发生改变,则会直接运行之前的二进制文件。 193 | 194 | ## 开发时检查 195 | 196 | 假设我们开发了一个非常复杂的 Rust 应用,我们想要查看我们开发的源码中是否存在潜在的错误,我们可能会通过执行 `cargo build` 来查看能否通过编译。但是 `cargo build` 的时间可能会非常漫长。 197 | 198 | 这个时候我们就可以执行 `cargo check` 来检查我们的代码,确认是否能通过编译,但同时不会生成可执行文件。因此它要比 `cargo build` 快得多。 199 | 200 | 在我们编写代码时可以反复使用 `cargo check` 来检查代码,提高效率。 201 | 202 | ## 构建 release 版本 203 | 204 | 上面的编译指令是用于编译 debug 版本的,如果要投入发布使用,则需要在编译时加上 flag ,完整的指令为 `cargo build --release`,也可以简写为 `cargo build -r`。 205 | 206 | 它在编译时会进行优化,代码运行速度更快,但是编译时间也会更长。 207 | 208 | 它生成的可执行文件位于 `target/release/hello_cargo.exe`。 209 | -------------------------------------------------------------------------------- /packages/kira-hexo-demo/source/_posts/Unity使用Newtonsoft报错的解决方案.md: -------------------------------------------------------------------------------- 1 | --- 2 | title: Unity使用Newtonsoft报错的解决方案 3 | date: 2021-11-26 21:12:31 4 | tags: [Unity3D] 5 | categories: [编程] 6 | cover: https://tse1-mm.cn.bing.net/th/id/R-C.1c06375ca9292528fe62ed3c027090b7?rik=V9YxI7dFI9A3WA&riu=http%3a%2f%2fuploadfile.qikuedu.com%2f2019%2f0520%2f20190520104330150.jpg&ehk=cohtMwwyzbmXZI7ZW%2fQBo3NAw%2f5hkB%2fem9%2fnqDfRXDc%3d&risl=&pid=ImgRaw&r=0 7 | --- 8 | 9 | 最近在做人机交互课的实验,主要开发工具选择了 Unity3D 。把做好的项目通过 **git** 上传后,又用 `git clone` 了下来来测试项目上传是否成功。结果发现 clone 回来的项目,出现了一些问题。 10 | 11 | 12 | 13 | 14 | 15 | # Unity 使用 Newtonsoft 报错的解决方案 16 | 17 | ## 问题描述 18 | 19 | 在项目中,我用到了 **Newtonsoft.Json** 这个包来处理我需要的 Json 数据。 20 | 21 | ```csharp 22 | using Newtonsoft.Json; 23 | using Newtonsoft.Json.Linq; 24 | ``` 25 | 26 | 在原项目中并没有出现什么问题(这里是因为之前设置了一些东西,具体我会在**解决方法**部分的**方法一**提到),但是在**克隆**回来的项目中 Unity3D 的控制台直接甩了个错误给我: 27 | `The type or namespace name 'Newtonsoft' could not be found (are you missing a using directive or an assembly reference?)` 28 | ![在这里插入图片描述](https://img-blog.csdnimg.cn/481bd4a571584ed9b0222f2b59bcfd30.png) 29 | 30 | 这是因为 Json.NET 官方没有直接支持 Unity ,导致 Unity 无法找到正确的程序集。 31 | 32 | ## 解决方法 33 | 34 | 下面我将给出两种解决方案,两种方案都是可行的。 35 | 36 | ### 方法一:使用 Unity 的 Package Manager 自动导入 37 | 38 | 在 **Project** 标签页中,右键点击 **Packages**。 39 | ![在这里插入图片描述](https://img-blog.csdnimg.cn/ce4a3c81de7a4997a3141eba363f8f2b.png) 40 | 在打开的菜单栏中点击 **View in Package Manager** 。 41 | ![在这里插入图片描述](https://img-blog.csdnimg.cn/8a7f605ac9034b7986689808b6c8ab36.png) 42 | 在打开的 **Package Manager** 中,点击左上角的**加号**,选择通过名称添加。 43 | ![在这里插入图片描述](https://img-blog.csdnimg.cn/5facb010b9e34904b596fa077bb8487b.png#pic_center) 44 | 包名是 **com.unity.nuget.newtonsoft-json** ,我发这篇博客时,版本号为 **2.0.2**,各位读者也可以填该版本号,导入后 unity 会提示你进行更新。 45 | ![在这里插入图片描述](https://img-blog.csdnimg.cn/02b8e6a2adc243fa8c9ce9fee05ec5cf.png) 46 | ![在这里插入图片描述](https://img-blog.csdnimg.cn/2d0ad8bec8544e28b7873d3a82ee0a0a.png) 47 | 添加成功后 Unity 的报错信息就消失了。 48 | 49 | ### 方法二:访问 GitHub 下载 unitypackage 文件手动导入 50 | 51 | 访问 GitHub 下载相应的支持 Unity 的 Newtonsoft.Json 资源包。[点我跳转](https://github.com/SaladLab/Json.Net.Unity3D/releases) 52 | ![在这里插入图片描述](https://img-blog.csdnimg.cn/3ccd69afc8ed4acbb89df49f40fdfc65.png) 53 | 54 | 选择需要的版本进行下载(由于我使用到了 `Newtonsoft.Json.Linq` ,因此我需要下载的是 `JsonNet.9.0.1.unitypackage` )。 55 | ![在这里插入图片描述](https://img-blog.csdnimg.cn/e603d8a638d6423980fdf418d4dbdccd.png) 56 | 打开报错的 Unity 项目,双击下载好的 **unitypackage** 文件,使用 **Unity Editor** 打开。 57 | ![在这里插入图片描述](https://img-blog.csdnimg.cn/52bdfa6bef544914b123f3a9abfb96ba.png) 58 | 将所有包都勾选好点击“导入”即可。此时 Unity 会重新编译一遍脚本。 59 | ![在这里插入图片描述](https://img-blog.csdnimg.cn/9622959061f64ffd853ced64e275e3e9.png) 60 | 编译成功后你就会发现控制台里已经没有报错的信息了。 61 | ![在这里插入图片描述](https://img-blog.csdnimg.cn/84963310156d4a0ca3b62d82dc0fd176.png) 62 | -------------------------------------------------------------------------------- /packages/kira-hexo-demo/source/_posts/【Fira-Code】一款为程序员量身打造的字体.md: -------------------------------------------------------------------------------- 1 | --- 2 | title: 【Fira Code】一款为程序员量身打造的字体 3 | date: 2022-09-18 12:17:22 4 | tags: [VSCODE] 5 | categories: [编程] 6 | cover: https://kira.host/assets/Pictures/Others/FiraCodeLogo.svg 7 | --- 8 | 9 | 今天给大家介绍一款非常炫酷的等宽字体—— **Fira Code**。 10 | 11 | 12 | 13 | 14 | 15 | # 什么是 Fira Code 16 | 17 | Fira 是由 Mozilla 公司(也就是火狐浏览器的母公司)主推的字体系列,主打的就是具有 **等宽** 的属性。而 Fira Code 则在这一基础上加入了 **编程连字特性**,也就是 `Ligatures`。 18 | Fira Code 利用这一特性,对编程人员常用的一些编程符号做了连字处理,将我们经常用到的诸如 `=>`、`<=`、`!=` 等超过一个字符的操作符渲染为对应的数学符号,使得我们能够更快地阅读理解代码。 19 | 20 | ## 预览 21 | 22 | 我们可以先来看一下在 VSCode 中使用 Fira Code 书写代码的效果。来看下面这一段代码: 23 | ```ts 24 | /** 25 | * 这段 TypeScript 代码本身不具有任何意义 26 | * 只是为了展示 Fira Code 连字渲染的效果 27 | */ 28 | const func = (arr: Array) => { 29 | for (let i = 0; i <= arr.length; i++) { 30 | let item = arr[i]; 31 | if (typeof item === 'number') { 32 | while (item >= 10) { 33 | item /= 10; // 只是为了演示效果,别在意代码效率了... 34 | } 35 | console.log(`${arr[i]} ${item % 1 != 0 ? '不能' : '可以'} 被 10 整除`); 36 | } 37 | } 38 | }; 39 | 40 | const arr = [1, 30, 24, 'afaa', undefined, 50]; 41 | func(arr); 42 | 43 | ``` 44 | 下面是这段代码在 VSCode 中的效果图: 45 | ![TypeScript Fira Code 预览](https://kira.host/assets/Pictures/Others/20220918125944.png) 46 | 47 | # 如何使用 Fira Code 48 | 49 | 本文下面将介绍如何在 VSCode 当中使用 Fira Code。 50 | 51 | ## 下载字体 52 | 53 | 首先,我们进入到 [Fira Code 官方仓库](https://github.com/tonsky/FiraCode) 中,找到 Releases,点击进入[最新的一次发布](https://github.com/tonsky/FiraCode/releases/latest)。 54 | ![FiraCode官方仓库](https://kira.host/assets/Pictures/Others/20220918123410.png) 55 | 56 | ## 安装字体 57 | 58 | 下载最新发布的 **Assets** 中的 **Fira_Code_v\*.\*.zip** ,这个是字体的压缩包。下载下来解压后,我们进入到其中的 `ttf` 文件夹,我们右键选中所有字体然后右键点击**安装**。 59 | ![安装字体](https://kira.host/assets/Pictures/Others/20220918124037.png) 60 | 61 | ## 设置字体 62 | 63 | 安装完毕后,我们就可以在 VSCode 中使用该字体了。我们进入到 `settings.json` 当中,在文件中加入这两行设置: 64 | ```json 65 | { 66 | // ... 67 | "editor.fontFamily": "Fira Code", 68 | "editor.fontLigatures": true, 69 | // ... 70 | } 71 | ``` 72 | 这两行设置分别是设置编辑区字体以及是否开启连字符,添加这两行配置后就能够愉快地使用 Fira Code 进行编程了! -------------------------------------------------------------------------------- /packages/kira-hexo-demo/source/_posts/【VSCODE插件推荐】TODO-Highlight.md: -------------------------------------------------------------------------------- 1 | --- 2 | title: 【VSCODE插件推荐】TODO Highlight 3 | date: 2022-04-09 14:22:07 4 | tags: [VSCODE] 5 | categories: [编程] 6 | cover: https://wayou.gallerycdn.vsassets.io/extensions/wayou/vscode-todo-highlight/1.0.5/1635478170130/Microsoft.VisualStudio.Services.Icons.Default 7 | --- 8 | 9 | 当你在使用 VSCode 编写代码时,突然发现了一个小 bug,但是又不想停下手上的活来解决这个 bug,应该怎么办呢?在这篇文章中,我将为你们推荐一款 VSCode 的插件,帮你在代码中添加醒目的 `TODO` 注释。 10 | 11 | 12 | 13 | 14 | 15 | **插件名称**:TODO Highlight 16 | **插件作者**:Wayou Liu 17 | **下载量**:2,451,400+ (统计于 2022 年 4 月 9 日 14:25:37) 18 | 19 | # 基本使用方法 20 | 21 | 在编写代码时,遇到突然发现的小 bug 时,根据代码编写规范,一般来说应该在代码中加一个 TODO 注释,就像下面这样: 22 | 23 | ```js 24 | // TODO: 这个地方需要进行修改,我确信我有一种绝妙的写法,可惜这里地方太小,我的代码放不下 25 | ``` 26 | 27 | 或者 28 | 29 | ```js 30 | // FIXME: 这谁写的阴间代码?你牛び啊! 31 | ``` 32 | 33 | 但是这些 TODO 标记随着时间和项目的增长,会逐渐散布在项目的每一个角落,而且总是用着模糊不清的描述让开发者摸不着头脑。 34 | 今天我就来推荐一款 VSCode 可用的插件——TODO Highlight 。 35 | _安装插件的方法就不用我来介绍了吧_ 36 | 安装好插件后,来到你的项目代码中,试试看写一段 TODO 标记吧! 37 | ![默认样式](https://kira.host/assets/Pictures/Others/20220409143727.png) 38 | 这就是 TODO Highlight 的默认样式,它会自动匹配代码中的 `TODO:` 和 `FIXME:` ,并显示不同的颜色。 39 | 40 | # 自定义关键字及样式 41 | 42 | 当然,你也可以通过 settings.json 自行配置该插件。下面我们来尝试修改一下 settings.json 匹配的关键字及样式。 43 | 打开 settings.json ,找到 `todohighlight.defaultStyle` 字段,这里是 TODOHighlight 的默认样式定义。我的配置是这样的: 44 | 45 | ```json 46 | "todohighlight.defaultStyle": { 47 | "cursor": "pointer", 48 | "border": "1px solid #eee", 49 | "borderRadius": "2px", 50 | "isWholeLine": false 51 | }, 52 | ``` 53 | 54 | 表示当鼠标指向这些 TODO 标记时,鼠标光标会呈现 `pointer` 的状态,同时为标记外围设置边缘,`isWholeLine` 则是说明高亮提示是否要覆盖一整行。 55 | 在设置好默认样式后,我们在 settings.json 中新增一条字段 `todohighlight.keywords` ,它接收一个 json 数组,用来定义插件匹配的关键字。 56 | 比如我们将它修改为如下的代码: 57 | 58 | ```json 59 | "todohighlight.keywords": [ 60 | { 61 | "text": "TODO:", 62 | "color": "#000", 63 | "backgroundColor": "#ffab00", 64 | "overviewRulerColor": "#ffab00" 65 | }, 66 | { 67 | "text": "FIXME:", 68 | "color": "#fff", 69 | "backgroundColor": "#f00", 70 | "overviewRulerColor": "#f00", 71 | "isWholeLine": true 72 | }, 73 | { 74 | "text": "DEBUG:", 75 | "color": "#000", 76 | "backgroundColor": "#0f0", 77 | "overviewRulerColor": "#0f0", 78 | "isWholeLine": true, 79 | "fontWeight": "bold" 80 | }, 81 | { 82 | "text": "NOTE:", 83 | "color": "#fff", 84 | "backgroundColor": "#00a0ff", 85 | "overviewRulerColor": "#00a0ff", 86 | "isWholeLine": true 87 | }, 88 | { 89 | "text": "INFO:", 90 | "color": "#000", 91 | "backgroundColor": "#a0a0a0", 92 | "overviewRulerColor": "#a0a0a0" 93 | } 94 | ], 95 | ``` 96 | 97 | 每个 json 对应了一种匹配形式。 98 | 99 | - 其中 `text` 字段表示需要匹配的具体关键字,这个插件默认只匹配了 `TODO:` 和 `FIXME:` 两条,我们可以通过这个字段新增匹配的关键字,比如最下方的 `DEBUG:`; 100 | - `color` 字段表示匹配后文本的颜色; 101 | - `backgroundColor` 字段表示匹配的文本的背景底色; 102 | - `overviewRulerColor` 字段表示该行在 Vscode 右侧的滚动条上显示的颜色; 103 | - `isWholeLine` 表示是否覆盖整行; 104 | - 可以根据在 JSX 中书写 css 的格式自行定义样式字段 105 | 106 | 而在上面这样配置后,你的 VSCode 就会变成这种风格: 107 | 108 | ```js 109 | // INFO: 这里是示例 110 | // NOTE: 做个笔记 111 | // TODO: 这是个TODO标记 112 | // FIXME: 这里有个 Bug 需要解决 113 | // DEBUG: 下面的代码是调试用的,调试完了记得删除 114 | ``` 115 | 116 | ![自定义样式](https://kira.host/assets/Pictures/Others/20220409150024.png) 117 | -------------------------------------------------------------------------------- /packages/kira-hexo-demo/source/_posts/字节跳动西瓜视频一面面经.md: -------------------------------------------------------------------------------- 1 | --- 2 | title: 字节跳动西瓜视频一面面经 3 | date: 2021-09-30 15:14:58 4 | tags: [面试, 字节跳动] 5 | categories: [面经] 6 | cover: https://lf1-cdn-tos.bytescm.com/obj/static/ies/bytedance_official/_next/static/images/0-390b5def140dc370854c98b8e82ad394.png 7 | --- 8 | 9 | 今天人生第一次面试给了字节跳动,面试前非常紧张,从投递简历到正式面试之间只隔了三天。 10 | 感觉这三天看的博客比三个月学的都多(-\_-||)。 11 | 正式面试的时候也发生了很多状况,包括但不限于对方听不见我说话(面试前明明特地调试了话筒来着),害得人家面试官小哥哥还特地打了一通长达 1 个小时的电话来和我语音面试。 12 | 不过面试官人挺好的,一直都在认真听我回答问题,虽然我面试回答得稀烂,面试结束后也立刻给我发了短信通知我准备二面。 13 | 14 | 15 | 16 | 17 | 18 | # 面试概况 19 | 20 | - **部门**:字节跳动西瓜视频前端开发 21 | - **Base**:厦门 22 | 23 | # 面试的问题 24 | 25 | **以下是个人回忆的面试时问到的问题(后悔没有录音了)** 26 | 27 | 1. 自我介绍 28 | 2. 你是怎么学习前端的 29 | 我就回答了:官方文档、大神写的博客(如阮一峰),遇到自己解决不了的问题就去 CSDN 或者 StackOverflow 上查 30 | 3. 讲一下 jQuery、React、Vue.js 之间的区别 31 | 4. 简要描述一下操作系统中的页表概念 √ 32 | 5. 简要介绍一下操作系统中的虚拟内存 √ 33 | 6. 讲一下你对数据库索引的了解 √ 34 | 这里还顺带问了一下数据库中所有属性是否都应该添加索引 35 | 7. 说一下数据库中的事务,并举一个例子说明 √ 36 | 8. 问了一个简单的算法题:找出数组中前三大的数字 37 | 这个地方我没太想明白,我感觉直接定义一个长为 3 的数组,遍历一遍原数组好像就已经能够在 O(n)的时间复杂度内完成这个流程了。面试官也没说什么,就又问了一句这个算法的空间复杂度是多少。话说这个还有更快的算法吗? 38 | 9. 你知道 javascript 的数组排序算法怎么实现的吗? 39 | 答:没有看过 js 的 sort 方法,但是看过 java 的源码,接着把 java 的 sort 方法的源码解释了一下。 40 | 10. 讲一下什么是稳定排序,什么是非稳定排序,举例说明。 41 | 11. 知道 TCP 和 UDP 之间的区别吗? √ 42 | 12. 说一下你对 Http 的了解 √ 43 | Http 状态码、三次握手、四次挥手、Http 结构 balabala 能说的全说了一遍 44 | 13. 因为简历上写了一个 H5+的 App 项目,所以面试官问了一句你知道 WebView 和底层的 java 怎么通信的吗? 45 | 这段直接给我干蒙了,确实没了解过通信的原理,于是小哥哥让我解释了一下 WebView 是什么东西。 46 | 14. 为什么 Vue 的 data 被定义成方法而不是对象? 47 | 这段其实是知道的,但是一直没回答到重点上,很尴尬 48 | 15. 解释一下浏览器渲染页面的过程 √ 49 | 这里因为我说了 script 标签是串行执行的,所以面试官特地问了一句如果把 script 标签提前到 head 怎么保证执行 script 的同时不阻塞浏览器渲染 html 正文(给 script 标签加 async 属性) 50 | 16. 既然提到了 async,面试官就让我解释一下 async 是什么,有什么作用 51 | 17. 因为上面一题的回答涉及到了 Promise 对象,所以面试官又问了一道 js 事件循环的机制,给了一串代码让我写输出。具体代码记不太清了,只要弄明白了 js 事件循环机制和宏任务微任务的话还是蛮简单的,网上有很多这种代码。 52 | 18. 面试官让我举几个 css 中表示尺寸的单位,我随口答了几个。接着问我知不知道 rem,我回答说是相对于父元素字体的大小,他说我的回答是错的,雀食,em 才是相对于父元素字体的大小,rem 是相对于根元素字体的大小。 53 | 19. 然后让我通过纯 css 做一个动画,我问能不能通过 js 实现……(CSS 一生之敌了属于是) 54 | 20. 虚拟 DOM 和真实 DOM 之间的关系 √ 55 | 21. 简历上有提到过 Nginx,所以面试官问了一句除了反向代理,你有用 Nginx 实现过负载均衡吗 × 56 | 22. 解释一下浏览器创建 AJAX 请求的过程 √ 57 | 顺便手写了一下原生的 JS 代码 58 | 23. AJAX 怎么携带 cookie √ 59 | 24. 说明一下 v-show 和 v-if 的区别,并问如果让你实现 v-show 你会怎么做 √ 60 | 25. http 请求有哪些方法?GET、POST、OPTIONS、PUT 等 61 | 26. 说一下 OPTIONS 和 PUT 是做什么的 (寄了,这些基本没用过,回答得也并不好)× 62 | 27. 说一下 GET 和 POST 之间的区别 √ 63 | 28. 介绍一下 fetch(只听过,没用过,了解得并不多) × 64 | 29. 说一下 http 和 websocket 的区别 65 | 30. 最后让我写了一道算法题: 66 | > 输入一段数组表示许多格子 67 | > 每一个格子中都有一个数字,表示在这个格子可以向前挪动几步,问从第一个格子出发能否到达最后一个格子 68 | > **输入样例一** > **[ 2, 3, 1, 1, 4 ]** > **输出样例一** > **true** 69 | > 70 | > **输入样例二** > **[ 3, 2, 1, 0, 4]** > **输出样例二** > **false** 71 | 72 | 以下是我给出的代码: 73 | 74 | ```java 75 | public static boolean canReach(int[] arr) { 76 | int index = arr.length - 2; 77 | while(index >= 0){ 78 | while(arr[index] != 0){ 79 | if(--index < 0){ 80 | return true; 81 | } 82 | } 83 | int zeroIndex = index; 84 | while(index >= 0 && arr[index] + index <= zeroIndex){ 85 | if(--index < 0){ 86 | return false; 87 | } 88 | } 89 | } 90 | return true; 91 | } 92 | ``` 93 | 94 | 我的想法是,从后往前依次遍历数组,如果遇到了 0,就往前看有没有元素能够跨过这个位置。如果没有就说明到不了末尾元素。 95 | 这题给的时间不太多,只给了差不多 5 分钟吧,这段代码只测试了用例,有没有其他 bug 还不是很清楚。 96 | 97 | # 感想 98 | 99 | 这毕竟是人生第一次面试,心里非常紧张。不过面试官小哥人非常好,一直都非常有耐心。 100 | 最后我在明知自己面试表现稀烂的情况下还是斗胆问了一句,“能不能评价一下我今天的表现?”。 101 | 面试官哥哥尴尬而不失礼貌地笑了一下,然后说你计算机方面的基础还是挺扎实的,算法也还可以,就是下次多看下 CSS 方面的知识。只能说**大厂不愧是大厂**,是我高攀不起了。 102 | 本来以为这轮面试寄了,结果中午去食堂吃饭的时候 HR 直接帮我约了二面和三面,字节跳动速度雀食快,只能说**大厂不愧是大厂**。 103 | ![在这里插入图片描述](https://img-blog.csdnimg.cn/24ed78b1812c43e089c26b75a515a102.jpg) 104 | -------------------------------------------------------------------------------- /packages/kira-hexo-demo/source/_posts/测试文章.md: -------------------------------------------------------------------------------- 1 | --- 2 | title: 测试文章 3 | --- 4 | 5 | 6 | 7 | ## Performing a sauté 8 | 9 | 这列需要一袋段文案 10 | 11 | ## 中文标题 12 | 13 | 阿打发未发放啊无法啊我发的 -------------------------------------------------------------------------------- /packages/kira-hexo-demo/source/_posts/蚂蚁集团-数字金融线-体验技术部前端一面面经.md: -------------------------------------------------------------------------------- 1 | --- 2 | title: 蚂蚁集团-数字金融线-体验技术部前端一面面经 3 | date: 2022-03-11 12:05:43 4 | tags: [面试, 阿里巴巴, 蚂蚁] 5 | categories: [面经] 6 | cover: https://gw.alipayobjects.com/mdn/rms_02c092/afts/img/A*5fXrSZF8be8AAAAAAAAAAAAAARQnAQ 7 | --- 8 | 9 | > 大三春招试着投了份简历,没想到很顺利地拿到了 offer。 10 | 11 | 12 | 13 | 面试官 19:00 打了个电话过来,说往我邮箱里发了个链接,让我先做一个小时的笔试题。 14 | 15 | # 笔试 阿里伯乐系统 60min 16 | 17 | > 笔试是在阿里的伯乐系统上做的,三道手撕代码。 18 | 19 | ## 第一题、根据表达式计算字母数量 20 | 21 | **描述**:输入一串字符串,根据字符串求出每个字母的数量并返回结果对象。(数字为 1 时可省略) 22 | **示例一**:输入:A3B2,输出:{"A": 3, "B": 2} 23 | **示例二**:输入:A(A(A2B)2)3C2,输出:{"A": 16, "B": 6, "C": 2} 24 | 25 | 这题我放在最后写了,结果因为被第三题最后一个输出卡了很久只剩下五分钟写这题代码,来不及写了。 26 | 27 | ## 第二题、手写节流 28 | 29 | **描述**:参数一:执行的函数,参数二:时间间隔。要求实现即使函数被连续处罚多次也只在连续时间内执行一次。 30 | 我一看题面描述立马反应过来用节流,刷刷刷写出来了。 31 | 32 | ```js 33 | function throttle(func, time) { 34 | let timeout; 35 | return function () { 36 | if (!timeout) { 37 | func.apply(this, arguments); 38 | timeout = setTimeout(() => { 39 | timeout = null; 40 | }, delay); 41 | } 42 | }; 43 | } 44 | ``` 45 | 46 | ## 第三题、对象扁平化 47 | 48 | **输入**: 49 | 50 | ```json 51 | { 52 | "a": "a", 53 | "b": [1, { "c": true }, [3]], 54 | "d": { "e": undefined, "f": 3 }, 55 | "g": null 56 | } 57 | ``` 58 | 59 | > 输入用例记不太清了,应该大致差不多吧 60 | 61 | **输出**: 62 | 63 | ```json 64 | { 65 | a: "a", 66 | b[0]: 1, 67 | b[1].c: true, 68 | b[2][0]: 3, 69 | d.f: 3 70 | // null和undefined直接舍去 71 | } 72 | ``` 73 | 74 | 因为没写过这种代码所以一开始也挺没有头绪的,花了很多时间在这题上面。(代码实现挺烂的……时间来不及不够优化了) 75 | 76 | ```js 77 | function flatten(obj) { 78 | const res = {}; 79 | const _flatten = function (o, prev = null) { 80 | if (Array.isArray(o)) { 81 | for (const index in o) { 82 | const ele = o[index]; 83 | if (ele instanceof Object) { 84 | _flatten(ele, `${prev ? prev : ''}[${index}]`); 85 | } else { 86 | if (ele) { 87 | res[`${prev ? prev : ''}[${index}]`] = ele; 88 | } 89 | } 90 | } 91 | return; 92 | } 93 | for (const key in o) { 94 | if (typeof o[key] === 'object') { 95 | if (o[key] !== null) { 96 | _flatten(o[key], `${prev ? prev + '.' : ''}${key}`); 97 | } 98 | } else { 99 | if (o[key] !== undefined) { 100 | res[`${prev ? prev + '.' : ''}${key}`] = o[key]; 101 | } 102 | } 103 | } 104 | }; 105 | _flatten(obj); 106 | return res; 107 | } 108 | ``` 109 | 110 | ## 吐槽一下 111 | 112 | 阿里的伯乐系统在我写代码的时候出问题了,因为面试官说我可以在浏览器的控制台测试代码所以我是全程开着控制台的。结果我写到一半发现控制台一直在报错: 113 | `WebSocket is already in CLOSING or CLOSED state.` 114 | 我当时一看人都麻了……不会是这系统觉得我一直在控制台里测试觉得我离线自动断开 ws 了吧…… 115 | 一个小时后笔试结束,面试官问我第三题是不是没写完,我就告诉他好像 ws 断开连接了,他可能看不到我后面的代码了。 116 | 最后面试官就让我口述了一下第三题的思路,又问了问我有没有解第一题的思路。我就把两道题的思路说了一下,因为第三题是我已经做出来了的,所以我就解释得比较详细,第一题因为还没怎么做就只讲了基本思路,并且回答了应该使用什么数据结构来处理这道题。 117 | 118 | # 面试 全程电话面 30min 119 | 120 | 1. 解释一下笔试题 121 | 2. 自我介绍 122 | 3. 有没有看过 React 的源码? 123 | 我回答说没有看过,但是了解过虚拟 DOM 和 DIFF 算法,面试官让我解释一下这两者。 124 | 4. 根据我的回答,面试官又问了一句为什么在 JSX 里循环生成 DOM 需要添加 key 125 | 我就从 DIFF 算法的原理特性解释了这个问题 126 | 5. class 组件和使用 hooks 的组件有什么区别 127 | 6. 有没有用过 iframe?没有用过 128 | 7. 有做过 h5 的手机端的页面吗 129 | 8. 在手机端一般用什么单位?我就说比较喜欢用 rem、em、rpx 这些,面试官接着又让我解释一下 rem 130 | 9. 现在写代码 Promise 用的比较多哈,你能解释一下 Promise 是什么样的一个概念吗? 131 | 我解释了一下 Promise 的主要用途和用法,也同时讲了一下 async/await 的概念,以及它们和 Promise 之间的关系。 132 | 10. 在以往的项目里有遇到什么困难的点吗? 133 | 这个问题给我噎住了,一下子想不起来有什么很牛逼的难点,比较基本的不敢答,最后挑了一个现在在做的 electron 项目的一个小问题的解决办法。并且讲了一下由于项目重构后使用了更新版的 electron 导致原项目的解决方案不再适用,当时也找不到问题所在,于是通过 overstackflow 了解到 electron 这次更新是把我的这部分功能限制了的,而它的中文文档又没有更新,因此得查阅英文文档才能看到更新的细节……后面又想到了目前的解决方式解决了这个问题。 134 | 135 | 然后问了一下我现在是大几,最后面试官说如果有后续面试会打电话通知我的。 136 | 137 | # 后续进展 138 | 139 | - 3 月 14 日 19:30:一面通过,接到二面面试官好友请求(部门主管) 140 | - 3 月 15 日 18:40:二面通过,当晚二面面试官告知我会帮我约下一轮面试 141 | - 3 月 29 日 08:37:接到来自阿里巴巴的邮件告知已被录用 142 | 143 | ![录取邮件](https://kira.host/assets/Pictures/Others/20220401171825.png) 144 | -------------------------------------------------------------------------------- /packages/kira-hexo-demo/source/about.md: -------------------------------------------------------------------------------- 1 | --- 2 | title: 关于本人 3 | layout: about 4 | --- 5 | 6 | {% krplayer %} 7 | {% aplayerlrc "桜花千爛 -オープニング-" "橋本みゆき" "https://kira.host/assets/Audios/樱花千烂.mp3" "https://p3.music.126.net/vzOncWIreOhP44GpaTcDmg==/109951166875303449.jpg?param=90y90" %} 8 | [00:00.000]作词 : 石川泰 9 | [00:00.040]作曲 : 山口卓也 10 | [00:00.800]はらはらと 舞い落ちる 桜 (樱花落英缤纷 飞舞飘落) 11 | [00:04.540]花びらは 美しさ賛え (片片花瓣绝艳 使人赞叹) 12 | [00:08.189]仮初の 現身(うつしみ)でも いいから (即便其转瞬即逝也无妨) 13 | [00:12.490]その姿 忘れないで (莫忘那春日的繁花盛景) 14 | [00:18.000] 15 | [00:22.300]未来へと 繋がる先は (向着未来相连的前方) 16 | [00:26.200]因果の道 へ続き (构成因果之路的延续) 17 | [00:29.640]光差す ほどその影は 色濃く 落ちゆく (那光线越是耀眼 其落影就愈发深沉) 18 | [00:36.540] 19 | [00:37.040]託された 言葉の重さ 心に 刺さる 棘が (寄托于心的言语 像刺心刻骨般沉重) 20 | [00:44.440]疼くたび 思い出される あの日の約束 (伤痛时回想起的 是那天许下的约定) 21 | [00:51.500] 22 | [00:51.600]生きたい今を 過去を 生きる あなたと (与此刻渴望生命 活在往昔的你) 23 | [00:58.050]言葉は 同じで 遷(うつ)ろう (用相同的话语 来改写) 24 | [01:01.000]愛 と生きる 意味 (爱与生存的含意) 25 | [01:05.000] 26 | [01:07.250]刻を超え 必定の出会い (跨越时空命中注定的邂逅) 27 | [01:11.000]時知らず ゆくりない あなた (不知在何时偶然降临的你) 28 | [01:14.800]出会いとは 別れの 数え歌を  (那相遇与离别的熟悉歌谣) 29 | [01:19.330]導き たなびく (余音袅袅 宛转悠扬) 30 | [01:22.000]重なった 刻と 思い出が (重叠交错的时间与回忆) 31 | [01:25.800]作り出す 今と 明日(あした)になれば (若能创造出现在与未来的话) 32 | [01:30.840]言霊に 火を灯す (但愿能为你) 33 | [01:34.400]道を 作り出すから (用那言灵点亮) 34 | [01:37.140] 35 | [01:37.600]願わくば 君がために (灯火通明的前方) 36 | [01:42.040] 37 | [01:52.690]あなたへと 繋ぐ思いは (与你所牵连的心意) 38 | [01:56.640]記憶に影 を落とし (在记忆中留下残影) 39 | [02:00.100]光指す 方に歩けば 陽炎 消えゆく (沿着光照之处前行 那幻景便云消雾散) 40 | [02:07.090] 41 | [02:07.330]生きた証が 砂と 消える 時でも (哪怕生命如沙般尽数消散) 42 | [02:13.740]一握(いちあく)に残す 掌(てのひら) (手中之物所剩无几) 43 | [02:16.590]だけ 忘れないで (也请不要忘却) 44 | [02:20.840] 45 | [02:22.880]刻を止め 願いを給えば (倘若能让时间停止的话) 46 | [02:26.650]頃刻(けいこく)を 過ごしたい あなた (唯愿与你度过须臾时光) 47 | [02:30.400]別れとは 再び 出会うための (离别是为了在重逢时刻) 48 | [02:35.000]青い鳥 になる (能化作象征幸福的青鸟) 49 | [02:37.690]重ね合う 刻が 思い出を (相互交叠的时空 创造出) 50 | [02:41.440]作り出す 未来 を残すために (的思念 是为了延续那未来) 51 | [02:46.540]言霊が 紡ぎ出す (但愿那言灵所编织的) 52 | [02:50.100]道が 誘(いざな)う 光 (耀眼道路的光芒) 53 | [02:53.000] 54 | [02:53.200]願わくば 君を照らす (能给予你光明) 55 | [02:58.640] 56 | [03:12.000]でも 忘れないで (但是 请牢记于心) 57 | [03:19.000]あなたに 分かる ように (想必你也终将理解) 58 | [03:24.890]篭められた 本当の 想いは このまま  (愿那饱含真心的思念) 59 | [03:31.740]いたかった (连绵不断) 60 | [03:35.000] 61 | [03:36.790]舞い上がる (漫天飞舞的) 62 | [03:38.890]桜吹雪へと (绚烂樱花中) 63 | [03:41.480]隠された 本当の気持ち (藏匿了深埋于心的爱恋) 64 | [03:45.490]春が征く 散り際 さえ 優しい (樱花那稍纵即逝的宿命) 65 | [03:49.800]桜の 宿命 (哪怕在春散花凋之际 也仍是旖旎风光) 66 | [03:52.440]受け止めた 最後の一枚 (抬手接住了最后那片花瓣) 67 | [03:56.190]薄紅も 消えかかっている けど   (即便那抹浅红正渐渐消散) 68 | [04:01.350]次の春が 来た時 (在下个春日到来之时) 69 | [04:05.000]最初の 一枚だけ (愿你能再次伸手触碰) 70 | [04:07.800] 71 | [04:08.039]また 受け止めて欲しいの (那第一片飘落的樱瓣) 72 | [04:12.390] 73 | [04:16.440]わたしのこと (以及我对你的恋心) 74 | [04:20.140] 75 | {% endaplayerlrc %} 76 | {% endkrplayer %} 77 | 78 | ## 自我介绍 79 | 80 | 本人本科就读于世界一流大学的山东大学的软件工程系。 81 | 入学后便成为了一名小码农,主攻前端方向,目前已拿到蚂蚁集团的 Offer,如果顺利以后可能直接入职蚂蚁成为社畜了。 82 | 喜欢二次元,是个**死宅**,半个甲级战犯P**社玩家**。 83 | 此外,也是个 **☭ 共产主义者 ☭**,向伟大的无产阶级革命家毛主席致敬! 84 | 85 | - [ ] abc 86 | - [x] done 87 | - [ ] todo 88 | -------------------------------------------------------------------------------- /packages/kira-hexo-demo/source/archive.md: -------------------------------------------------------------------------------- 1 | --- 2 | title: 文章归档 3 | layout: archives 4 | --- 5 | -------------------------------------------------------------------------------- /packages/kira-hexo-demo/source/friends.md: -------------------------------------------------------------------------------- 1 | --- 2 | title: 我的朋友 3 | layout: friends 4 | --- 5 | 6 | {% krplayer %} 7 | {% aplayerlrc "You are a ghost, I am a ghost 〜劇場のゴースト〜" "スタァライト九九組" "https://kira.host/assets/Audios/YouGhostIGhost.mp3" "https://p3.music.126.net/7DUwlk6F0Lfj9TgL36yNfA==/109951163778883762.jpg?param=90y90" %} 8 | [00:00.000]作词 : 中村彼方 9 | [00:01.000]作曲 : 叶人 / 藤井亮太 10 | [00:06.671] 11 | [00:07.671]hello 私の居場所はどこに (hello,我的容身之处在哪里) 12 | [00:11.254]スポットライトの光が届かないところ (是那沐浴不到舞台灯光的地方) 13 | [00:15.388]さぁ お嬢さんこっちへおいで (来吧,小姑娘,到这儿来) 14 | [00:18.673]苦しい鎖を壊してあげましょう (我来帮你破坏那痛苦的枷锁) 15 | [00:22.957]ああステファニー そっちへ行ってはいけない (啊,斯蒂芬妮,你不能去那里。) 16 | [00:26.606]奈落に向かい歩みを進める小さな足 (向着地狱一步步前进的小小步伐) 17 | [00:30.407]舞台に閉じ込められたら (若被囚禁于舞台之上) 18 | [00:34.057]命が尽きるまで踊らされる (直至生命燃尽你的舞蹈才会结束) 19 | [00:38.373]煌めき (闪耀) 20 | [00:42.341]聖なる歌声が聞こえてる (神圣的歌声不绝于耳) 21 | [00:46.041]それは呪いなのか 救済なのか (这究竟是诅咒,还是救济) 22 | [00:49.709]本当にゴーストは ゴーストは (幽灵真的) 23 | [00:52.109]いたのでしょうか? (真的存在过吗) 24 | [00:53.676]誰も知らないの (谁都不知道啊) 25 | [00:57.060]美しさゆえに愛されてしまう (因这份美而被爱怜) 26 | [01:00.709]この世のものでない何かにすら (即使不是这个世界上的东西) 27 | [01:04.411]本当にゴーストは ゴーストは (幽灵真的) 28 | [01:06.761]いたのでしょうか? (真的存在过吗) 29 | [01:08.361]誰も分からぬまま (谁也不会知道) 30 | [01:14.161]舞台の神 それは あなたと私 (舞台之神,那是你和我) 31 | [01:21.512]舞台の闇 それは あなたは私 (舞台的黑暗 你就是我) 32 | [01:34.097]だって私は舞台の上で (因为我好不容易) 33 | [01:37.631]辛うじて生きることを許されただけ (才被允许活在这舞台之上) 34 | [01:41.780]ねぇ お嬢さん さぞ辛いでしょう (嘿 小姑娘 你一定很辛苦吧) 35 | [01:44.914]永遠の栄光を授けてあげましょう (让我授予你永远的荣光吧) 36 | [01:49.381]ステファニー あなたは一番の女優 (斯蒂芬妮 你是最棒的女演员) 37 | [01:52.914]この瞬間 この街で一番ね (在这个瞬间 这座城市 最棒的女演员) 38 | [01:56.698]舞台の幕が降りた時 (当舞台落下帷幕) 39 | [02:00.216]あなたの命の炎も消える運命 (你的生命之火也将迎来消逝的命运) 40 | [02:08.667]一番星に手が届くように (就让我实现你的愿望) 41 | [02:12.334]あなたの願いを叶えましょう (让你能触到最闪亮之星) 42 | [02:16.033]本当に ゴーストは ゴーストは (幽灵真的) 43 | [02:18.352]居たのでしょうか (真的存在过吗) 44 | [02:20.068]誰も知らないの (谁都不知道啊) 45 | [02:23.368]一瞬の輝きだとしても (就算只是一瞬的闪耀) 46 | [02:27.018]夢が叶うなら 命惜しくはない (只要能实现愿望 即使付出生命也在所不惜) 47 | [02:30.736]本当に ゴーストは ゴーストは (幽灵真的) 48 | [02:33.053]居たのでしょうか (真的存在过吗) 49 | [02:34.703]誰もわからぬまま (谁也不会知道) 50 | [02:45.905]喝采こそがレクイエム (喝彩正是我的安魂曲) 51 | [02:49.288]苦しみのない世界へと (快将我迎入那) 52 | [02:53.022]私を 迎えに来て (没有痛苦的世界) 53 | [02:56.689]一番星に いきたい (想要去往那最闪亮之星) 54 | [03:00.424]さぁ 飛び込め (来吧 跳进去吧) 55 | [03:14.824]美しさゆえに愛されてしまう (因这份美而被爱怜) 56 | [03:18.474]この世のものでない何かにすら (即使不是这个世界上的东西) 57 | [03:22.175]本当にゴーストは ゴーストは (幽灵真的) 58 | [03:24.525]いたのでしょうか? (真的存在过吗?) 59 | [03:26.108]誰も知らないの (谁都不知道啊) 60 | [03:30.443]一瞬の輝きだとしても (就算只是一瞬的闪耀) 61 | [03:32.808](あなたの居場所はない そんなこともわからないの?) (这里没有你的位置 你连这个都不明白么?) 62 | [03:34.492]夢が叶うなら 命惜しくはない (只要能实现愿望 即使付出生命也在所不惜) 63 | [03:37.776]本当に ゴーストは ゴーストは (幽灵真的) 64 | [03:40.080]居たのでしょうか (真的存在过吗?) 65 | [03:41.628]誰もわからぬまま (谁也不会知道) 66 | [03:42.417](ねぇ こっちおいで 楽しいよ) ((嘿 到这来吧 会很快乐哦)) 67 | [03:47.477]舞台の神 それは あなたと私 (舞台之神,那是你和我) 68 | [03:54.862]舞台の闇 それは あなたは私 (舞台的黑暗 你就是我) 69 | [03:57.111](ねぇ 遊ぼう?) ((嘿 来玩吧?)) 70 | [04:06.845]埃の焼ける匂いが私の糧 (舞台灯光灼烧灰尘的气味是我的食粮) 71 | [04:09.530]スポットライトの光だけが 私の存在をあぶりだす (只有聚光灯的闪耀 才能彰显我的存在) 72 | {% endaplayerlrc %} 73 | {% endkrplayer %} 74 | 75 |
76 | 77 | ## 我的朋友 78 | -------------------------------------------------------------------------------- /packages/kira-hexo-demo/themes/.gitkeep: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ch1ny/kira-hexo/0bba396b1c70e7ba6a9f5480194b067692bfeb3f/packages/kira-hexo-demo/themes/.gitkeep -------------------------------------------------------------------------------- /packages/kira-hexo-docs/.gitignore: -------------------------------------------------------------------------------- 1 | .DS_Store 2 | Thumbs.db 3 | db.json 4 | *.log 5 | node_modules/ 6 | dist/ 7 | .deploy*/ 8 | _multiconfig.yml -------------------------------------------------------------------------------- /packages/kira-hexo-docs/docs/.vitepress/config.ts: -------------------------------------------------------------------------------- 1 | import fs from 'fs'; 2 | import path from 'path'; 3 | import { SitemapStream } from 'sitemap'; 4 | import { defineConfig } from 'vitepress'; 5 | 6 | const links: { url: string; lastmod?: number }[] = []; 7 | 8 | export default defineConfig({ 9 | base: '/hexo', 10 | title: 'Kira-Hexo', 11 | description: 'A kirameki ✨ hexo theme for your blog.', 12 | appearance: true, // 允许用户切换深色模式 13 | outDir: '../dist', 14 | themeConfig: { 15 | socialLinks: [ 16 | { icon: 'github', link: 'https://github.com/ch1ny/' }, 17 | { 18 | icon: { 19 | svg: '', 20 | }, 21 | link: 'tencent://AddContact/?fromId=45&fromSubId=1&subcmd=all&uin=1056317718&website=www.oicqzone.com', 22 | }, 23 | ], 24 | sidebar: [ 25 | { 26 | items: [ 27 | { text: '快速开始', link: '/' }, 28 | { text: '版本迭代', link: '/version' }, 29 | { text: '常见问题', link: '/faqs' }, 30 | ], 31 | }, 32 | { 33 | text: '主题配置', 34 | items: [ 35 | { text: '配置文件', link: '/config/config' }, 36 | { text: '图标', link: '/config/icon' }, 37 | { text: '自定义样式', link: '/config/customStyles' }, 38 | { text: '自定义配色', link: '/config/colors' }, 39 | ], 40 | }, 41 | { 42 | text: '页面配置', 43 | items: [ 44 | { text: 'Front Matter', link: '/article/front-matter' }, 45 | { text: '文章归档', link: '/article/archive' }, 46 | ], 47 | }, 48 | { 49 | text: '特色功能', 50 | items: [ 51 | { text: '可复制的代码块', link: '/feature/copy-codeblock' }, 52 | { text: '音频播放', link: '/feature/music' }, 53 | { 54 | text: '哔哩哔哩播放器', 55 | link: '/feature/bilibili', 56 | }, 57 | { 58 | text: 'CodePen', 59 | link: '/feature/codepen', 60 | }, 61 | ], 62 | }, 63 | ], 64 | }, 65 | async transformHtml(_code, id, ctx) { 66 | if (/[\\/]404\.html$/.test(id)) return; 67 | 68 | const url = ctx.pageData.relativePath.replace(/((^|\/)index)?\.md$/, `$2.html`); 69 | 70 | const link = { 71 | url: `${ctx.siteConfig.site.base}${url === '.html' ? 'index.html' : url}`, 72 | lastmod: ctx.pageData.lastUpdated, 73 | } 74 | 75 | links.push(link); 76 | }, 77 | async buildEnd(siteConfig) { 78 | const { outDir, site: { base } } = siteConfig; 79 | const sitemap = new SitemapStream({ hostname: `https://kira.host${base}` }); 80 | const sitemapWriteStream = fs.createWriteStream(path.resolve(outDir, 'sitemap.xml')); 81 | sitemap.pipe(sitemapWriteStream); 82 | links.forEach((link) => sitemap.write(link)); 83 | sitemap.end(); 84 | }, 85 | }); 86 | -------------------------------------------------------------------------------- /packages/kira-hexo-docs/docs/.vitepress/theme/index.ts: -------------------------------------------------------------------------------- 1 | import Theme from 'vitepress/theme'; 2 | import { h } from 'vue'; 3 | import './styles/vars.css'; 4 | 5 | export default { 6 | ...Theme, 7 | Layout() { 8 | return h(Theme.Layout, null, {}); 9 | }, 10 | }; 11 | -------------------------------------------------------------------------------- /packages/kira-hexo-docs/docs/.vitepress/theme/styles/vars.css: -------------------------------------------------------------------------------- 1 | /** 2 | * Colors 3 | * -------------------------------------------------------------------------- */ 4 | 5 | :root { 6 | --vp-c-brand: #569fed; 7 | --vp-c-brand-light: #6daef5; 8 | --vp-c-brand-lighter: #96c8fd; 9 | --vp-c-brand-lightest: #aad3fe; 10 | --vp-c-brand-dark: #3d8bde; 11 | --vp-c-brand-darker: #1b69bd; 12 | --vp-c-brand-dimm: #1b69bd24; 13 | } 14 | 15 | /** 16 | * Component: Button 17 | * -------------------------------------------------------------------------- */ 18 | 19 | :root { 20 | --vp-button-brand-border: var(--vp-c-brand-light); 21 | --vp-button-brand-text: var(--vp-c-white); 22 | --vp-button-brand-bg: var(--vp-c-brand); 23 | --vp-button-brand-hover-border: var(--vp-c-brand-light); 24 | --vp-button-brand-hover-text: var(--vp-c-white); 25 | --vp-button-brand-hover-bg: var(--vp-c-brand-light); 26 | --vp-button-brand-active-border: var(--vp-c-brand-light); 27 | --vp-button-brand-active-text: var(--vp-c-white); 28 | --vp-button-brand-active-bg: var(--vp-button-brand-bg); 29 | } 30 | 31 | /** 32 | * Component: Home 33 | * -------------------------------------------------------------------------- */ 34 | 35 | :root { 36 | --vp-home-hero-name-color: transparent; 37 | --vp-home-hero-name-background: -webkit-linear-gradient(60deg, #3178c6 30%, #9feaf9); 38 | --vp-home-hero-image-filter: blur(40px); 39 | } 40 | 41 | @media (min-width: 640px) { 42 | :root { 43 | --vp-home-hero-image-filter: blur(56px); 44 | } 45 | } 46 | 47 | @media (min-width: 960px) { 48 | :root { 49 | --vp-home-hero-image-filter: blur(72px); 50 | } 51 | } 52 | 53 | /** 54 | * Component: Custom Block 55 | * -------------------------------------------------------------------------- */ 56 | 57 | :root { 58 | --vp-custom-block-tip-border: var(--vp-c-brand); 59 | --vp-custom-block-tip-text: var(--vp-c-brand-darker); 60 | --vp-custom-block-tip-bg: var(--vp-c-brand-dimm); 61 | } 62 | 63 | .dark { 64 | --vp-custom-block-tip-border: var(--vp-c-brand); 65 | --vp-custom-block-tip-text: var(--vp-c-brand-lightest); 66 | --vp-custom-block-tip-bg: var(--vp-c-brand-dimm); 67 | } 68 | 69 | /** 70 | * Component: Algolia 71 | * -------------------------------------------------------------------------- */ 72 | 73 | .DocSearch { 74 | --docsearch-primary-color: var(--vp-c-brand) !important; 75 | } 76 | 77 | /** 78 | * VitePress: Custom fix 79 | * -------------------------------------------------------------------------- */ 80 | 81 | /* 82 | Use lighter colors for links in dark mode for a11y. 83 | Also specify some classes twice to have higher specificity 84 | over scoped class data attribute. 85 | */ 86 | .dark .vp-doc a, 87 | .dark .vp-doc a > code, 88 | .dark .VPNavBarMenuLink.VPNavBarMenuLink:hover, 89 | .dark .VPNavBarMenuLink.VPNavBarMenuLink.active, 90 | .dark .link.link:hover, 91 | .dark .link.link.active, 92 | .dark .edit-link-button.edit-link-button, 93 | .dark .pager-link .title { 94 | color: var(--vp-c-brand-lighter); 95 | } 96 | 97 | .dark .vp-doc a:hover, 98 | .dark .vp-doc a > code:hover { 99 | color: var(--vp-c-brand-lightest); 100 | opacity: 1; 101 | } 102 | 103 | /* Transition by color instead of opacity */ 104 | .dark .vp-doc .custom-block a { 105 | transition: color 0.25s; 106 | } 107 | 108 | .vp-doc h1 { 109 | font-size: 32px; 110 | } 111 | 112 | .vp-doc h2 { 113 | font-size: 28px; 114 | } 115 | 116 | .vp-doc h3 { 117 | font-size: 24px; 118 | } 119 | 120 | .vp-doc h4 { 121 | font-size: 22px; 122 | } 123 | 124 | .vp-doc h5 { 125 | font-size: 18px; 126 | } 127 | 128 | .vp-doc h6 { 129 | font-size: 16px; 130 | } 131 | 132 | .vp-doc b, 133 | .vp-doc strong { 134 | margin-inline: 0.15em; 135 | text-shadow: 0 0 0.05em #000; 136 | } 137 | 138 | .dark .vp-doc b, 139 | .dark .vp-doc strong { 140 | margin-inline: 0.15em; 141 | text-shadow: 0 0 0.05em #fff; 142 | } 143 | 144 | .vp-doc :not(pre) > code { 145 | background-color: #50d6ff26; 146 | } 147 | -------------------------------------------------------------------------------- /packages/kira-hexo-docs/docs/article/archive.md: -------------------------------------------------------------------------------- 1 | # 文章归档 2 | 3 | ## 用法 4 | 5 | 在 hexo 项目根目录的 `source` 文件夹下新建一个 Markdown 文件,文件名随意。 6 | 7 | > 比如我自己的站点就是叫做 `archive.md`。 8 | 9 | 然后在文件中填入: 10 | ```md 11 | --- 12 | title: 文章归档 13 | layout: archives 14 | --- 15 | ``` 16 | 17 | :::tip 18 | 其中的 `title` 字段可以根据自己的需要替换成自己喜欢的页面标题,但是 `layout` 的值**必须是** `archives`。 19 | ::: 20 | 21 | *** 22 | 23 | ## 效果演示 24 | 25 | [文章归档 - 德布罗煜](https://kira.host/archive.html) 26 | 27 | ![文章归档页效果演示](/assets/img/archive.webp) -------------------------------------------------------------------------------- /packages/kira-hexo-docs/docs/article/front-matter.md: -------------------------------------------------------------------------------- 1 | # Front Matter 2 | 3 | ## 关于 Front Matter 4 | 5 | 在 Hexo 中,Front Matter 就是文章最上方使用 `---` 隔开的区域,用于声明单个文件的变量,比如: 6 | 7 | ```markdown 8 | --- 9 | title: 这是一篇文章 10 | date: 2022/09/04 21:14:56 11 | --- 12 | ``` 13 | 14 | 关于 Front Matter 的更多信息可以参考 Hexo 的[官方文档](https://hexo.io/zh-cn/docs/front-matter)。 15 | 16 | ## 扩展 Front Matter 17 | 18 | 在 Kira-Hexo 当中,我们也为各位保留了如下几个 Front Matter 用于对文章进行部分定制: 19 | | 参数 | 默认值 | 描述 | 20 | | --- | --- | --- | 21 | | cover | theme.background.path | 文章封面 | 22 | | reprinted | false | 是否为转载文章(转载文章不会标记版权信息) | -------------------------------------------------------------------------------- /packages/kira-hexo-docs/docs/assets/img/archive.webp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ch1ny/kira-hexo/0bba396b1c70e7ba6a9f5480194b067692bfeb3f/packages/kira-hexo-docs/docs/assets/img/archive.webp -------------------------------------------------------------------------------- /packages/kira-hexo-docs/docs/assets/img/biliplayer.webp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ch1ny/kira-hexo/0bba396b1c70e7ba6a9f5480194b067692bfeb3f/packages/kira-hexo-docs/docs/assets/img/biliplayer.webp -------------------------------------------------------------------------------- /packages/kira-hexo-docs/docs/assets/img/copied.webp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ch1ny/kira-hexo/0bba396b1c70e7ba6a9f5480194b067692bfeb3f/packages/kira-hexo-docs/docs/assets/img/copied.webp -------------------------------------------------------------------------------- /packages/kira-hexo-docs/docs/assets/img/copyable.webp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ch1ny/kira-hexo/0bba396b1c70e7ba6a9f5480194b067692bfeb3f/packages/kira-hexo-docs/docs/assets/img/copyable.webp -------------------------------------------------------------------------------- /packages/kira-hexo-docs/docs/assets/img/preview.webp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ch1ny/kira-hexo/0bba396b1c70e7ba6a9f5480194b067692bfeb3f/packages/kira-hexo-docs/docs/assets/img/preview.webp -------------------------------------------------------------------------------- /packages/kira-hexo-docs/docs/config/colors.md: -------------------------------------------------------------------------------- 1 | # 自定义配色 2 | 3 | ## 自定义彩虹配色 4 | 在 Kira-Hexo 中,为开发者预置了一套丰富的彩虹配色方案,同时允许开发者自行修改彩虹色配置。 5 | 6 | ```yaml 7 | color: # 配色方案,从first到seventh为优先级为1-7的颜色,默认为彩虹配色 8 | first: # 同时作为主题色 9 | r: 49 10 | g: 174 11 | b: 255 12 | second: 13 | r: 255 14 | g: 78 15 | b: 106 16 | third: 17 | r: 255 18 | g: 185 19 | b: 0 20 | fourth: 21 | r: 51 22 | g: 213 23 | b: 122 24 | fifth: 25 | r: 0 26 | g: 219 27 | b: 255 28 | sixth: 29 | r: 255 30 | g: 69 31 | b: 0 32 | seventh: 33 | r: 144 34 | g: 144 35 | b: 255 36 | ``` 37 | 38 | 下面是按顺序排出的彩虹配色: 39 | 40 |
41 |
42 |
43 |
44 |
45 |
46 |
47 |
48 |
-------------------------------------------------------------------------------- /packages/kira-hexo-docs/docs/config/config.md: -------------------------------------------------------------------------------- 1 | # 配置详解 2 | 3 | 为了让 Kira-Hexo 正常工作,你还需要在 Hexo 项目的根目录下新建一个名为 `_config.kira.yml` 的文件,并在文件中填入下方的配置信息。 4 | 5 | ## 配置源代码 6 | 7 | 大部分配置项均已写好对应的注释,开发者可以自行尝试。 8 | 9 | ```yaml 10 | avatar: https://kira.host/assets/Pictures/Others/20220922230447.jpg # 网站 Logo 11 | background: # 既是博客的背景,又是文章默认头图 12 | path: https://kira.host/assets/Pictures/Others/-f0d5cc34c6e5aa7_compressed.jpg 13 | width: 1280 14 | height: 720 15 | favicon: 16 | href: https://kira.host/assets/Pictures/Others/116359b4ccf19917.jpg # 网站图标 17 | type: image/png # 图标类型,可能的值有(image/png, image/vnd.microsoft.icon, image/x-icon, image/gif) 18 | 19 | # 附加图标库 使用说明:https://kira.host/hexo/config/icon.html 20 | # iconlib: //at.alicdn.com/t/font_3299330_el19bsi97h8.css 21 | 22 | cdn: # 这里可以修改站点使用的库的CDN 23 | gitalk: 24 | css: https://unpkg.com/gitalk@latest/dist/gitalk.css 25 | js: https://unpkg.com/gitalk@latest/dist/gitalk.min.js 26 | giscus: 27 | js: https://giscus.app/client.js 28 | 29 | # beian: 赣ICP备2021007955号-3 # 备案号(选填,别往你们网站上挂我的备案号!!!) 30 | 31 | menu: 32 | 回到首页: 33 | - / 34 | - icon-home 35 | 文章归档: 36 | - /archive.html 37 | - icon-container 38 | 关于本人: 39 | - /about.html 40 | - icon-user 41 | 我的朋友: 42 | - /friends.html 43 | - icon-team 44 | 45 | widgets: 46 | - social 47 | - category 48 | - tagcloud 49 | - archive 50 | 51 | maxTagcloud: 0 # 标签云组件显示的标签数量,0 表示不限制 52 | 53 | social: 54 | QQ: 55 | - tencent://AddContact/?fromId=45&fromSubId=1&subcmd=all&uin=<去掉尖括号后填上你的QQ号>&website=www.oicqzone.com 56 | - icon-QQ 57 | - rgb(49, 174, 255) 58 | - rgba(49, 174, 255, .1) 59 | 哔哩哔哩: 60 | - https://space.bilibili.com/<改成你的B站uid> 61 | - icon-bilibili 62 | - rgb(231, 106, 141) 63 | - rgba(231, 106, 141, .15) 64 | GitHub: 65 | - https://github.com/<你的github id>/ 66 | - icon-github 67 | - rgb(25, 23, 23) 68 | - rgba(25, 23, 23, .15) 69 | Gitee: 70 | - https://gitee.com/<你的gitee id> 71 | - icon-gitee 72 | - rgb(165, 15, 15) 73 | - rgba(165, 15, 15, .15) 74 | 75 | color: # 配色方案,从first到seventh为优先级为1-7的颜色,默认为彩虹配色 76 | first: # 同时作为主题色 77 | r: 49 78 | g: 174 79 | b: 255 80 | second: 81 | r: 255 82 | g: 78 83 | b: 106 84 | third: 85 | r: 255 86 | g: 185 87 | b: 0 88 | fourth: 89 | r: 51 90 | g: 213 91 | b: 122 92 | fifth: 93 | r: 0 94 | g: 219 95 | b: 255 96 | sixth: 97 | r: 255 98 | g: 69 99 | b: 0 100 | seventh: 101 | r: 144 102 | g: 144 103 | b: 255 104 | 105 | # 评论区 106 | gitalk: 107 | active: false # 是否启用 gitalk 108 | admin: -your github username- # 拥有对该repo进行操作的 GitHub username 109 | owner: -your github username- # 持有该 repo 的 GitHub username 110 | repo: -issue repo name- # 存放评论的 issue 所在的 repo 111 | clientID: -id- # GitHub Client ID 112 | clientSecret: -key- # GitHub Client Secret 113 | title: '' # Gitalk Issue Title 114 | # 你们不要在这里填我的 giscus 配置项,不然你们博客下的评论会全部跑到我的仓库下面…… 115 | # https://giscus.app/zh-CN 可以在这个网站上手动选择配置填到下方对应位置 116 | giscus: 117 | active: true # 是否启用 giscus 118 | repo: -your github username-/-your giscus repo- # 存放评论的 discus 所在的 repo 119 | repoID: -your giscus repo ID- # GitHub repo ID 120 | category: Announcements # 选择新 discussions 所在的分类 121 | categoryID: -giscus category id- # 分类 ID 122 | mapping: pathname # pathname, url, title, og:title, specific, number 123 | # term: # abc 123 # specific | number 124 | theme: light 125 | lang: en 126 | 127 | copyright: '版权声明:本文采用 CC BY-NC-SA 3.0 CN 协议进行许可' 128 | copyTip: "著作权归作者所有。\n商业转载请联系作者获得授权,非商业转载请注明出处。\n来源:%url" # 自定义复制版权文案,使用 %url 代替当前页面URL, 修改为false禁用 129 | 130 | # 自定义侧边栏尾部内容 131 | sidebar: '' 132 | 133 | # 自定义样式 134 | # customStyles: 135 | # - style 136 | # - custom 137 | 138 | # 友链配置 139 | friends: 140 | # - avatar: <友链缩略图> 141 | # link: <跳转连接> 142 | # name: <名称> 143 | 144 | # 可复制的代码块 145 | copyableCodeblock: true 146 | 147 | ``` -------------------------------------------------------------------------------- /packages/kira-hexo-docs/docs/config/customStyles.md: -------------------------------------------------------------------------------- 1 | # 自定义样式 2 | 3 | `kira-hexo` 为用户提供了自定义样式的配置接口。 4 | 先在 `_config.kira.yml` 主题配置文件中新增字段 `customStyles`,其值为字符串数组。例如下面的配置: 5 | 6 | ```yaml 7 | # 自定义样式 8 | customStyles: 9 | - style 10 | - custom 11 | ``` 12 | 之后在博客根目录下的 `source` 文件夹下分别新建 `style.css` 以及 `custom.css` 即可。 13 | 14 | ::: danger 自定义样式注意 15 | 如果您需要使用自定义样式,我们建议您对根目录下的 `_config.yml` 进行如下修改: 16 | ```yaml 17 | aplayer: 18 | asset_inject: false 19 | ``` 20 | ::: 21 | -------------------------------------------------------------------------------- /packages/kira-hexo-docs/docs/config/icon.md: -------------------------------------------------------------------------------- 1 | # 图标 2 | 3 | ## Kira-Hexo 自带图标 4 | [kira-hexo iconfont](https://kira.host/blog/lib/iconfont/demo_index.html) 5 | 6 | ## 新增图标 7 | 如果需要自己添加图标的话,建议使用[阿里巴巴矢量图标库](https://www.iconfont.cn/): 8 | 9 | 1. 注册登录阿里巴巴矢量图标库 10 | 2. [资源管理 - 我的项目](https://www.iconfont.cn/manage/index?manage_type=myprojects) 11 | 3. 新建项目,`Font Family` 参数设置为 `kirafont` 12 | 4. 添加新图标至项目 13 | 5. 可以直接选择生成 CDN 地址使用,但是建议打包资源到本地使用 -------------------------------------------------------------------------------- /packages/kira-hexo-docs/docs/faqs.md: -------------------------------------------------------------------------------- 1 | # 常见问题 2 | 3 | ## 语法高亮显示 4 | 5 | 由于 kira-hexo 的语法高亮依赖于 `hljs`,请在根目录中配置 `_config.yml` 以启动语法高亮显示: 6 | 7 | ```yaml 8 | highlight: 9 | enable: true 10 | hljs: true 11 | ``` 12 | -------------------------------------------------------------------------------- /packages/kira-hexo-docs/docs/feature/bilibili.md: -------------------------------------------------------------------------------- 1 | # Bilibili 播放器 2 | 3 | ## 使用 biliplayer 标签 4 | Kira-Hexo 为用户提供了 `{% biliplayer %}` 标签用以在文章当中快速创建**哔哩哔哩** iframe 播放器。 5 | 6 | ### 用法 7 | ```markdown 8 | {% biliplayer 33053034 11 1 %} 9 | ``` 10 | ![预览](/assets/img/biliplayer.webp) 11 | 12 | ### 标签参数 13 | | 选项 | 默认值 | 描述 | 14 | | --- | --- | --- | 15 | | vid | 必须值 | 视频av/bv号 | 16 | | page | 1 | 视频分P | 17 | | danmaku | 1 | 开启/关闭弹幕 | 18 | 19 | :::tip BV支持 20 | 自 `1.3.0` 版本起,`biliplayer` 支持 BV 号播放,kira-hexo 会根据传入的值自动区分是 av 号还是 bv 号。 21 | ::: 22 | -------------------------------------------------------------------------------- /packages/kira-hexo-docs/docs/feature/codepen.md: -------------------------------------------------------------------------------- 1 | # CodePen 快捷标签 2 | 3 | Kira-Hexo 也为各位程序员用户提供了方便快捷的 CodePen 直链标签。 4 | 5 | ## 用法 6 | 7 | ```markdown 8 | {% pen https://codepen.io/ch1ny/pen/yLvENLp?editors=0010 %} 9 | ``` 10 | 11 | 在文章中的表现如下: 12 | 13 | 27 | -------------------------------------------------------------------------------- /packages/kira-hexo-docs/docs/feature/copy-codeblock.md: -------------------------------------------------------------------------------- 1 | # 可复制的代码块 2 | 3 | 通过主题配置文件配置 `copyableCodeblock` true | false 来开关代码块复制功能。 4 | 5 | 鼠标悬浮于代码块时右上角显示复制按钮。 6 | 7 | ![](/assets/img/copyable.webp) 8 | 9 | ![](/assets/img/copied.webp) 10 | -------------------------------------------------------------------------------- /packages/kira-hexo-docs/docs/feature/music.md: -------------------------------------------------------------------------------- 1 | # 音频播放 2 | 3 | ## 使用 APlayer 4 | Kira-Hexo 自带了 `hexo-tag-aplayer` 依赖,用户可以使用它在文章中插入音乐。 5 | 6 | 关于 aplayer 的用法可以查阅[官方文档](https://github.com/MoePlayer/hexo-tag-aplayer/blob/master/docs/README-zh_cn.md#%E4%BD%BF%E7%94%A8)。 7 | 8 | ```markdown 9 | 10 | {% meting "60198" "netease" "playlist" %} 11 | 12 | 13 | {% meting "60198" "netease" "playlist" "autoplay" "mutex:false" "listmaxheight:340px" "preload:none" "theme:#ad7a86"%} 14 | ``` 15 | 16 | :::tip 17 | 自 `hexo-theme-kira@1.3.0` 版本开始,我们已经支持直接使用 `{% meting %}` 标签使用 MetingJS 播放器。如果您曾是旧版用户,我们强烈建议您将 `_config.yml` 中的 `aplayer` 配置移除或将 `aplayer.asset_inject` 设置为 `false`。 18 | ::: 19 | 20 | 下面是 meting 标签的参数列表: 21 | | 选项 | 默认值 | 描述 | 22 | | --- | --- | --- | 23 | | id | 必须值 | 歌曲 id / 播放列表 id / 相册 id / 搜索关键字 | 24 | | server | 必须值 | 音乐平台: netease, tencent, kugou, xiami, baidu | 25 | | type | 必须值 | song, playlist, album, search, artist | 26 | | fixed | false | 开启固定模式 | 27 | | mini | false | 开启迷你模式 | 28 | | loop | all | 列表循环模式:all, one,none | 29 | | order | list | 列表播放模式: list, random | 30 | | volume | 0.7 | 播放器音量 | 31 | | lrctype | 0 | 歌词格式类型 | 32 | | listfolded | false | 指定音乐播放列表是否折叠 | 33 | | storagename | metingjs | LocalStorage 中存储播放器设定的键名 | 34 | | autoplay | true | 自动播放,移动端浏览器暂时不支持此功能 | 35 | | mutex | true | 该选项开启时,如果同页面有其他 aplayer 播放,该播放器会暂停 | 36 | | listmaxheight | 340px | 播放列表的最大长度 | 37 | | preload | auto | 音乐文件预载入模式,可选项: none, metadata, auto | 38 | | theme | #ad7a86 | 播放器风格色彩设置 | 39 | 40 | ## 旧版本兼容 41 | 42 | 在低于 1.3.0 的版本中,你可以在 `_config.yml` 当中添加下面的配置来开启 APlayer 对 MetingJS 的支持: 43 | ```yaml 44 | aplayer: 45 | meting: true 46 | asset_inject: false # 请务必将该值设置为 false 47 | ``` 48 | 现在你可以通过 `{% meting ... %}` 在文章中使用 MetingJS 播放器了。 49 | 50 | :::danger APlayer导致的资源污染 51 | 由于 `hexo-tag-aplayer` 默认会自动注入资源,会对您文档的构建产物造成资源污染。因此,如果您仍在使用低于 1.3.0 的 kira-hexo,我们强烈建议您更新至 1.3.0 版本以上,并完全移除 `_config.yml` 中的 `aplayer` 相关配置或将 `aplayer.asset_inject` 设置为 `false`。 52 | ::: 53 | -------------------------------------------------------------------------------- /packages/kira-hexo-docs/docs/index.md: -------------------------------------------------------------------------------- 1 | # 快速开始 2 | 3 | ## Kira Hexo 4 | 5 | :::tip CREDITS 6 | 特别鸣谢 [`nexmoe`](https://github.com/theme-nexmoe/hexo-theme-nexmoe),这是我最初使用的 hexo 主题,kira-hexo 的设计风格也是借鉴于此,在其风格之上做了部分定制化,希望各位能够支持支持原作者。 7 | ::: 8 | 9 | > A kirameki ✨ hexo theme for your blog. 10 | 11 | 12 |
13 | 14 | npm version 15 | 16 |   17 | 18 | npm weekly download 19 | 20 |   21 | 22 | github stars 23 | 24 |
25 | 26 | 27 | [Kira-Hexo](https://github.com/ch1ny/kira-hexo) 是一款高度定制化的 Hexo 专属主题 28 | ![预览](/assets/img/preview.webp) 29 | 30 | > 欢迎访问 [我的主页](https://kira.host/),这也是使用该主题搭建的示例站点。 31 | 32 | :::tip 33 | 在使用 kira-hexo 之前,请确认已经仔细阅读过 [Hexo 官方文档](https://hexo.io/zh-cn/docs/),完成了对 hexo 的安装以及对 `_config.yml` 的基本配置。 34 | ::: 35 | 36 | ## 使用模板 37 | 38 | 我们提供了一份 `kira-hexo` 模板,帮您免去了初期的配置工作,如果您不想学习后面的配置方案,则可以使用我们提供的模板体验 `kira-hexo` 。 39 | 40 | **With npm:** 41 | ```bash 42 | # 我其实更推荐您使用 yarn 或 pnpm ,而不是 npm 43 | npm create kira-hexo@latest myblog 44 | ``` 45 | 46 | **With yarn:** 47 | ```bash 48 | yarn create kira-hexo myblog 49 | ``` 50 | 51 | **With pnpm:** 52 | ```bash 53 | pnpm create kira-hexo myblog 54 | ``` 55 | 56 | ## 使用 npm 安装主题 57 | 58 | 在你的 Hexo 项目根目录下运行 59 | 60 | ```bash 61 | npm i hexo-theme-kira 62 | ``` 63 | 64 | 当然,我们更推荐您使用 yarn 进行安装 65 | 66 | ```bash 67 | yarn add hexo-theme-kira 68 | ``` 69 | 70 | ## 启用 Kira-Hexo 71 | 72 | 在 `_config.yml` 中,将 `theme` 的值修改为 `kira` 73 | 74 | :::tip **代码高亮** 75 | `Kira-Hexo` 的代码高亮依赖于 `hljs`,因此使用 kira-hexo 的同时需要将 `_config.yml` 中的 `highlight.hljs` 设置为 `true`。 76 | ::: 77 | 78 | ## 配置 Kira-Hexo 79 | 80 | 安装好主题后,在 Hexo 根目录下修改 `_config.kira.yml` 81 | 82 | 配置文件内容请参考 [配置文件](/config/config.html) -------------------------------------------------------------------------------- /packages/kira-hexo-docs/docs/version.md: -------------------------------------------------------------------------------- 1 | # 版本迭代 2 | 3 | ## 更新版本 4 | 5 | 你可以通过 npm 包的形式下载到最新版的 **Kira-Hexo** ,在你的 hexo 项目根目录下执行下面的指令即可升级 **Kira-Hexo**: 6 | ```bash 7 | npm i hexo-theme-kira 8 | 或 9 | yarn add hexo-theme-kira 10 | ``` 11 | 12 | ## 语义化版本 13 | 14 | **Kira-Hexo** 更新符合语义化版本,使用者可根据版本号的更迭来大致推测此次更新的范围并及时做出调整。 15 | 16 | 首先我们需要知道版本号的构成: 主版本号.次版本号.修订号 17 | 18 | 举个例子: 19 | 20 | | 版本号 | 主版本号 | 次版本号 | 修订号 | 21 | | --- | --- | --- | --- | 22 | | 0.1.2 | 0 | 1 | 2 | 23 | 24 | * **修订号**更新,表示本次更新属于无感更新,开发者通常感知不到新的变化,不需要修改 `_config.kira.yml` 配置文件。一般是性能优化、 bug 修复等细节改动,少数情况下可能是针对某一功能的拓展开发。 25 | * **次版本号**更新,说明本次升级含有可以被直观感受到的变化,比如界面大范围调整、功能新增,少数情况下需要修改配置文件。 26 | * **主版本号**更新,意味着本次改动属于大版本更新,存在大规模变动,需要修改配置文件。 27 | 28 | 如果对升级存在问题,请前往 [Github](https://github.com/ch1ny/kira-hexo/issues/new) 提交您的疑问。 -------------------------------------------------------------------------------- /packages/kira-hexo-docs/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "kira-hexo-docs", 3 | "version": "1.4.9", 4 | "main": "index.js", 5 | "author": "德布罗煜", 6 | "license": "MIT", 7 | "devDependencies": { 8 | "vitepress": "^1.0.0-alpha.13" 9 | }, 10 | "scripts": { 11 | "dev": "vitepress dev docs", 12 | "dist": "vitepress build docs", 13 | "serve": "vitepress serve docs" 14 | }, 15 | "dependencies": { 16 | "sitemap": "^7.1.1" 17 | } 18 | } 19 | -------------------------------------------------------------------------------- /packages/kira-hexo-toc/index.js: -------------------------------------------------------------------------------- 1 | const cheerio = require("cheerio"); 2 | const toc = require("markdown-toc"); 3 | 4 | const config = hexo.config.toc || {}; 5 | hexo.config.toc = Object.assign({}, config); 6 | 7 | function insert(data) { 8 | const options = Object.assign({}, this.config.toc); 9 | 10 | // add class option 11 | if (options.class) { 12 | data.content = data.content.replace( 13 | "", 14 | '
', 19 | ); 20 | } 21 | 22 | data.content = toc.insert(data.content, options); 23 | return data; 24 | } 25 | 26 | function heading(data) { 27 | const options = Object.assign({}, this.config.toc); 28 | 29 | const $ = cheerio.load(data.content, { 30 | decodeEntities: 31 | options.decodeEntities !== undefined ? options.decodeEntities : false, 32 | }); 33 | const headings = $("h1, h2, h3, h4, h5, h6"); 34 | 35 | headings.each(function () { 36 | const $title = $(this); 37 | const title = $title.text(); 38 | const id = toc.slugify(title, options); 39 | // $title.attr('id', id); 40 | $title.children("a").remove(); 41 | $title.html( 42 | '' + $title.html() + "", 43 | ); 44 | $title.removeAttr("id"); 45 | 46 | if (options.anchor) { 47 | const anchorOpts = Object.assign( 48 | { 49 | position: "after", 50 | symbol: "#", 51 | style: "header-anchor", 52 | }, 53 | options.anchor, 54 | ); 55 | 56 | // Put the anchor after the title by default, unless says otherwise 57 | const link = 58 | '' + 63 | anchorOpts.symbol + 64 | ""; 65 | if (anchorOpts.position === "before") { 66 | $title.prepend(link); 67 | } else { 68 | $title.append(link); 69 | } 70 | } 71 | }); 72 | 73 | data.content = $.html(); 74 | 75 | // add class option 76 | if (options.class) { 77 | data.content = data.content 78 | .replace( 79 | '
', 80 | '
', 81 | ) 82 | .replace('
', "
"); 83 | } 84 | 85 | return data; 86 | } 87 | 88 | hexo.extend.filter.register("before_post_render", insert); 89 | hexo.extend.filter.register("after_post_render", heading); 90 | -------------------------------------------------------------------------------- /packages/kira-hexo-toc/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "hexo-kira-toc", 3 | "version": "1.4.9", 4 | "main": "index.js", 5 | "dependencies": { 6 | "cheerio": "^1.0.0", 7 | "markdown-toc": "^1.2.0" 8 | } 9 | } 10 | -------------------------------------------------------------------------------- /packages/kira-hexo/.gitignore: -------------------------------------------------------------------------------- 1 | .DS_Store 2 | Thumbs.db 3 | db.json 4 | *.log 5 | node_modules/ 6 | public/ 7 | .deploy*/ 8 | _multiconfig.yml 9 | *.lock 10 | .yalc/ 11 | -------------------------------------------------------------------------------- /packages/kira-hexo/.npmignore: -------------------------------------------------------------------------------- 1 | .DS_Store 2 | Thumbs.db 3 | db.json 4 | *.log 5 | node_modules/ 6 | public/ 7 | .deploy*/ 8 | _multiconfig.yml 9 | demo/ 10 | *.lock 11 | preview.png 12 | .github/ 13 | pnpm-lock.yaml 14 | -------------------------------------------------------------------------------- /packages/kira-hexo/languages/default.yml: -------------------------------------------------------------------------------- 1 | continue: 查看更多 2 | nav: 3 | home: 回到首页 4 | 5 | search: 搜索 6 | archive: 文章归档 7 | categories: 文章分类 8 | tagcloud: 标签云 9 | social: 社交按钮 10 | 11 | count: 12 | articles: 文章 13 | tags: 标签 14 | categories: 分类 15 | 16 | copyright: 17 | author: 本文作者 18 | permalink: 本文链接 -------------------------------------------------------------------------------- /packages/kira-hexo/languages/en.yml: -------------------------------------------------------------------------------- 1 | continue: More 2 | nav: 3 | home: Home 4 | 5 | search: Search 6 | archive: Archive 7 | categories: Categories 8 | tagcloud: Tag Cloud 9 | 10 | count: 11 | articles: Articles 12 | tags: Tags 13 | categories: Categories 14 | 15 | copyright: 16 | author: Author 17 | permalink: Link -------------------------------------------------------------------------------- /packages/kira-hexo/languages/it.yml: -------------------------------------------------------------------------------- 1 | continue: Di più 2 | nav: 3 | home: Home 4 | 5 | search: Cerca 6 | archive: Archivio 7 | categories: Categorie 8 | tagcloud: Tagcloud 9 | social: Social 10 | 11 | count: 12 | articles: Articoli 13 | tags: Tags 14 | categories: Categorie 15 | 16 | copyright: 17 | author: Autore 18 | permalink: Link 19 | -------------------------------------------------------------------------------- /packages/kira-hexo/languages/ja.yml: -------------------------------------------------------------------------------- 1 | continue: 続きを読む 2 | nav: 3 | home: ホーム 4 | 5 | search: 検索 6 | archive: アーカイブ 7 | categories: カテゴリ 8 | tagcloud: タグクラウド 9 | social: タグクラウド 10 | 11 | count: 12 | articles: 文章 13 | tags: タグ 14 | categories: カテゴリ 15 | 16 | copyright: 17 | author: 著者 18 | permalink: リンク 19 | -------------------------------------------------------------------------------- /packages/kira-hexo/languages/zh-CN.yml: -------------------------------------------------------------------------------- 1 | continue: 查看更多 2 | nav: 3 | home: 回到首页 4 | 5 | search: 搜索 6 | archive: 文章归档 7 | categories: 文章分类 8 | tagcloud: 标签云 9 | social: 社交按钮 10 | 11 | count: 12 | articles: 文章 13 | tags: 标签 14 | categories: 分类 15 | 16 | copyright: 17 | author: 本文作者 18 | permalink: 本文链接 -------------------------------------------------------------------------------- /packages/kira-hexo/languages/zh-HK.yml: -------------------------------------------------------------------------------- 1 | continue: 查看更多 2 | nav: 3 | home: 回到首頁 4 | 5 | search: 搜索 6 | archive: 文章歸檔 7 | categories: 文章分類 8 | tagcloud: 標籤雲 9 | 10 | count: 11 | articles: 文章 12 | tags: 標籤 13 | categories: 分類 14 | 15 | copyright: 16 | author: 本文作者 17 | permalink: 本文鏈接 -------------------------------------------------------------------------------- /packages/kira-hexo/languages/zh-TW.yml: -------------------------------------------------------------------------------- 1 | continue: 查看更多 2 | nav: 3 | home: 回到首頁 4 | 5 | search: 搜索 6 | archive: 文章歸檔 7 | categories: 文章分類 8 | tagcloud: 標籤雲 9 | 10 | count: 11 | articles: 文章 12 | tags: 標籤 13 | categories: 分類 14 | 15 | copyright: 16 | author: 本文作者 17 | permalink: 本文鏈接 -------------------------------------------------------------------------------- /packages/kira-hexo/layout/_widget/archive.ejs: -------------------------------------------------------------------------------- 1 | <% if (site.posts.length) { %> 2 |
3 |

4 | <%= __('archive') %> 5 |

6 |
7 | <%- list_archives({show_count: true, type: 'year'}) %> 8 |
9 |
10 | <% } %> 11 | -------------------------------------------------------------------------------- /packages/kira-hexo/layout/_widget/category.ejs: -------------------------------------------------------------------------------- 1 | <% if (site.categories.length) { %> 2 |
3 |

分类

4 |
5 |
    6 | <% 7 | let categories = Array(); 8 | let categories_counter = 0; 9 | 10 | site.categories.sort('name').each(function(item) { 11 | categories[categories_counter] = { 12 | name: item.name, 13 | path: item.path, 14 | length: item.length 15 | }; 16 | categories_counter++; 17 | }); 18 | %> 19 | <% 20 | // 筛选 删掉重复的 将重复的数量放到唯一的哪一个 21 | let counter; 22 | let isDisplayed = false; 23 | let displayed = Array(); 24 | let final_categories = Array(); 25 | 26 | for (counter = 0; counter < categories.length; counter++){ 27 | for (let i = 0; i < displayed.length; i++){ 28 | if (displayed[i].name === categories[counter].name){ 29 | for (let b = 0; b < final_categories.length; b++){ 30 | if (displayed[i].name === final_categories[b].name){ 31 | final_categories[b].length++; 32 | } 33 | } 34 | isDisplayed = true; 35 | break; 36 | }else{ 37 | isDisplayed = false; 38 | } 39 | } 40 | 41 | if (isDisplayed == false){ 42 | final_categories[final_categories.length] = { 43 | name: categories[counter].name, 44 | path: categories[counter].path, 45 | length: categories[counter].length 46 | } 47 | 48 | displayed[displayed.length] = { 49 | name: categories[counter].name, 50 | path: categories[counter].path, 51 | length: categories[counter].length 52 | } 53 | } 54 | } 55 | %> 56 | 57 | <% for (let u = 0; u < final_categories.length; u++) { %> 58 |
  • 59 | 60 | <%= final_categories[u].name %> 61 | 62 | <%= final_categories[u].length %> 63 |
  • 64 | <% } %> 65 |
66 |
67 |
68 | <% } %> -------------------------------------------------------------------------------- /packages/kira-hexo/layout/_widget/social.ejs: -------------------------------------------------------------------------------- 1 |
2 |
3 | <% for (name in theme.social) { %> 4 | 11 | 19 | 20 | <% } %> 21 |
22 |
23 | -------------------------------------------------------------------------------- /packages/kira-hexo/layout/_widget/tagcloud.ejs: -------------------------------------------------------------------------------- 1 | <% if (site.tags.length) { %> 2 |
3 |
4 | <%- tagcloud() %> 5 |
6 | <% if (theme.maxTagcloud) { %> 7 | 23 | <% } %> 24 |
25 | <% } %> 26 | -------------------------------------------------------------------------------- /packages/kira-hexo/layout/archives.ejs: -------------------------------------------------------------------------------- 1 |
2 |
3 | <%- list_tags({ 4 | show_count: true, 5 | style: "unordered list", 6 | class: "mdui-ripple ", 7 | separator: "" 8 | }) %> 9 |
10 |
11 | <% site.categories.sort('name').map(function(category) { %> 12 | <% let coverx = "" %> 13 | <% category.posts.sort('-date').map(function(post) { %> 14 | <% if (post.cover !== undefined && coverx === "") { %> 15 | <% coverx = post.cover %> 16 | <% } %> 17 | <% }) %> 18 | 19 |
20 |

<%= category.name %>

21 |
22 | <% }) %> 23 |
24 |
25 | <% function buildArchive(posts, year) { %> 26 |

<%= year %>

27 |
    28 | <% posts.sort('date',-1).each(post => { %> 29 |
  • <%= date(post.date, 'MM-DD') %><%- post.title %>
  • 30 | <% }) %> 31 |
32 | <% } %> 33 | <% 34 | if (!page.year) { 35 | let years = {}; 36 | let allpost = page.tag ? site.tags.findOne({name: page.tag}).posts : site.posts; 37 | allpost.each(post => years[post.date.year()] = null); 38 | for (let year of Object.keys(years).sort((a, b) => b - a)) { 39 | let posts = allpost.filter(p => p.date.year() == year); 40 | buildArchive(posts, year) 41 | } 42 | } else { 43 | let year = page.year; 44 | let posts = site.posts.filter(p => p.date.year() == year); 45 | buildArchive(posts, year) 46 | } 47 | %> 48 |
49 |
-------------------------------------------------------------------------------- /packages/kira-hexo/layout/components/comments/giscus.ejs: -------------------------------------------------------------------------------- 1 | <% if (theme.giscus.active) { %> 2 |
3 | <% if (theme.giscus.mapping === 'specific' || theme.giscus.mapping === 'number') { %> 4 | 21 | <% } else { %> 22 | 38 | <% } %> 39 | <% } %> -------------------------------------------------------------------------------- /packages/kira-hexo/layout/components/comments/gitalk.ejs: -------------------------------------------------------------------------------- 1 | <% if (theme.gitalk.active) { %> 2 | 3 |
4 | 5 | 17 | <% } %> 18 | -------------------------------------------------------------------------------- /packages/kira-hexo/layout/components/copyright.ejs: -------------------------------------------------------------------------------- 1 | <% if (page.hide_copyright !== true && theme.copyright || page.copyright) { %> 2 |
3 | <%- __('copyright.author') %>:<%= config.author %>
4 | <%- __('copyright.permalink') %>:<%- link_to(page.permalink, decodeURI(page.permalink), {external: true}) %>
5 | <% if (page.copyright) { %> 6 | <%- page.copyright %> 7 | <% } else { %> 8 | <%- theme.copyright %> 9 | <% } %> 10 |
11 | <% } %> 12 | -------------------------------------------------------------------------------- /packages/kira-hexo/layout/components/friends.ejs: -------------------------------------------------------------------------------- 1 | <% if (Array.isArray(theme.friends)) { %> 2 | <%- css("css/kira-friends") %> 3 |
4 | <% theme.friends.forEach(friend => { %> 5 | 13 | <% }) %> 14 |
15 |
16 | <% } %> 17 | -------------------------------------------------------------------------------- /packages/kira-hexo/layout/components/header.ejs: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /packages/kira-hexo/layout/components/kira-image.ejs: -------------------------------------------------------------------------------- 1 | <%- css("css/kira-image") %> 2 | <%- js('js/kira-image') %> 3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 | 11 |
12 |
13 | 14 |
15 |
16 |
17 |
18 |
19 |
20 | 21 |
22 |
23 |
24 |
25 | 26 |
27 |
28 | 29 |
30 |
31 | 32 |
33 |
34 |
35 |
36 | 37 |
38 |
39 |
40 |
41 |
-------------------------------------------------------------------------------- /packages/kira-hexo/layout/components/right-column.ejs: -------------------------------------------------------------------------------- 1 | 8 | -------------------------------------------------------------------------------- /packages/kira-hexo/layout/components/sidebar.ejs: -------------------------------------------------------------------------------- 1 | 58 | -------------------------------------------------------------------------------- /packages/kira-hexo/layout/friends.ejs: -------------------------------------------------------------------------------- 1 |
2 |
3 | <%- image_auto_lazyload(page.content) %> 4 | <%- partial('components/friends') %> 5 |
6 | <% if (page.comments) { %> 7 | 11 | <% } %> 12 |
13 | -------------------------------------------------------------------------------- /packages/kira-hexo/layout/index.ejs: -------------------------------------------------------------------------------- 1 | 58 | <% if (page.total > 1){ %> 59 |
60 | <%- paginator({ 61 | prev_text: '', 62 | next_text: '', 63 | escape: false 64 | }) %> 65 |
66 | <% } %> -------------------------------------------------------------------------------- /packages/kira-hexo/layout/layout.ejs: -------------------------------------------------------------------------------- 1 | 2 | 3 | lang="<%- config.language %>"<% } %>> 4 | 5 | 6 | 7 | 8 | <%- css("css/layout") %> 9 | <% var title=page.title; if (is_archive()){ title=__('archive'); if 10 | (is_month()){ title +=':' + page.year + '/' + page.month; } else if (is_year()){ title 11 | +=':' + page.year; } } else if (is_category()){ title=__('count.categories') + ':' + 12 | page.category; } else if (is_tag()){ title=__('count.tags') + ':' + page.tag; } %> 13 | <% if (title){ %> <%= title %> - <% } %> <%= config.title %> 14 | 15 | 16 | <%- css("lib/mdui/mdui.min") %> 17 | <%- js("lib/mdui/mdui.min") %> 18 | 19 | <%- js("lib/lazysizes") %> 20 | 21 | <%- js("lib/smooth-scrolling") %> 22 | 23 | <%- css("lib/highlight/atom-one-dark.min") %> 24 | <%- js("lib/highlight/highlight.min") %> 25 | 26 | <%- css("lib/iconfont/iconfont") %> 27 | <% if (theme.iconlib) { %> 28 | 29 | <% } %> 30 | 35 | <%- css("deps/css/APlayer.min") %> 36 | <% if (theme.customStyles) { %> 37 | <% theme.customStyles.forEach(function(customCss){ %> 38 | <%- css(customCss) %> 39 | <% }) %> 40 | <% } %> 41 | <%- js(["deps/js/APlayer.min", "deps/js/Meting.min"]) %> 42 | 43 | 44 | 45 |
49 | <%- include("components/header") %> 50 |
51 | <%- include("components/sidebar") %> 52 |
53 |
54 |
55 | <%- body %> 56 |
57 |
58 | <%- include("components/right-column") %> 59 |
60 | 61 | 62 | -------------------------------------------------------------------------------- /packages/kira-hexo/layout/post.ejs: -------------------------------------------------------------------------------- 1 | <%- partial('components/kira-image') %> 2 | <% if (theme.copyableCodeblock) { %> 3 | <%- css('css/kira-code-copy') %> 4 | <%- js('js/kira-code-copy') %> 5 | <% } %> 6 |
7 | 39 | 40 | <% if (!page.reprinted){ %> <%- partial('components/copyright') %> <% } %> <% if (page.layout == 41 | 'post') { %> 42 |
43 | 66 |
67 | <% } %> 68 | 86 | <% if (page.comments){ %> 87 | 91 | <% } %> 92 |
93 | -------------------------------------------------------------------------------- /packages/kira-hexo/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "hexo-theme-kira", 3 | "version": "1.4.9", 4 | "description": "A kirameki ✨ hexo theme for your blog.", 5 | "keywords": [ 6 | "hexo", 7 | "theme", 8 | "kira" 9 | ], 10 | "license": "Apache-2.0", 11 | "main": "index.js", 12 | "author": "德布罗煜", 13 | "repository": { 14 | "type": "git", 15 | "url": "git://github.com/ch1ny/kira-hexo.git" 16 | }, 17 | "bugs": { 18 | "url": "https://github.com/ch1ny/kira-hexo/issues" 19 | }, 20 | "homepage": "https://kira.host/hexo/", 21 | "dependencies": { 22 | "hexo-kira-toc": "1.4.9", 23 | "hexo-tag-aplayer": "^3.0.4", 24 | "hexo-wordcount": "^6.0.1" 25 | } 26 | } 27 | -------------------------------------------------------------------------------- /packages/kira-hexo/preview.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ch1ny/kira-hexo/0bba396b1c70e7ba6a9f5480194b067692bfeb3f/packages/kira-hexo/preview.png -------------------------------------------------------------------------------- /packages/kira-hexo/readme.md: -------------------------------------------------------------------------------- 1 | # Kira-Hexo 2 | 3 | [![npm version](https://badgen.net/npm/v/hexo-theme-kira)](https://www.npmjs.com/package/hexo-theme-kira) [![npm weekly download](https://badgen.net/npm/dw/hexo-theme-kira)](https://www.npmjs.com/package/hexo-theme-kira) [![github stars](https://badgen.net/github/stars/ch1ny/kira-hexo?color=orange)](https://github.com/ch1ny/kira-hexo/stargazers) 4 | 5 | Kira-Hexo,或者你也可以叫它 hexo-theme-kira。正如它的名字一样,是一款 KiraKira ✨ 让人眼前一亮的 hexo 风格化主题。 6 | 7 | ![](https://raw.githubusercontent.com/ch1ny/kira-hexo/master/preview.png) 8 | 9 | ## 快速开始 10 | 11 | 你可以在这里学习如何使用 Kira-Hexo 搭建你的风格化网站:[快速开始](https://kira.host/hexo/) 12 | 13 | ### 使用模板脚手架 14 | 15 | 您也可以使用我们提供的模板脚手架来快速生成基于 `kira-hexo` 主题的 hexo 博客: 16 | 17 | **With npm:** 18 | ```bash 19 | # 我其实更推荐您使用 yarn 或 pnpm ,而不是 npm 20 | npm create kira-hexo@latest my-blog 21 | ``` 22 | 23 | **With yarn:** 24 | ```bash 25 | yarn create kira-hexo my-blog 26 | ``` 27 | 28 | **With pnpm:** 29 | ```bash 30 | pnpm create kira-hexo my-blog 31 | ``` 32 | 33 | ## 代码仓库 34 | 35 | 你能够在 [GitHub](https://github.com/ch1ny/kira-hexo) 上直接获取项目的源代码,也能够在 [这里](https://github.com/ch1ny/kira-hexo/issues) 提出您的建议和意见。 36 | 37 | ## Credits 38 | 39 | > **声明**: 本仓库设计灵感来源于 [hexo-theme-nexmoe](https://github.com/theme-nexmoe/hexo-theme-nexmoe),欢迎各位支持原作者。 40 | -------------------------------------------------------------------------------- /packages/kira-hexo/scripts/tag/biliplayer.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | hexo.extend.tag.register( 4 | 'biliplayer', 5 | function (args) { 6 | const vid = args[0]; 7 | const page = args[1] ? args[1] : 1; 8 | const danmaku = args[2] ? 1 : 0; 9 | 10 | const isBv = /([a-z]|[A-Z])/.test(vid); 11 | 12 | return ``; 17 | }, 18 | { ends: false } 19 | ); 20 | -------------------------------------------------------------------------------- /packages/kira-hexo/scripts/tag/codepen.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | hexo.extend.tag.register( 4 | 'pen', 5 | function (args) { 6 | const url = args[0]; 7 | return `在 Codepen 上尝试`; 8 | }, 9 | { ends: false } 10 | ); 11 | -------------------------------------------------------------------------------- /packages/kira-hexo/scripts/tag/kira-player.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | hexo.extend.tag.register( 4 | 'krplayer', 5 | function (args, content) { 6 | return `
${content}
`; 7 | }, 8 | { ends: true } 9 | ); 10 | -------------------------------------------------------------------------------- /packages/kira-hexo/scripts/tag/meting.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | const extractOptionValue = (pair) => { 4 | return pair.slice(pair.indexOf(':') + 1); 5 | }; 6 | 7 | const METING_TAG_OPTION = { 8 | id: '', 9 | server: '', 10 | type: '', 11 | mode: 'circulation', 12 | autoplay: false, 13 | mutex: true, 14 | listmaxheight: '340px', 15 | preload: 'auto', 16 | theme: '#ad7a86', 17 | }; 18 | 19 | function parse(options) { 20 | let settings = Object.assign({}, METING_TAG_OPTION); 21 | [settings.id, settings.server, settings.type] = options; 22 | const optionalArgs = options.slice(3); 23 | optionalArgs.forEach((option, index) => { 24 | switch (true) { 25 | case option === 'autoplay': 26 | settings.autoplay = true; 27 | break; 28 | case option === 'fixed': 29 | settings.fixed = true; 30 | break; 31 | case option === 'mini': 32 | settings.mini = true; 33 | break; 34 | case option.startsWith('loop:'): 35 | settings.loop = extractOptionValue(option); 36 | break; 37 | case option.startsWith('order:'): 38 | settings.order = extractOptionValue(option); 39 | break; 40 | case option.startsWith('volume:'): 41 | settings.volume = extractOptionValue(option); 42 | break; 43 | case option.startsWith('lrctype:'): 44 | settings.lrctype = extractOptionValue(option); 45 | break; 46 | case option === 'listfolded': 47 | settings.listfolded = true; 48 | break; 49 | case option.startsWith('storagename:'): 50 | settings.storagename = extractOptionValue(option); 51 | break; 52 | case option.startsWith('mutex:'): 53 | settings.mutex = extractOptionValue(option) === 'true'; 54 | break; 55 | case option.startsWith('mode:'): 56 | settings.mode = extractOptionValue(option); 57 | break; 58 | case option.startsWith('listmaxheight:'): 59 | settings.listmaxheight = extractOptionValue(option); 60 | break; 61 | case option.startsWith('preload:'): 62 | settings.preload = extractOptionValue(option); 63 | break; 64 | case option.startsWith('theme:'): 65 | settings.theme = extractOptionValue(option); 66 | break; 67 | default: 68 | throwError(`Unrecognized tag argument(${index + 1}): ${value}`); 69 | } 70 | }); 71 | return settings; 72 | } 73 | 74 | hexo.extend.tag.register('meting', function (args) { 75 | const { id, server, type, mode, autoplay, mutex, listmaxheight, preload, theme } = parse(args); 76 | 77 | return ` 87 | `; 88 | }); 89 | -------------------------------------------------------------------------------- /packages/kira-hexo/scripts/utils/image_auto_lazyload.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | function imageAutoLazyloadHelper(content) { 4 | var str = content.replace( 5 | //gi, 6 | '$2' 7 | ); 8 | str = str.replace( 9 | /src="images\//g, 10 | 'src="https://cdn.jsdelivr.net/gh/ch1ny/ch1ny.github.io/images/' 11 | ); 12 | str = str.replace( 13 | /\.\.\/\.\.\/images\//g, 14 | 'https://cdn.jsdelivr.net/gh/ch1ny/ch1ny.github.io/images/' 15 | ); 16 | return str; 17 | } 18 | 19 | hexo.extend.helper.register('image_auto_lazyload', imageAutoLazyloadHelper); 20 | -------------------------------------------------------------------------------- /packages/kira-hexo/source/css/archive.styl: -------------------------------------------------------------------------------- 1 | .kira-archives { 2 | .tagcloud { 3 | margin-bottom: 13px; 4 | font-size: 0; 5 | 6 | a { 7 | border-radius: 15px; 8 | padding: 6px 12px; 9 | font-size: 15px !important; 10 | display: inline-block; 11 | margin-bottom: 7px; 12 | margin-right: 7px; 13 | 14 | &::before { 15 | content: '# '; 16 | } 17 | 18 | span::before { 19 | content: ' '; 20 | } 21 | } 22 | } 23 | 24 | .categories { 25 | margin-bottom: 12px; 26 | font-size: 0; 27 | display: grid; 28 | grid-template-columns: repeat(3, 98% / 3); 29 | grid-column-gap: 1%; 30 | grid-row-gap: 12px; 31 | 32 | a { 33 | border-radius: 12px; 34 | font-size: 16px; 35 | display: inline-block; 36 | height: 156px; 37 | width: 100%; 38 | position: relative; 39 | 40 | &:before { 41 | top: 0; 42 | left: 0; 43 | content: ''; 44 | background-color: rgba(0, 0, 0, 0.4); 45 | width: 100%; 46 | height: 100%; 47 | position: absolute; 48 | z-index: 1; 49 | } 50 | 51 | .bg { 52 | background-size: cover; 53 | background-position: center center; 54 | top: 0; 55 | left: 0; 56 | width: 100%; 57 | height: 100%; 58 | position: absolute; 59 | opacity: 0.8; 60 | } 61 | 62 | h1 { 63 | margin: 20px; 64 | position: absolute; 65 | bottom: 0; 66 | left: 0; 67 | z-index: 2; 68 | } 69 | 70 | span { 71 | margin-top: 5px; 72 | display: block; 73 | 74 | &::after { 75 | content: ' Articles'; 76 | } 77 | } 78 | } 79 | } 80 | 81 | article > * { 82 | &:first-child { 83 | margin-top: 0; 84 | } 85 | 86 | &:last-child { 87 | margin-bottom: 0; 88 | } 89 | } 90 | } 91 | -------------------------------------------------------------------------------- /packages/kira-hexo/source/css/color.styl: -------------------------------------------------------------------------------- 1 | // 常规配色 2 | $color1 = rgb(hexo-config('color.first.r'), hexo-config('color.first.g'), hexo-config('color.first.b')); 3 | $color2 = rgb(hexo-config('color.second.r'), hexo-config('color.second.g'), hexo-config('color.second.b')); 4 | $color3 = rgb(hexo-config('color.third.r'), hexo-config('color.third.g'), hexo-config('color.third.b')); 5 | $color4 = rgb(hexo-config('color.fourth.r'), hexo-config('color.fourth.g'), hexo-config('color.fourth.b')); 6 | $color5 = rgb(hexo-config('color.fifth.r'), hexo-config('color.fifth.g'), hexo-config('color.fifth.b')); 7 | $color6 = rgb(hexo-config('color.sixth.r'), hexo-config('color.sixth.g'), hexo-config('color.sixth.b')); 8 | $color7 = rgb(hexo-config('color.seventh.r'), hexo-config('color.seventh.g'), hexo-config('color.seventh.b')); 9 | // kira-hexo-rainbow 背景配色 10 | $krlbgc1 = rgba($color1, 0.25); 11 | $krlbgc2 = rgba($color2, 0.25); 12 | $krlbgc3 = rgba($color3 0.25); 13 | $krlbgc4 = rgba($color4, 0.25); 14 | $krlbgc5 = rgba($color5, 0.25); 15 | $krlbgc6 = rgba($color6, 0.25); 16 | $krlbgc7 = rgba($color7, 0.25); 17 | // kira-hexo-rainbow-fill 背景配色 18 | $krdbgc1 = rgba($color1, 0.85); 19 | $krdbgc2 = rgba($color2, 0.85); 20 | $krdbgc3 = rgba($color3 0.85); 21 | $krdbgc4 = rgba($color4, 0.85); 22 | $krdbgc5 = rgba($color5, 0.85); 23 | $krdbgc6 = rgba($color6, 0.85); 24 | $krdbgc7 = rgba($color7, 0.85); 25 | -------------------------------------------------------------------------------- /packages/kira-hexo/source/css/constants.styl: -------------------------------------------------------------------------------- 1 | $gutter = 25px; 2 | $radius = 13px; 3 | 4 | @import 'color.styl'; 5 | -------------------------------------------------------------------------------- /packages/kira-hexo/source/css/content.styl: -------------------------------------------------------------------------------- 1 | .kira-content { 2 | position: relative; 3 | max-width: 860px; 4 | height: fit-content; 5 | flex-grow: 1; 6 | overflow: auto; 7 | scrollbar-width: none; 8 | box-shadow: 0 0 1rem rgba(138, 151, 174, 0.4); 9 | margin-top: 2vh; 10 | margin-bottom: 2vh; 11 | 12 | .kira-main-content { 13 | position: relative; 14 | background-color: #fff; 15 | max-width: 100%; 16 | padding: 25px; 17 | min-height: 96vh; 18 | 19 | .kira-page-nav { 20 | list-style: none; 21 | text-align: center; 22 | display: flex; 23 | color: #ddd; 24 | background-color: #f5f6f5; 25 | border-radius: $radius; 26 | justify-content: center; 27 | 28 | .page-number { 29 | transition: 300ms; 30 | margin-inline: 10px; 31 | } 32 | 33 | .current { 34 | color: #fff; 35 | background: $color1; 36 | opacity: 0.9; 37 | box-shadow: 0 2px 12px $color1; 38 | } 39 | 40 | a:not(.current):hover { 41 | background-color: rgba(155, 155, 155, 0.3); 42 | } 43 | } 44 | 45 | .kira-page-nav > * { 46 | color: #999; 47 | border-radius: $radius; 48 | width: 35px; 49 | height: 35px; 50 | line-height: 35px; 51 | float: left; 52 | } 53 | 54 | .kira-posts { 55 | position: relative; 56 | 57 | .kira-post { 58 | max-width: 100%; 59 | transition: 300ms; 60 | padding: 10px; 61 | border-radius: 1rem; 62 | 63 | article .aplayer { 64 | margin: 6px 0 0 0 !important; 65 | } 66 | } 67 | 68 | .kira-post:hover { 69 | background-color: rgba(170, 177, 183, 0.1); 70 | } 71 | 72 | .kira-post-meta { 73 | margin: 10px 0 0 0 !important; 74 | } 75 | 76 | .kira-post:last-child { 77 | margin-bottom: $gutter; 78 | } 79 | 80 | .kira-hr { 81 | border-bottom: 1px solid rgba(135, 135, 135, 0.3); 82 | height: 0; 83 | margin-block: 12px; 84 | } 85 | } 86 | } 87 | } 88 | 89 | .kira-content::-webkit-scrollbar { 90 | display: none; 91 | } 92 | -------------------------------------------------------------------------------- /packages/kira-hexo/source/css/kira-code-copy.styl: -------------------------------------------------------------------------------- 1 | .highlight { 2 | position: relative; 3 | 4 | & > .kira-codeblock-copy-wrapper { 5 | position: absolute; 6 | width: 30px; 7 | height: 30px; 8 | right: 12px; 9 | top: 12px; 10 | border-radius: 4px; 11 | z-index: 10; 12 | background-color: #1e1e20; 13 | background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' fill='none' height='20' width='20' stroke='rgba(128,128,128,1)' stroke-width='2' viewBox='0 0 24 24'%3E%3Cpath stroke-linecap='round' stroke-linejoin='round' d='M9 5H7a2 2 0 0 0-2 2v12a2 2 0 0 0 2 2h10a2 2 0 0 0 2-2V7a2 2 0 0 0-2-2h-2M9 5a2 2 0 0 0 2 2h2a2 2 0 0 0 2-2M9 5a2 2 0 0 1 2-2h2a2 2 0 0 1 2 2'/%3E%3C/svg%3E"); 14 | background-position: 50%; 15 | background-size: 20px; 16 | background-repeat: no-repeat; 17 | cursor: pointer; 18 | opacity: 0; 19 | transition: opacity 0.25s; 20 | 21 | &-copied { 22 | opacity: 1; 23 | border-radius: 0 4px 4px 0; 24 | background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' fill='none' height='20' width='20' stroke='rgba(128,128,128,1)' stroke-width='2' viewBox='0 0 24 24'%3E%3Cpath stroke-linecap='round' stroke-linejoin='round' d='M9 5H7a2 2 0 0 0-2 2v12a2 2 0 0 0 2 2h10a2 2 0 0 0 2-2V7a2 2 0 0 0-2-2h-2M9 5a2 2 0 0 0 2 2h2a2 2 0 0 0 2-2M9 5a2 2 0 0 1 2-2h2a2 2 0 0 1 2 2m-6 9 2 2 4-4'/%3E%3C/svg%3E"); 25 | 26 | &::before { 27 | position: relative; 28 | left: -58px; 29 | display: flex; 30 | justify-content: center; 31 | align-items: center; 32 | border-radius: 4px 0 0 4px; 33 | width: 48px; 34 | height: 30px; 35 | padding-left: 10px; 36 | text-align: center; 37 | font-size: 12px; 38 | font-weight: 500; 39 | color: rgba(235, 235, 245, 0.6); 40 | background-color: #1e1e20; 41 | white-space: nowrap; 42 | content: 'Copied'; 43 | } 44 | } 45 | } 46 | 47 | &:hover > .kira-codeblock-copy-wrapper { 48 | opacity: 1; 49 | } 50 | } 51 | -------------------------------------------------------------------------------- /packages/kira-hexo/source/css/kira-friends.styl: -------------------------------------------------------------------------------- 1 | @import 'constants.styl'; 2 | 3 | .kira-friends-friendWrapper { 4 | flex: 0 0 25%; 5 | max-width: 25%; 6 | position: relative; 7 | user-select: none; 8 | 9 | & > a { 10 | position: relative; 11 | color: unset; 12 | display: flex; 13 | justify-content: center; 14 | align-items: center; 15 | padding: 7.5px; 16 | border-radius: 16px; 17 | overflow: hidden; 18 | transition: all 0.5s ease; 19 | 20 | &:hover, &:focus { 21 | text-decoration: none; 22 | color: unset; 23 | } 24 | 25 | &::before { 26 | content: ""; 27 | position: absolute; 28 | background: $color1; 29 | width: 100%; 30 | height: 100%; 31 | border-radius: 16px; 32 | transition: all 0.5s ease; 33 | transform: scale(0, 0); 34 | } 35 | 36 | & > .kira-friends-avatarWrapper { 37 | position: relative; 38 | z-index: 1; 39 | display: flex; 40 | justify-content: center; 41 | align-items: center; 42 | 43 | & > img { 44 | transition: all 0.5s ease !important; 45 | border-radius: 50%; 46 | } 47 | 48 | & > img, & > img:hover { 49 | border-radius: 50% !important; 50 | box-shadow: none !important; 51 | } 52 | } 53 | 54 | & > .kira-friends-blogName { 55 | display: flex; 56 | justify-content: center; 57 | align-items: center; 58 | font-size: 16px; 59 | font-weight: bold; 60 | position: relative; 61 | z-index: 1; 62 | transition: all 0.2s ease; 63 | } 64 | 65 | &:hover { 66 | box-shadow: 0 0 16px $krdbgc1; 67 | 68 | &::before { 69 | transform: scale(1, 1); 70 | } 71 | 72 | & > .kira-friends-avatarWrapper > img { 73 | transform: rotateZ(360deg); 74 | } 75 | 76 | & > .kira-friends-blogName { 77 | color: #fff; 78 | } 79 | } 80 | } 81 | } 82 | -------------------------------------------------------------------------------- /packages/kira-hexo/source/css/kira-image.styl: -------------------------------------------------------------------------------- 1 | .kira-image { 2 | position: fixed; 3 | left: 0; 4 | top: 0; 5 | width: 100vw; 6 | height: 100vh; 7 | pointer-events: none; 8 | z-index: 20; 9 | 10 | &-modal { 11 | position: absolute; 12 | top: 0; 13 | left: 0; 14 | width: 100%; 15 | height: 100%; 16 | background-color: rgba(0, 0, 0, 0); 17 | display: flex; 18 | flex-direction: column; 19 | transition: all 0.2s ease; 20 | backdrop-filter: blur(0px); 21 | 22 | * { 23 | transition: all 0.2s ease; 24 | } 25 | 26 | .kira-image-header { 27 | width: 100%; 28 | height: 64px; 29 | background-image: linear-gradient(to bottom, rgba(0, 0, 0, 0.5) 50%, rgba(0, 0, 0, 0) 100%); 30 | display: flex; 31 | align-items: center; 32 | color: white; 33 | z-index: 21; 34 | 35 | .kira-image-counter { 36 | height: 100%; 37 | display: flex; 38 | justify-content: center; 39 | align-items: center; 40 | padding: 0 10px; 41 | font-size: 18px; 42 | font-variant-numeric: tabular-nums; 43 | } 44 | 45 | .kira-image-operation { 46 | margin: 0 20px 0 auto; 47 | height: 100%; 48 | position: relative; 49 | display: flex; 50 | justify-content: center; 51 | align-items: center; 52 | 53 | &-button { 54 | width: 32px; 55 | height: 32px; 56 | font-size: 16px; 57 | cursor: pointer; 58 | display: flex; 59 | justify-content: center; 60 | align-items: center; 61 | 62 | &:hover { 63 | background-color: rgba(143, 141, 144, 0.45); 64 | } 65 | } 66 | } 67 | } 68 | 69 | .kira-image-container { 70 | width: 100%; 71 | height: calc(100% - 64px); 72 | display: flex; 73 | pointer-events: none; 74 | 75 | div[class^='kira-image-'][class$='-button-panel'] { 76 | width: 86px; 77 | display: flex; 78 | justify-content: center; 79 | align-items: center; 80 | z-index: 21; 81 | 82 | .kira-image-exchange-button { 83 | width: 56px; 84 | height: 56px; 85 | border-radius: 50%; 86 | color: white; 87 | pointer-events: auto; 88 | display: flex; 89 | justify-content: center; 90 | align-items: center; 91 | 92 | i { 93 | font-size: 24px; 94 | text-shadow: 0 0 3px #000; 95 | } 96 | } 97 | } 98 | 99 | .kira-image-list { 100 | flex-grow: 1; 101 | display: flex; 102 | position: relative; 103 | animation-duration: 0.2s; 104 | animation-fill-mode: forwards; 105 | 106 | div { 107 | position: absolute; 108 | width: 100%; 109 | height: 100%; 110 | display: flex; 111 | justify-content: center; 112 | align-items: center; 113 | 114 | img { 115 | max-width: calc(100% - 12px); 116 | max-height: calc(100% - 24px); 117 | user-select: none; 118 | } 119 | } 120 | 121 | .kira-image-prev { 122 | transform: translateX(-100vw); 123 | } 124 | 125 | .kira-image-next { 126 | transform: translateX(100vw); 127 | } 128 | 129 | [class^='kira-image-'] > img { 130 | cursor: zoom-in; 131 | -webkit-user-drag: none; 132 | transition: scale 0.2s ease, translate 0s; 133 | } 134 | 135 | .kira-image-now img.zoom { 136 | cursor: grab; 137 | scale: 3; 138 | } 139 | } 140 | } 141 | 142 | &.visible { 143 | pointer-events: auto; 144 | background-color: rgba(0, 0, 0, 0.6); 145 | backdrop-filter: blur(2px); 146 | 147 | .kira-image-container { 148 | div[class^='kira-image-'][class$='-button-panel'] .kira-image-exchange-button:hover { 149 | cursor: pointer; 150 | background-color: rgba(75, 75, 75, 0.4); 151 | } 152 | 153 | .kira-image-list { 154 | div > img { 155 | pointer-events: auto; 156 | } 157 | } 158 | } 159 | } 160 | 161 | &:not(.visible) * { 162 | opacity: 0; 163 | pointer-events: none; 164 | } 165 | } 166 | } 167 | 168 | @keyframes kira-image-to-next { 169 | from { 170 | transform: translateX(0); 171 | } 172 | to { 173 | transform: translateX(-100vw); 174 | } 175 | } 176 | 177 | @keyframes kira-image-to-prev { 178 | from { 179 | transform: translateX(0); 180 | } 181 | to { 182 | transform: translateX(100vw); 183 | } 184 | } 185 | -------------------------------------------------------------------------------- /packages/kira-hexo/source/css/layout.styl: -------------------------------------------------------------------------------- 1 | @import 'constants.styl'; 2 | 3 | body { 4 | width: 100%; 5 | margin: auto !important; 6 | height: 100vh; 7 | position: absolute; 8 | left: 0; 9 | top: 0; 10 | } 11 | 12 | * { 13 | scrollbar-width: none; 14 | outline: none; 15 | 16 | &::selection { 17 | background: $color1; 18 | color: #fff; 19 | text-shadow: none; 20 | } 21 | } 22 | 23 | ::-webkit-scrollbar { 24 | display: none; 25 | } 26 | 27 | a { 28 | text-decoration: none; 29 | } 30 | 31 | img::selection { 32 | background: $krlbgc2; 33 | } 34 | 35 | figure.highlight table tbody tr td { 36 | &.gutter { 37 | user-select: none; 38 | } 39 | 40 | &.code pre *::selection { 41 | background: $color2; 42 | } 43 | } 44 | 45 | .kira-background { 46 | opacity: 0.2; 47 | background-size: cover; 48 | height: 100vh; 49 | width: 100%; 50 | position: fixed; 51 | top: 0; 52 | left: 0; 53 | z-index: -1; 54 | } 55 | 56 | .kira-header { 57 | height: 0; 58 | display: none; 59 | } 60 | 61 | #kira-top-header { 62 | position: absolute; 63 | width: 100%; 64 | height: 0; 65 | left: 0; 66 | top: -2vh; 67 | } 68 | 69 | .kira-body { 70 | display: flex; 71 | justify-content: center; 72 | } 73 | 74 | .kira-rainbow { 75 | a:nth-child(7n + 1) { 76 | background-color: $krlbgc1; 77 | color: $color1; 78 | } 79 | 80 | a:nth-child(7n + 2) { 81 | background-color: $krlbgc2; 82 | color: $color2; 83 | } 84 | 85 | a:nth-child(7n + 3) { 86 | background-color: $krlbgc3; 87 | color: $color3; 88 | } 89 | 90 | a:nth-child(7n + 4) { 91 | background-color: $krlbgc4; 92 | color: $color4; 93 | } 94 | 95 | a:nth-child(7n + 5) { 96 | background-color: $krlbgc5; 97 | color: $color5; 98 | } 99 | 100 | a:nth-child(7n + 6) { 101 | background-color: $krlbgc6; 102 | color: $color6; 103 | } 104 | 105 | a:nth-child(7n + 7) { 106 | background-color: $krlbgc7; 107 | color: $color7; 108 | } 109 | } 110 | 111 | .kira-rainbow-fill { 112 | a { 113 | color: #fff; 114 | } 115 | } 116 | 117 | @import 'article.styl'; 118 | 119 | @import 'sidebar.styl'; 120 | @import 'content.styl'; 121 | @import 'right-column.styl'; 122 | @import 'post.styl'; 123 | @import 'archive.styl'; 124 | 125 | @import 'media.styl'; 126 | -------------------------------------------------------------------------------- /packages/kira-hexo/source/css/media.styl: -------------------------------------------------------------------------------- 1 | // 响应式布局 2 | @media (max-width: 1180px) { 3 | .kira-sidebar { 4 | left: 0; 5 | } 6 | 7 | .kira-content { 8 | margin-right: auto; 9 | } 10 | 11 | .kira-right-column { 12 | position: fixed; 13 | top: 0; 14 | right: 0; 15 | 16 | .kira-backtotop { 17 | background-color: rgba(255, 255, 255, 1); 18 | } 19 | } 20 | } 21 | 22 | @media (max-width: 1120px) { 23 | .kira-body::-webkit-scrollbar { 24 | width: 0; 25 | } 26 | } 27 | 28 | @media (max-width: 1000px) { 29 | body { 30 | height: fit-content; 31 | overflow: auto; 32 | 33 | .kira-header { 34 | height: 60px; 35 | padding: 10px; 36 | display: flex; 37 | align-items: center; 38 | justify-content: space-between; 39 | position: relative; 40 | z-index: 4; 41 | 42 | a { 43 | width: 45px; 44 | height: 45px; 45 | text-align: center; 46 | border-radius: 50%; 47 | transition: all 0.5s ease; 48 | 49 | i { 50 | font-size: 25px; 51 | line-height: 45px; 52 | } 53 | img { 54 | width: 100%; 55 | height: 100%; 56 | border-radius: 50%; 57 | } 58 | 59 | &:hover { 60 | background-color: rgba(0, 0, 0, 0.16); 61 | } 62 | } 63 | } 64 | 65 | .kira-body { 66 | height: fit-content; 67 | overflow: visible; 68 | 69 | .kira-sidebar { 70 | position: fixed; 71 | top: 0; 72 | left: 0; 73 | z-index: 16; 74 | transform: translateX(-100%); 75 | background-color: white; 76 | 77 | &.show { 78 | transform: translateX(0%); 79 | width: calc(100% - 56px); 80 | } 81 | 82 | &-modal.show { 83 | pointer-events: auto; 84 | background-color: rgba(0, 0, 0, 0.4); 85 | } 86 | } 87 | 88 | .kira-content { 89 | #kira-top-header { 90 | top: calc(-2vh - 80px); 91 | } 92 | 93 | margin-right: unset; 94 | max-width: 100vw; 95 | margin-top: 0; 96 | } 97 | } 98 | } 99 | body::-webkit-scrollbar { 100 | width: 0; 101 | } 102 | } 103 | 104 | @media (max-width: 756px) { 105 | .kira-archives .categories { 106 | grid-template-columns: repeat(2, 98% / 2); 107 | grid-column-gap: 2%; 108 | } 109 | } 110 | 111 | @media (max-width: 400px) { 112 | .kira-archives .categories { 113 | grid-template-columns: repeat(1, 100%); 114 | } 115 | } 116 | -------------------------------------------------------------------------------- /packages/kira-hexo/source/css/post.styl: -------------------------------------------------------------------------------- 1 | @import 'constants.styl'; 2 | 3 | .kira-post { 4 | &-cover { 5 | width: 100%; 6 | padding-bottom: 40%; 7 | position: relative; 8 | overflow: hidden; 9 | border-radius: 16px; 10 | min-height: 95px; 11 | background-color: #eee; 12 | 13 | img { 14 | display: block; 15 | opacity: 0; 16 | transition: opacity 400ms ease-out; 17 | position: absolute; 18 | left: 0; 19 | top: 0; 20 | object-fit: cover; 21 | width: 100%; 22 | height: 100%; 23 | 24 | &.lazyloaded { 25 | opacity: 1; 26 | } 27 | } 28 | 29 | h1 { 30 | color: #fff; 31 | font-size: 2.5em; 32 | font-weight: normal; 33 | margin: 0; 34 | margin-top: 10px; 35 | padding-left: 1px; 36 | position: absolute; 37 | bottom: 0; 38 | width: 100%; 39 | box-sizing: border-box; 40 | text-transform: none; 41 | z-index: 1; 42 | margin: 0; 43 | padding: $gutter; 44 | 45 | &::after { 46 | background-image: -moz-linear-gradient( 47 | to top, 48 | rgba(16, 16, 16, 0.35) 25%, 49 | rgba(16, 16, 16, 0) 100% 50 | ); 51 | background-image: -webkit-linear-gradient( 52 | to top, 53 | rgba(16, 16, 16, 0.35) 25%, 54 | rgba(16, 16, 16, 0) 100% 55 | ); 56 | background-image: -ms-linear-gradient( 57 | to top, 58 | rgba(16, 16, 16, 0.35) 25%, 59 | rgba(16, 16, 16, 0) 100% 60 | ); 61 | background-image: linear-gradient( 62 | to top, 63 | rgba(16, 16, 16, 0.35) 25%, 64 | rgba(16, 16, 16, 0) 100% 65 | ); 66 | -moz-pointer-events: none; 67 | -webkit-pointer-events: none; 68 | -ms-pointer-events: none; 69 | pointer-events: none; 70 | background-size: cover; 71 | content: ''; 72 | display: block; 73 | height: 100%; 74 | left: 0; 75 | position: absolute; 76 | bottom: 0; 77 | width: 100%; 78 | z-index: -1; 79 | } 80 | } 81 | } 82 | 83 | .kira-post-meta { 84 | margin: $gutter 0px; 85 | font-size: 0; 86 | 87 | a { 88 | border-radius: 20px; 89 | padding: 10px 18px; 90 | font-size: 14px; 91 | display: inline-block; 92 | margin-bottom: 5px; 93 | margin-right: 10px; 94 | text-decoration: none; 95 | 96 | .kirafont { 97 | font-size: 14px; 98 | } 99 | } 100 | 101 | a::before, 102 | i::before { 103 | margin-right: 5px; 104 | } 105 | } 106 | 107 | .kira-post-copyright { 108 | margin: 0 -25px; 109 | margin-bottom: 25px; 110 | padding: 25px; 111 | color: #191919; 112 | background-color: #fafafa; 113 | line-height: 1.5em; 114 | position: relative; 115 | overflow: hidden; 116 | 117 | a { 118 | color: $color1; 119 | } 120 | } 121 | 122 | .kira-post-copyright::after { 123 | position: absolute; 124 | background: url("data:image/svg+xml;charset=utf-8,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 496 512'%3E%3Cpath fill='%234a4a4a' d='M245.8 214.9l-33.2 17.3c-9.4-19.6-25.2-20-27.4-20-22.2 0-33.3 14.6-33.3 43.9 0 23.5 9.2 43.8 33.3 43.8 14.4 0 24.6-7 30.5-21.3l30.6 15.5a73.2 73.2 0 01-65.1 39c-22.6 0-74-10.3-74-77 0-58.7 43-77 72.6-77 30.8-.1 52.7 11.9 66 35.8zm143 0l-32.7 17.3c-9.5-19.8-25.7-20-27.9-20-22.1 0-33.2 14.6-33.2 43.9 0 23.5 9.2 43.8 33.2 43.8 14.5 0 24.7-7 30.5-21.3l31 15.5c-2 3.8-21.3 39-65 39-22.7 0-74-9.9-74-77 0-58.7 43-77 72.6-77C354 179 376 191 389 214.8zM247.7 8C104.7 8 0 123 0 256c0 138.4 113.6 248 247.6 248C377.5 504 496 403 496 256 496 118 389.4 8 247.6 8zm.8 450.8c-112.5 0-203.7-93-203.7-202.8 0-105.5 85.5-203.3 203.8-203.3A201.7 201.7 0 01451.3 256c0 121.7-99.7 202.9-202.9 202.9z'/%3E%3C/svg%3E"); 125 | content: ' '; 126 | height: 160px; 127 | width: 160px; 128 | right: -30px; 129 | top: -45px; 130 | opacity: 0.1; 131 | } 132 | 133 | .kira-post-nav { 134 | width: 100%; 135 | height: 2em; 136 | background-color: #ffffff; 137 | margin-top: 0; 138 | user-select: none; 139 | 140 | .post-nav { 141 | .old { 142 | float: left; 143 | } 144 | 145 | .new { 146 | float: right; 147 | } 148 | 149 | div a { 150 | transition: 0.2s; 151 | padding: 0.2em; 152 | color: $color1; 153 | border-bottom: 1px solid $krdbgc1; 154 | 155 | &:hover { 156 | text-shadow: 0px 0px 5px $krlbgc1; 157 | text-decoration: none; 158 | border-bottom: 1px solid $color1; 159 | } 160 | } 161 | } 162 | } 163 | 164 | .kira-post-footer { 165 | background-color: #f5f6f5; 166 | padding: $gutter; 167 | margin: -($gutter); 168 | margin-top: 0; 169 | } 170 | } 171 | -------------------------------------------------------------------------------- /packages/kira-hexo/source/css/right-column.styl: -------------------------------------------------------------------------------- 1 | .kira-right-column { 2 | width: 80px; 3 | height: 100vh; 4 | display: flex; 5 | flex-direction: column; 6 | align-items: center; 7 | position: sticky; 8 | pointer-events: none; 9 | top: 0; 10 | z-index: 10; 11 | 12 | .kira-backtotop { 13 | bottom: 20px; 14 | color: rgb(85, 85, 85); 15 | background-color: rgba(255, 255, 255, 0.501); 16 | border-radius: 50%; 17 | margin-top: auto; 18 | margin-bottom: 15px; 19 | transition: 500ms; 20 | pointer-events: all; 21 | 22 | i { 23 | font-size: 22px; 24 | } 25 | } 26 | } 27 | -------------------------------------------------------------------------------- /packages/kira-hexo/source/css/sidebar.styl: -------------------------------------------------------------------------------- 1 | @import 'constants.styl'; 2 | 3 | .kira-sidebar { 4 | scrollbar-width: none; 5 | max-width: 240px; 6 | user-select: none; 7 | max-height: 100vh; 8 | overflow: auto; 9 | position: sticky; 10 | top: 0; 11 | flex-shrink: 0; 12 | transition: all 0.3s ease-out; 13 | 14 | .kira-avatar { 15 | margin: 25px; 16 | box-shadow: 0 0 2rem rgba($color1, 0.2); 17 | 18 | a { 19 | padding-bottom: 100%; 20 | height: 0; 21 | display: block; 22 | } 23 | 24 | &, 25 | & img { 26 | max-width: 100%; 27 | border-radius: 50%; 28 | transition: transform 1.5s ease-out; 29 | } 30 | } 31 | 32 | .kira-count { 33 | display: flex; 34 | 35 | div { 36 | -webkit-box-flex: 1; 37 | -ms-flex: 1; 38 | flex: 1; 39 | text-align: center; 40 | color: #a3a8ae; 41 | 42 | span { 43 | color: #363636; 44 | display: block; 45 | } 46 | } 47 | } 48 | 49 | .kira-list { 50 | padding: 8px 20px; 51 | 52 | &-item { 53 | padding: 0 36px; 54 | color: #9ca2a8; 55 | border-radius: $radius; 56 | margin-bottom: 10px; 57 | text-align: center; 58 | transition: none !important; 59 | display: flex; 60 | align-items: center; 61 | 62 | &:hover { 63 | background-color: rgba(0, 0, 0, 0.08); 64 | } 65 | 66 | &.true { 67 | opacity: 0.9; 68 | background: $color1; 69 | box-shadow: 0 2px 12px $color1; 70 | 71 | &, 72 | & i { 73 | color: #fff; 74 | } 75 | } 76 | 77 | i { 78 | font-size: 22px; 79 | color: #9ca2a8; 80 | } 81 | 82 | &-content { 83 | margin-left: 0px; 84 | padding-top: 14px; 85 | padding-bottom: 14px; 86 | font-size: 16px; 87 | font-weight: 400; 88 | line-height: 20px; 89 | -webkit-box-flex: 1; 90 | -webkit-flex-grow: 1; 91 | -ms-flex-positive: 1; 92 | flex-grow: 1; 93 | } 94 | 95 | .mdui-list-item-content { 96 | margin-left: 0px; 97 | } 98 | } 99 | } 100 | 101 | .kira-social { 102 | padding: 12px; 103 | font-size: 0; 104 | 105 | a { 106 | width: 36px; 107 | height: 36px; 108 | line-height: 36px; 109 | margin: 4px; 110 | border-radius: 100%; 111 | display: inline-block; 112 | text-align: center; 113 | color: #606266; 114 | } 115 | } 116 | 117 | .kira-widget-wrap { 118 | box-shadow: 0 0 1rem rgba(161, 177, 204, 0.4); 119 | background-color: #fff; 120 | margin: 20px; 121 | border-radius: $radius; 122 | overflow: hidden; 123 | white-space: normal; 124 | 125 | .kira-widget-title { 126 | font-size: 1em; 127 | font-weight: 400; 128 | padding: 24px 18px 12px; 129 | margin: 0; 130 | color: $color1; 131 | } 132 | 133 | .kira-widget { 134 | ul { 135 | list-style-type: none; 136 | padding: 0; 137 | margin: 0; 138 | 139 | li { 140 | overflow: hidden; 141 | text-overflow: ellipsis; 142 | white-space: nowrap; 143 | position: relative; 144 | padding: 12px 18px; 145 | 146 | a { 147 | color: #606266; 148 | } 149 | 150 | &:last-child { 151 | border-bottom: none; 152 | padding-bottom: 24px; 153 | } 154 | } 155 | } 156 | 157 | .category-list-count, 158 | .archive-list-count { 159 | background-color: rgba( 160 | hexo-config('color.first.r'), 161 | hexo-config('color.first.g'), 162 | hexo-config('color.first.b'), 163 | 0.1 164 | ); 165 | display: inline-block; 166 | width: 26px; 167 | height: 26px; 168 | line-height: 26px; 169 | text-align: center; 170 | border-radius: 100%; 171 | color: $color1; 172 | position: absolute; 173 | right: 18px; 174 | top: 10px; 175 | } 176 | } 177 | 178 | .tagcloud { 179 | padding: 10px; 180 | padding-bottom: 5px; 181 | 182 | a { 183 | border-radius: $radius; 184 | padding: 5px 10px; 185 | font-size: 12px !important; 186 | display: inline-block; 187 | margin-bottom: 5px; 188 | 189 | &::before { 190 | content: '# '; 191 | } 192 | } 193 | } 194 | 195 | &:first-child { 196 | margin-top: 0; 197 | } 198 | } 199 | 200 | .kira-copyright { 201 | padding: 0 30px; 202 | text-align: center; 203 | color: #777; 204 | white-space: normal; 205 | margin-bottom: 20px; 206 | font-size: 12px; 207 | a { 208 | color: $color1; 209 | } 210 | } 211 | 212 | &::-webkit-scrollbar { 213 | display: none; 214 | } 215 | 216 | &-modal { 217 | position: fixed; 218 | left: 0; 219 | top: 0; 220 | width: 100vw; 221 | height: 100vh; 222 | z-index: 15; 223 | pointer-events: none; 224 | transition: background-color 0.3s ease; 225 | background-color: rgba(0, 0, 0, 0); 226 | } 227 | } 228 | -------------------------------------------------------------------------------- /packages/kira-hexo/source/deps/js/Meting.min.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | function _objectSpread(a) { 3 | for (var b = 1; b < arguments.length; b++) { 4 | var c = null == arguments[b] ? {} : arguments[b], 5 | d = Object.keys(c); 6 | 'function' == typeof Object.getOwnPropertySymbols && 7 | (d = d.concat( 8 | Object.getOwnPropertySymbols(c).filter(function (a) { 9 | return Object.getOwnPropertyDescriptor(c, a).enumerable; 10 | }) 11 | )), 12 | d.forEach(function (b) { 13 | _defineProperty(a, b, c[b]); 14 | }); 15 | } 16 | return a; 17 | } 18 | function _defineProperty(a, b, c) { 19 | return ( 20 | b in a 21 | ? Object.defineProperty(a, b, { value: c, enumerable: !0, configurable: !0, writable: !0 }) 22 | : (a[b] = c), 23 | a 24 | ); 25 | } 26 | class MetingJSElement extends HTMLElement { 27 | connectedCallback() { 28 | window.APlayer && window.fetch && (this._init(), this._parse()); 29 | } 30 | disconnectedCallback() { 31 | this.lock || this.aplayer.destroy(); 32 | } 33 | _camelize(a) { 34 | return a 35 | .replace(/^[_.\- ]+/, '') 36 | .toLowerCase() 37 | .replace(/[_.\- ]+(\w|$)/g, (a, b) => b.toUpperCase()); 38 | } 39 | _init() { 40 | let a = {}; 41 | for (let b = 0; b < this.attributes.length; b += 1) 42 | a[this._camelize(this.attributes[b].name)] = this.attributes[b].value; 43 | let b = [ 44 | 'server', 45 | 'type', 46 | 'id', 47 | 'api', 48 | 'auth', 49 | 'auto', 50 | 'lock', 51 | 'name', 52 | 'title', 53 | 'artist', 54 | 'author', 55 | 'url', 56 | 'cover', 57 | 'pic', 58 | 'lyric', 59 | 'lrc', 60 | ]; 61 | this.meta = {}; 62 | for (var c = 0; c < b.length; c++) { 63 | let d = b[c]; 64 | (this.meta[d] = a[d]), delete a[d]; 65 | } 66 | (this.config = a), 67 | (this.api = 68 | this.meta.api || 69 | window.meting_api || 70 | 'https://api.i-meto.com/meting/api?server=:server&type=:type&id=:id&r=:r'), 71 | this.meta.auto && this._parse_link(); 72 | } 73 | _parse_link() { 74 | let a = [ 75 | ['music.163.com.*song.*id=(\\d+)', 'netease', 'song'], 76 | ['music.163.com.*album.*id=(\\d+)', 'netease', 'album'], 77 | ['music.163.com.*artist.*id=(\\d+)', 'netease', 'artist'], 78 | ['music.163.com.*playlist.*id=(\\d+)', 'netease', 'playlist'], 79 | ['music.163.com.*discover/toplist.*id=(\\d+)', 'netease', 'playlist'], 80 | ['y.qq.com.*song/(\\w+).html', 'tencent', 'song'], 81 | ['y.qq.com.*album/(\\w+).html', 'tencent', 'album'], 82 | ['y.qq.com.*singer/(\\w+).html', 'tencent', 'artist'], 83 | ['y.qq.com.*playsquare/(\\w+).html', 'tencent', 'playlist'], 84 | ['y.qq.com.*playlist/(\\w+).html', 'tencent', 'playlist'], 85 | ['xiami.com.*song/(\\w+)', 'xiami', 'song'], 86 | ['xiami.com.*album/(\\w+)', 'xiami', 'album'], 87 | ['xiami.com.*artist/(\\w+)', 'xiami', 'artist'], 88 | ['xiami.com.*collect/(\\w+)', 'xiami', 'playlist'], 89 | ]; 90 | for (var b = 0; b < a.length; b++) { 91 | let c = a[b], 92 | d = new RegExp(c[0]), 93 | e = d.exec(this.meta.auto); 94 | if (null !== e) 95 | return (this.meta.server = c[1]), (this.meta.type = c[2]), void (this.meta.id = e[1]); 96 | } 97 | } 98 | _parse() { 99 | if (this.meta.url) { 100 | let a = { 101 | name: this.meta.name || this.meta.title || 'Audio name', 102 | artist: this.meta.artist || this.meta.author || 'Audio artist', 103 | url: this.meta.url, 104 | cover: this.meta.cover || this.meta.pic, 105 | lrc: this.meta.lrc || this.meta.lyric || '', 106 | type: this.meta.type || 'auto', 107 | }; 108 | return ( 109 | a.lrc || (this.meta.lrcType = 0), 110 | this.innerText && ((a.lrc = this.innerText), (this.meta.lrcType = 2)), 111 | void this._loadPlayer([a]) 112 | ); 113 | } 114 | let a = this.api 115 | .replace(':server', this.meta.server) 116 | .replace(':type', this.meta.type) 117 | .replace(':id', this.meta.id) 118 | .replace(':auth', this.meta.auth) 119 | .replace(':r', Math.random()); 120 | fetch(a) 121 | .then((a) => a.json()) 122 | .then((a) => this._loadPlayer(a)); 123 | } 124 | _loadPlayer(a) { 125 | let b = { audio: a, mutex: !0, lrcType: this.meta.lrcType || 3, storageName: 'metingjs' }; 126 | if (a.length) { 127 | let a = _objectSpread({}, b, this.config); 128 | for (let b in a) ('true' === a[b] || 'false' === a[b]) && (a[b] = 'true' === a[b]); 129 | let c = document.createElement('div'); 130 | (a.container = c), this.appendChild(c), (this.aplayer = new APlayer(a)); 131 | } 132 | } 133 | } 134 | console.log( 135 | '\n %c MetingJS v2.0.1 %c https://github.com/metowolf/MetingJS \n', 136 | 'color: #fadfa3; background: #030307; padding:5px 0;', 137 | 'background: #fadfa3; padding:5px 0;' 138 | ), 139 | window.customElements && 140 | !window.customElements.get('meting-js') && 141 | ((window.MetingJSElement = MetingJSElement), 142 | window.customElements.define('meting-js', MetingJSElement)); 143 | -------------------------------------------------------------------------------- /packages/kira-hexo/source/js/kira-code-copy.js: -------------------------------------------------------------------------------- 1 | window.addEventListener('DOMContentLoaded', () => { 2 | const codeBlocks = document.querySelectorAll('figure.highlight'); 3 | if (!codeBlocks.length) return; 4 | 5 | const addCopyButton = function (codeBlock) { 6 | const copyWrapper = document.createElement('div'); 7 | copyWrapper.setAttribute('class', 'kira-codeblock-copy-wrapper'); 8 | 9 | let copiedTimeout = null; 10 | 11 | copyWrapper.addEventListener('click', (ev) => { 12 | const highlightDom = ev.target.parentElement; 13 | const code = highlightDom.querySelector('code'); 14 | 15 | let copiedCode = ''; 16 | 17 | (function traverseChildNodes(node) { 18 | const childNodes = node.childNodes; 19 | childNodes.forEach((child) => { 20 | switch (child.nodeName) { 21 | case '#text': 22 | copiedCode += child.nodeValue; 23 | break; 24 | case 'BR': 25 | copiedCode += '\n'; 26 | break; 27 | default: 28 | traverseChildNodes(child); 29 | } 30 | }); 31 | })(code); 32 | 33 | navigator.clipboard 34 | .writeText( 35 | // 去掉最后的换行 36 | copiedCode.slice(0, -1) 37 | ) 38 | .then(() => { 39 | if (!!copiedTimeout) clearTimeout(copiedTimeout); 40 | 41 | copyWrapper.classList.add('kira-codeblock-copy-wrapper-copied'); 42 | copiedTimeout = setTimeout(() => { 43 | copyWrapper.classList.remove('kira-codeblock-copy-wrapper-copied'); 44 | copiedTimeout = null; 45 | }, 1500); 46 | }); 47 | }); 48 | codeBlock.appendChild(copyWrapper); 49 | }; 50 | 51 | codeBlocks.forEach(addCopyButton); 52 | }); 53 | -------------------------------------------------------------------------------- /packages/kira-hexo/source/lib/fonts/roboto/Roboto-Bold.woff2: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ch1ny/kira-hexo/0bba396b1c70e7ba6a9f5480194b067692bfeb3f/packages/kira-hexo/source/lib/fonts/roboto/Roboto-Bold.woff2 -------------------------------------------------------------------------------- /packages/kira-hexo/source/lib/fonts/roboto/Roboto-Medium.woff2: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ch1ny/kira-hexo/0bba396b1c70e7ba6a9f5480194b067692bfeb3f/packages/kira-hexo/source/lib/fonts/roboto/Roboto-Medium.woff2 -------------------------------------------------------------------------------- /packages/kira-hexo/source/lib/fonts/roboto/Roboto-Regular.woff2: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ch1ny/kira-hexo/0bba396b1c70e7ba6a9f5480194b067692bfeb3f/packages/kira-hexo/source/lib/fonts/roboto/Roboto-Regular.woff2 -------------------------------------------------------------------------------- /packages/kira-hexo/source/lib/highlight/atom-one-dark.min.css: -------------------------------------------------------------------------------- 1 | pre code.hljs{display:block;overflow-x:auto;padding:1em}code.hljs{padding:3px 5px}.hljs{color:#abb2bf;background:#282c34}.hljs-comment,.hljs-quote{color:#5c6370;font-style:italic}.hljs-doctag,.hljs-formula,.hljs-keyword{color:#c678dd}.hljs-deletion,.hljs-name,.hljs-section,.hljs-selector-tag,.hljs-subst{color:#e06c75}.hljs-literal{color:#56b6c2}.hljs-addition,.hljs-attribute,.hljs-meta .hljs-string,.hljs-regexp,.hljs-string{color:#98c379}.hljs-attr,.hljs-number,.hljs-selector-attr,.hljs-selector-class,.hljs-selector-pseudo,.hljs-template-variable,.hljs-type,.hljs-variable{color:#d19a66}.hljs-bullet,.hljs-link,.hljs-meta,.hljs-selector-id,.hljs-symbol,.hljs-title{color:#61aeee}.hljs-built_in,.hljs-class .hljs-title,.hljs-title.class_{color:#e6c07b}.hljs-emphasis{font-style:italic}.hljs-strong{font-weight:700}.hljs-link{text-decoration:underline} -------------------------------------------------------------------------------- /packages/kira-hexo/source/lib/iconfont/iconfont.css: -------------------------------------------------------------------------------- 1 | @font-face { 2 | font-family: "kirafont"; /* Project id 3299330 */ 3 | src: url('iconfont.woff2?t=1679498690298') format('woff2'), 4 | url('iconfont.woff?t=1679498690298') format('woff'), 5 | url('iconfont.ttf?t=1679498690298') format('truetype'); 6 | } 7 | 8 | .kirafont { 9 | font-family: "kirafont" !important; 10 | font-size: 16px; 11 | font-style: normal; 12 | -webkit-font-smoothing: antialiased; 13 | -moz-osx-font-smoothing: grayscale; 14 | } 15 | 16 | .icon-unordered-list:before { 17 | content: "\e7f5"; 18 | } 19 | 20 | .icon-area-chart-fill:before { 21 | content: "\e7af"; 22 | } 23 | 24 | .icon-time-circle-fill:before { 25 | content: "\e848"; 26 | } 27 | 28 | .icon-calendar-fill:before { 29 | content: "\e84d"; 30 | } 31 | 32 | .icon-container-fill:before { 33 | content: "\e85f"; 34 | } 35 | 36 | .icon-edit-fill:before { 37 | content: "\e86d"; 38 | } 39 | 40 | .icon-tag-fill:before { 41 | content: "\e86e"; 42 | } 43 | 44 | .icon-search:before { 45 | content: "\e752"; 46 | } 47 | 48 | .icon-close:before { 49 | content: "\eb6a"; 50 | } 51 | 52 | .icon-exit-fullscreen:before { 53 | content: "\ec13"; 54 | } 55 | 56 | .icon-fullscreen:before { 57 | content: "\ec14"; 58 | } 59 | 60 | .icon-zoom-out:before { 61 | content: "\ec32"; 62 | } 63 | 64 | .icon-zoom-in:before { 65 | content: "\ec33"; 66 | } 67 | 68 | .icon-link:before { 69 | content: "\ec7f"; 70 | } 71 | 72 | .icon-menu:before { 73 | content: "\e7f4"; 74 | } 75 | 76 | .icon-caret-up:before { 77 | content: "\e8ec"; 78 | } 79 | 80 | .icon-bilibili:before { 81 | content: "\e69e"; 82 | } 83 | 84 | .icon-gitee:before { 85 | content: "\e60c"; 86 | } 87 | 88 | .icon-container:before { 89 | content: "\e7b0"; 90 | } 91 | 92 | .icon-home:before { 93 | content: "\e7c6"; 94 | } 95 | 96 | .icon-right:before { 97 | content: "\e7eb"; 98 | } 99 | 100 | .icon-left:before { 101 | content: "\e7ec"; 102 | } 103 | 104 | .icon-QQ:before { 105 | content: "\e882"; 106 | } 107 | 108 | .icon-user:before { 109 | content: "\e7ad"; 110 | } 111 | 112 | .icon-team:before { 113 | content: "\e7ae"; 114 | } 115 | 116 | .icon-github:before { 117 | content: "\e885"; 118 | } 119 | 120 | -------------------------------------------------------------------------------- /packages/kira-hexo/source/lib/iconfont/iconfont.json: -------------------------------------------------------------------------------- 1 | { 2 | "id": "3299330", 3 | "name": "my-blog", 4 | "font_family": "kirafont", 5 | "css_prefix_text": "icon-", 6 | "description": "", 7 | "glyphs": [ 8 | { 9 | "icon_id": "4767060", 10 | "name": "unordered list", 11 | "font_class": "unordered-list", 12 | "unicode": "e7f5", 13 | "unicode_decimal": 59381 14 | }, 15 | { 16 | "icon_id": "4766297", 17 | "name": "area chart", 18 | "font_class": "area-chart-fill", 19 | "unicode": "e7af", 20 | "unicode_decimal": 59311 21 | }, 22 | { 23 | "icon_id": "4936512", 24 | "name": "time-circle-fill", 25 | "font_class": "time-circle-fill", 26 | "unicode": "e848", 27 | "unicode_decimal": 59464 28 | }, 29 | { 30 | "icon_id": "4936544", 31 | "name": "calendar-fill", 32 | "font_class": "calendar-fill", 33 | "unicode": "e84d", 34 | "unicode_decimal": 59469 35 | }, 36 | { 37 | "icon_id": "4936627", 38 | "name": "container-fill", 39 | "font_class": "container-fill", 40 | "unicode": "e85f", 41 | "unicode_decimal": 59487 42 | }, 43 | { 44 | "icon_id": "4936679", 45 | "name": "edit-fill", 46 | "font_class": "edit-fill", 47 | "unicode": "e86d", 48 | "unicode_decimal": 59501 49 | }, 50 | { 51 | "icon_id": "4936683", 52 | "name": "tag-fill", 53 | "font_class": "tag-fill", 54 | "unicode": "e86e", 55 | "unicode_decimal": 59502 56 | }, 57 | { 58 | "icon_id": "577365", 59 | "name": "搜索", 60 | "font_class": "search", 61 | "unicode": "e752", 62 | "unicode_decimal": 59218 63 | }, 64 | { 65 | "icon_id": "4118038", 66 | "name": "关闭", 67 | "font_class": "close", 68 | "unicode": "eb6a", 69 | "unicode_decimal": 60266 70 | }, 71 | { 72 | "icon_id": "4777231", 73 | "name": "还原画布", 74 | "font_class": "exit-fullscreen", 75 | "unicode": "ec13", 76 | "unicode_decimal": 60435 77 | }, 78 | { 79 | "icon_id": "4777232", 80 | "name": "全屏", 81 | "font_class": "fullscreen", 82 | "unicode": "ec14", 83 | "unicode_decimal": 60436 84 | }, 85 | { 86 | "icon_id": "5732757", 87 | "name": "搜索变小", 88 | "font_class": "zoom-out", 89 | "unicode": "ec32", 90 | "unicode_decimal": 60466 91 | }, 92 | { 93 | "icon_id": "5732758", 94 | "name": "搜索放大", 95 | "font_class": "zoom-in", 96 | "unicode": "ec33", 97 | "unicode_decimal": 60467 98 | }, 99 | { 100 | "icon_id": "6337456", 101 | "name": "插入链接", 102 | "font_class": "link", 103 | "unicode": "ec7f", 104 | "unicode_decimal": 60543 105 | }, 106 | { 107 | "icon_id": "4767059", 108 | "name": "menu", 109 | "font_class": "menu", 110 | "unicode": "e7f4", 111 | "unicode_decimal": 59380 112 | }, 113 | { 114 | "icon_id": "6598341", 115 | "name": "caret-up", 116 | "font_class": "caret-up", 117 | "unicode": "e8ec", 118 | "unicode_decimal": 59628 119 | }, 120 | { 121 | "icon_id": "10932452", 122 | "name": "bilibili-line", 123 | "font_class": "bilibili", 124 | "unicode": "e69e", 125 | "unicode_decimal": 59038 126 | }, 127 | { 128 | "icon_id": "26267572", 129 | "name": "gitee", 130 | "font_class": "gitee", 131 | "unicode": "e60c", 132 | "unicode_decimal": 58892 133 | }, 134 | { 135 | "icon_id": "4766438", 136 | "name": "container", 137 | "font_class": "container", 138 | "unicode": "e7b0", 139 | "unicode_decimal": 59312 140 | }, 141 | { 142 | "icon_id": "4766685", 143 | "name": "home", 144 | "font_class": "home", 145 | "unicode": "e7c6", 146 | "unicode_decimal": 59334 147 | }, 148 | { 149 | "icon_id": "4767011", 150 | "name": "right", 151 | "font_class": "right", 152 | "unicode": "e7eb", 153 | "unicode_decimal": 59371 154 | }, 155 | { 156 | "icon_id": "4767012", 157 | "name": "left", 158 | "font_class": "left", 159 | "unicode": "e7ec", 160 | "unicode_decimal": 59372 161 | }, 162 | { 163 | "icon_id": "4936984", 164 | "name": "QQ", 165 | "font_class": "QQ", 166 | "unicode": "e882", 167 | "unicode_decimal": 59522 168 | }, 169 | { 170 | "icon_id": "4766293", 171 | "name": "user", 172 | "font_class": "user", 173 | "unicode": "e7ad", 174 | "unicode_decimal": 59309 175 | }, 176 | { 177 | "icon_id": "4766294", 178 | "name": "team", 179 | "font_class": "team", 180 | "unicode": "e7ae", 181 | "unicode_decimal": 59310 182 | }, 183 | { 184 | "icon_id": "4937000", 185 | "name": "github-fill", 186 | "font_class": "github", 187 | "unicode": "e885", 188 | "unicode_decimal": 59525 189 | } 190 | ] 191 | } 192 | -------------------------------------------------------------------------------- /packages/kira-hexo/source/lib/iconfont/iconfont.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ch1ny/kira-hexo/0bba396b1c70e7ba6a9f5480194b067692bfeb3f/packages/kira-hexo/source/lib/iconfont/iconfont.ttf -------------------------------------------------------------------------------- /packages/kira-hexo/source/lib/iconfont/iconfont.woff: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ch1ny/kira-hexo/0bba396b1c70e7ba6a9f5480194b067692bfeb3f/packages/kira-hexo/source/lib/iconfont/iconfont.woff -------------------------------------------------------------------------------- /packages/kira-hexo/source/lib/iconfont/iconfont.woff2: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ch1ny/kira-hexo/0bba396b1c70e7ba6a9f5480194b067692bfeb3f/packages/kira-hexo/source/lib/iconfont/iconfont.woff2 -------------------------------------------------------------------------------- /pnpm-workspace.yaml: -------------------------------------------------------------------------------- 1 | packages: 2 | - 'packages/*' 3 | -------------------------------------------------------------------------------- /readme.md: -------------------------------------------------------------------------------- 1 | # Kira-Hexo 2 | 3 | [![npm version](https://badgen.net/npm/v/hexo-theme-kira)](https://www.npmjs.com/package/hexo-theme-kira) [![npm weekly download](https://badgen.net/npm/dw/hexo-theme-kira)](https://www.npmjs.com/package/hexo-theme-kira) [![github stars](https://badgen.net/github/stars/ch1ny/kira-hexo?color=orange)](https://github.com/ch1ny/kira-hexo/stargazers) 4 | 5 | Kira-Hexo,或者你也可以叫它 hexo-theme-kira。正如它的名字一样,是一款 KiraKira ✨ 让人眼前一亮的 hexo 风格化主题。 6 | 7 | ![](https://raw.githubusercontent.com/ch1ny/kira-hexo/master/preview.png) 8 | 9 | ## 快速开始 10 | 11 | 你可以在这里学习如何使用 Kira-Hexo 搭建你的风格化网站:[快速开始](https://kira.host/hexo/) 12 | 13 | ### 使用模板脚手架 14 | 15 | 您也可以使用我们提供的模板脚手架来快速生成基于 `kira-hexo` 主题的 hexo 博客: 16 | 17 | **With npm:** 18 | ```bash 19 | # 我其实更推荐您使用 yarn 或 pnpm ,而不是 npm 20 | npm create kira-hexo@latest my-blog 21 | ``` 22 | 23 | **With yarn:** 24 | ```bash 25 | yarn create kira-hexo my-blog 26 | ``` 27 | 28 | **With pnpm:** 29 | ```bash 30 | pnpm create kira-hexo my-blog 31 | ``` 32 | 33 | ## 代码仓库 34 | 35 | 你能够在 [GitHub](https://github.com/ch1ny/kira-hexo) 上直接获取项目的源代码,也能够在 [这里](https://github.com/ch1ny/kira-hexo/issues) 提出您的建议和意见。 36 | 37 | ## Credits 38 | 39 | > **声明**: 本仓库设计灵感来源于 [hexo-theme-nexmoe](https://github.com/theme-nexmoe/hexo-theme-nexmoe),欢迎各位支持原作者。 40 | --------------------------------------------------------------------------------