feat: 显示文章 metadata 中的 images。
All checks were successful
continuous-integration/drone/push Build is passing

This commit is contained in:
Ivan Li 2022-09-24 01:55:41 +00:00
parent 45af8732c0
commit d7c65cf444
4 changed files with 81 additions and 18 deletions

View File

@ -17,12 +17,32 @@
// Configure properties specific to VS Code. // Configure properties specific to VS Code.
"vscode": { "vscode": {
// Add the IDs of extensions you want installed when the container is created. // Add the IDs of extensions you want installed when the container is created.
"extensions": ["dbaeumer.vscode-eslint"] "extensions": [
"dbaeumer.vscode-eslint",
"formulahendry.auto-rename-tag",
"aaron-bond.better-comments",
"bierner.color-info",
"ldez.ignore-files",
"gooooloo.smartquote",
"wmaurer.change-case",
"streetsidesoftware.code-spell-checker",
"naumovs.color-highlight",
"EditorConfig.EditorConfig",
"mhutchie.git-graph",
"donjayamanne.githistory",
"ecmel.vscode-html-css",
"yzhang.markdown-all-in-one",
"christian-kohler.path-intellisense",
"esbenp.prettier-vscode",
"shardulm94.trailing-spaces",
"lihui.vs-color-picker",
"bradlc.vscode-tailwindcss"
]
} }
}, },
// Use 'forwardPorts' to make a list of ports inside the container available locally. // Use 'forwardPorts' to make a list of ports inside the container available locally.
// "forwardPorts": [], "forwardPorts": [3000],
// Use 'postCreateCommand' to run commands after the container is created. // Use 'postCreateCommand' to run commands after the container is created.
// "postCreateCommand": "yarn install", // "postCreateCommand": "yarn install",
@ -35,5 +55,6 @@
}, },
"mounts": [ "mounts": [
"source=${localEnv:HOME}${localEnv:USERPROFILE}/.ssh,target=/home/node/.ssh,type=bind,consistency=cached" "source=${localEnv:HOME}${localEnv:USERPROFILE}/.ssh,target=/home/node/.ssh,type=bind,consistency=cached"
] ],
"postStartCommand": "npm ci && npm run dev"
} }

View File

@ -4,6 +4,10 @@ date: '2022-09-23'
tags: ['Verdaccio', 'Self-Hosted', 'Docker', 'Caddy', 'registry', 'Node.js'] tags: ['Verdaccio', 'Self-Hosted', 'Docker', 'Caddy', 'registry', 'Node.js']
draft: false draft: false
summary: 作为靠着 JavaScript 生态吃饭的 Web 开发者,自建一个 Node regsitry 是很有必要的,我这次继续选择 Verdaccio 来搭建存储库。这次使用 Docker Compose 部署 Verdaccio并将 Caddy 用于反向代理该服务。 summary: 作为靠着 JavaScript 生态吃饭的 Web 开发者,自建一个 Node regsitry 是很有必要的,我这次继续选择 Verdaccio 来搭建存储库。这次使用 Docker Compose 部署 Verdaccio并将 Caddy 用于反向代理该服务。
images:
[
'https://pan.ivanli.cc/api/v3/file/source/2233/verdaccio.png?sign=qpoeADXzbhHk2MY5CehgTftUJ67pnUj-Ylko9D5jscU%3D%3A0',
]
--- ---
## 为何自建存储库? ## 为何自建存储库?
@ -19,11 +23,13 @@ summary: 作为靠着 JavaScript 生态吃饭的 Web 开发者,自建一个 No
## 如何自建存储库 ## 如何自建存储库
已有环境: 已有环境:
- Docker, Docker Compose - Docker, Docker Compose
- Caddy (in Docker) - Caddy (in Docker)
- 网络:`caddy` - 网络:`caddy`
新增: 新增:
- Verdaccio - Verdaccio
接下来使用 Docker Compose 部署 Verdaccio并将其加入到 `caddy` 网络中,之后配置 Caddy使其反向代理 Verdaccio。 接下来使用 Docker Compose 部署 Verdaccio并将其加入到 `caddy` 网络中,之后配置 Caddy使其反向代理 Verdaccio。
@ -33,7 +39,7 @@ summary: 作为靠着 JavaScript 生态吃饭的 Web 开发者,自建一个 No
创建文件 `docker-compose.yml` 创建文件 `docker-compose.yml`
```yml {9,16-17} showLineNumbers ```yml {9,16-17} showLineNumbers
version: "3,16-17" version: '3'
networks: networks:
caddy: caddy:
@ -68,6 +74,7 @@ volumes:
因为前面将配置文件目录 `verdaccio/conf` 设为了 `verdaccio`,所以: 因为前面将配置文件目录 `verdaccio/conf` 设为了 `verdaccio`,所以:
创建配置文件 `verdaccio/config.yaml` 创建配置文件 `verdaccio/config.yaml`
```zsh {1,2} showLineNumbers ```zsh {1,2} showLineNumbers
storage: /verdaccio/storage storage: /verdaccio/storage
plugins: /verdaccio/plugins plugins: /verdaccio/plugins
@ -107,6 +114,7 @@ web:
因为我们使用了 `bcrypt` 算法保存密码,所以可以借助 [Bcrypt-Generator.com](https://bcrypt-generator.com/) 生成保存的密码。 因为我们使用了 `bcrypt` 算法保存密码,所以可以借助 [Bcrypt-Generator.com](https://bcrypt-generator.com/) 生成保存的密码。
创建文件:`verdaccio/htpasswd`: 创建文件:`verdaccio/htpasswd`:
```htpasswd ```htpasswd
admin:$2a$12$9xxxxxxxxxxxxxxlO.slh2k2 admin:$2a$12$9xxxxxxxxxxxxxxlO.slh2k2
``` ```

View File

@ -7,18 +7,44 @@ import Tag from '@/components/Tag'
import siteMetadata from '@/data/siteMetadata' import siteMetadata from '@/data/siteMetadata'
import Comments from '@/components/comments' import Comments from '@/components/comments'
import ScrollTopAndComment from '@/components/ScrollTopAndComment' import ScrollTopAndComment from '@/components/ScrollTopAndComment'
import { useMemo } from 'react'
const editUrl = (fileName) => `${siteMetadata.siteRepo}/raw/master/data/blog/${fileName}` const editUrl = (fileName) => `${siteMetadata.siteRepo}/raw/master/data/blog/${fileName}`
const discussUrl = (slug) => const discussUrl = (slug) =>
`https://mobile.twitter.com/search?q=${encodeURIComponent( `https://mobile.twitter.com/search?q=${encodeURIComponent(
`${siteMetadata.siteUrl}/blog/${slug}` `${siteMetadata.siteUrl}/blog/${slug}`
)}` )}`
const Copyright = () => (
<a
rel="license"
href="http://creativecommons.org/licenses/by-sa/4.0/"
className="inline-flex self-center"
>
<Image
className="border-0"
alt="知识共享许可协议"
width="88"
height="15"
src="https://i.creativecommons.org/l/by-sa/4.0/80x15.png"
/>
</a>
)
const postDateTemplate = { weekday: 'long', year: 'numeric', month: 'long', day: 'numeric' } const postDateTemplate = { weekday: 'long', year: 'numeric', month: 'long', day: 'numeric' }
export default function PostLayout({ frontMatter, authorDetails, next, prev, children }) { export default function PostLayout({ frontMatter, authorDetails, next, prev, children }) {
const { slug, fileName, date, title, images, tags } = frontMatter const { slug, fileName, date, title, images, tags } = frontMatter
const headerStyles = useMemo(
() =>
images?.[0]
? {
backgroundImage: `url(${images[0]})`,
}
: {},
[images]
)
return ( return (
<SectionContainer> <SectionContainer>
<BlogSEO <BlogSEO
@ -29,8 +55,18 @@ export default function PostLayout({ frontMatter, authorDetails, next, prev, chi
<ScrollTopAndComment /> <ScrollTopAndComment />
<article> <article>
<div className="xl:divide-y xl:divide-gray-200 xl:dark:divide-gray-700"> <div className="xl:divide-y xl:divide-gray-200 xl:dark:divide-gray-700">
<header className="pt-6 xl:pb-6"> <header className="relative h-48 pt-6 xl:pb-6">
<div className="space-y-1 text-center"> {images?.[0] && (
<Image
alt="background"
layout="fill"
objectFit="cover"
src={images[0]}
style={headerStyles}
className="blur-xs -z-10 opacity-50 bg-blend-soft-light"
/>
)}
<div className="space-y-5 text-center">
<dl className="space-y-10"> <dl className="space-y-10">
<div> <div>
<dt className="sr-only">Published on</dt> <dt className="sr-only">Published on</dt>
@ -87,10 +123,8 @@ export default function PostLayout({ frontMatter, authorDetails, next, prev, chi
</dl> </dl>
<div className="divide-y divide-gray-200 dark:divide-gray-700 xl:col-span-3 xl:row-span-2 xl:pb-0"> <div className="divide-y divide-gray-200 dark:divide-gray-700 xl:col-span-3 xl:row-span-2 xl:pb-0">
<div className="prose max-w-none pt-10 pb-8 dark:prose-dark">{children}</div> <div className="prose max-w-none pt-10 pb-8 dark:prose-dark">{children}</div>
<div className="pt-6 pb-6 text-sm text-gray-700 dark:text-gray-300"> <div className="flex items-center pt-6 pb-6 text-sm text-gray-700 dark:text-gray-300">
<Link href={discussUrl(slug)} rel="nofollow"> <Copyright />
{'Discuss on Twitter'}
</Link>
{``} {``}
<Link href={editUrl(fileName)}>{'View source'}</Link> <Link href={editUrl(fileName)}>{'View source'}</Link>
</div> </div>

View File

@ -59,7 +59,7 @@ module.exports = withBundleAnalyzer({
dirs: ['pages', 'components', 'lib', 'layouts', 'scripts'], dirs: ['pages', 'components', 'lib', 'layouts', 'scripts'],
}, },
images: { images: {
domains: ['pan.ivanli.cc'], domains: ['pan.ivanli.cc', 'i.creativecommons.org'],
}, },
async headers() { async headers() {
return [ return [