diff --git a/.github/ISSUE_TEMPLATE/bug_report.yml b/.github/ISSUE_TEMPLATE/bug_report.yml new file mode 100644 index 00000000..7e3b604b --- /dev/null +++ b/.github/ISSUE_TEMPLATE/bug_report.yml @@ -0,0 +1,24 @@ +name: "\U0001F4DA 反馈中文文档项目问题" +description: 反馈 Vite 官方中文文档项目的相关问题 +labels: [documentation] +body: + - type: markdown + attributes: + value: | + 感谢您对 Vite 的支持,这里是 Vite 官方中文文档的翻译项目相关 issue 区,请不要在此提交关于 Vite 使用的问题或报 Bug。 + - type: checkboxes + id: documentation_is + attributes: + label: 文档的 + options: + - label: 翻译缺失 + - label: 翻译不准确 + - label: 其他问题 + - type: textarea + id: description + attributes: + label: 详细描述 + description: 请简明扼要地阐述您的问题。如果您愿意提交 PR 修改,请参考 [贡献指南](https://github.com/vitejs/docs-cn/wiki/%E5%90%88%E4%BD%9C%E8%A7%84%E8%8C%83)。 + placeholder: xxx章节下的翻译有歧义... xxx章节与英文原文对应不上... + validations: + required: true diff --git a/.github/ISSUE_TEMPLATE/config.yml b/.github/ISSUE_TEMPLATE/config.yml new file mode 100644 index 00000000..d3e4ab32 --- /dev/null +++ b/.github/ISSUE_TEMPLATE/config.yml @@ -0,0 +1,8 @@ +blank_issues_enabled: false +contact_links: + - name: Vite Issue 区 + url: https://github.com/vitejs/vite/issues + about: 与 Vite 相关的 Bug 上报,请移步 Vite 主仓库 issue 区 + - name: Vite Discussion 区 + url: https://github.com/vitejs/vite/discussions + about: 与 Vite 相关的讨论和使用问题,请移步 Vite 主仓库 discussion 区 diff --git a/.gitignore b/.gitignore index 34570f14..becbdc49 100644 --- a/.gitignore +++ b/.gitignore @@ -7,4 +7,5 @@ node_modules/ package-lock.json yarn.lock .vitepress/dist -*.local \ No newline at end of file +*.local +.vitepress/cache \ No newline at end of file diff --git a/.vitepress/buildEnd.config.ts b/.vitepress/buildEnd.config.ts new file mode 100644 index 00000000..8e0d72b7 --- /dev/null +++ b/.vitepress/buildEnd.config.ts @@ -0,0 +1,50 @@ +import path from 'node:path' +import { writeFileSync } from 'node:fs' +import { Feed } from 'feed' +import type { SiteConfig } from 'vitepress' +import { createContentLoader } from 'vitepress' + +const siteUrl = 'https://vite.dev' +const blogUrl = `${siteUrl}/blog` + +export const buildEnd = async (config: SiteConfig): Promise => { + const feed = new Feed({ + title: 'Vite', + description: 'Next Generation Frontend Tooling', + id: blogUrl, + link: blogUrl, + language: 'en', + image: 'https://vite.dev/og-image.png', + favicon: 'https://vite.dev/logo.svg', + copyright: 'Copyright © 2019-present VoidZero Inc. & Vite Contributors', + }) + + const posts = await createContentLoader('blog/*.md', { + excerpt: true, + render: true, + }).load() + + posts.sort( + (a, b) => + +new Date(b.frontmatter.date as string) - + +new Date(a.frontmatter.date as string), + ) + + for (const { url, excerpt, frontmatter, html } of posts) { + feed.addItem({ + title: frontmatter.title, + id: `${siteUrl}${url}`, + link: `${siteUrl}${url}`, + description: excerpt, + content: html, + author: [ + { + name: frontmatter.author.name, + }, + ], + date: frontmatter.date, + }) + } + + writeFileSync(path.join(config.outDir, 'blog.rss'), feed.rss2()) +} diff --git a/.vitepress/config.ts b/.vitepress/config.ts index e57cc909..e8a9f85d 100644 --- a/.vitepress/config.ts +++ b/.vitepress/config.ts @@ -1,11 +1,79 @@ +import type { DefaultTheme } from 'vitepress' import { defineConfig } from 'vitepress' -import renderPermaLink from './render-perma-link' -import MarkDownItCustomAnchor from './markdown-it-custom-anchor' +import { transformerTwoslash } from '@shikijs/vitepress-twoslash' +import { + groupIconMdPlugin, + groupIconVitePlugin, +} from 'vitepress-plugin-group-icons' +import { buildEnd } from './buildEnd.config' const ogDescription = 'Next Generation Frontend Tooling' -const ogImage = 'https://vitejs.dev/og-image.png' +const ogImage = 'https://vite.dev/og-image.jpg' const ogTitle = 'Vite' -const ogUrl = 'https://vitejs.dev' +const ogUrl = 'https://vite.dev' + +// netlify envs +const deployURL = process.env.DEPLOY_PRIME_URL || '' +const commitRef = process.env.COMMIT_REF?.slice(0, 8) || 'dev' + +const deployType = (() => { + switch (deployURL) { + case 'https://main--vite-docs-main.netlify.app': + return 'main' + case '': + return 'local' + default: + return 'release' + } +})() +const additionalTitle = ((): string => { + switch (deployType) { + case 'main': + return ' (main branch)' + case 'local': + return ' (local)' + case 'release': + return '' + } +})() +const versionLinks = ((): DefaultTheme.NavItemWithLink[] => { + const oldVersions: DefaultTheme.NavItemWithLink[] = [ + { + text: 'Vite 6 Docs', + link: 'https://v6.vite.dev', + }, + { + text: 'Vite 5 Docs', + link: 'https://v5.vite.dev', + }, + { + text: 'Vite 4 Docs', + link: 'https://v4.vite.dev', + }, + { + text: 'Vite 3 Docs', + link: 'https://v3.vite.dev', + }, + { + text: 'Vite 2 Docs', + link: 'https://v2.vite.dev', + }, + ] + + switch (deployType) { + case 'main': + case 'local': + return [ + { + text: 'Vite 7 Docs (release)', + link: 'https://vite.dev', + }, + ...oldVersions, + ] + case 'release': + return oldVersions + } +})() export default defineConfig({ title: 'Vite 官方中文文档', @@ -14,103 +82,201 @@ export default defineConfig({ head: [ ['link', { rel: 'icon', type: 'image/svg+xml', href: '/logo.svg' }], + [ + 'link', + { rel: 'alternate', type: 'application/rss+xml', href: '/blog.rss' }, + ], + ['link', { rel: 'preconnect', href: 'https://fonts.googleapis.com' }], + [ + 'link', + { + rel: 'preconnect', + href: 'https://fonts.gstatic.com', + crossorigin: 'true', + }, + ], + [ + 'link', + { + rel: 'preload', + href: 'https://fonts.googleapis.com/css2?family=Inter:wght@400;500;600&family=Manrope:wght@600&family=IBM+Plex+Mono:wght@400&display=swap', + as: 'style', + }, + ], + [ + 'link', + { + rel: 'stylesheet', + href: 'https://fonts.googleapis.com/css2?family=Inter:wght@400;500;600&family=Manrope:wght@600&family=IBM+Plex+Mono:wght@400&display=swap', + }, + ], + ['link', { rel: 'me', href: 'https://m.webtoo.ls/@vite' }], ['meta', { property: 'og:type', content: 'website' }], ['meta', { property: 'og:title', content: ogTitle }], ['meta', { property: 'og:image', content: ogImage }], ['meta', { property: 'og:url', content: ogUrl }], ['meta', { property: 'og:description', content: ogDescription }], + ['meta', { property: 'og:site_name', content: 'vitejs' }], ['meta', { name: 'twitter:card', content: 'summary_large_image' }], ['meta', { name: 'twitter:site', content: '@vite_js' }], - ['meta', { name: 'theme-color', content: '#646cff' }] + ['meta', { name: 'theme-color', content: '#646cff' }], + [ + 'script', + { + src: 'https://cdn.usefathom.com/script.js', + 'data-site': 'TPLGJZGR', + 'data-spa': 'auto', + defer: '', + }, + ], ], - vue: { - reactivityTransform: true + locales: { + root: { label: '简体中文' }, + en: { label: 'English', link: 'https://vite.dev' }, + ja: { label: '日本語', link: 'https://ja.vite.dev' }, + es: { label: 'Español', link: 'https://es.vite.dev' }, + pt: { label: 'Português', link: 'https://pt.vite.dev' }, + ko: { label: '한국어', link: 'https://ko.vite.dev' }, + de: { label: 'Deutsch', link: 'https://de.vite.dev' }, + fa: { label: 'فارسی', link: 'https://fa.vite.dev' }, }, themeConfig: { logo: '/logo.svg', editLink: { + pattern: 'https://github.com/vitejs/docs-cn/edit/main/:path', text: '为此页提供修改建议', - pattern: 'https://github.com/vitejs/docs-cn/edit/main/:path' + }, + + outline: { + label: '本页目录', + level: [2, 3], }, socialLinks: [ - { icon: 'twitter', link: 'https://twitter.com/vite_js' }, - { icon: 'discord', link: 'https://chat.vitejs.dev' }, - { icon: 'github', link: 'https://github.com/vitejs/vite' } + { icon: 'bluesky', link: 'https://bsky.app/profile/vite.dev' }, + { icon: 'mastodon', link: 'https://elk.zone/m.webtoo.ls/@vite' }, + { icon: 'x', link: 'https://x.com/vite_js' }, + { icon: 'discord', link: 'https://chat.vite.dev' }, + { icon: 'github', link: 'https://github.com/vitejs/vite' }, ], - algolia: { - appId: '7H67QR5P0A', - apiKey: 'deaab78bcdfe96b599497d25acc6460e', - indexName: 'vitejs', - searchParameters: { - facetFilters: ['tags:cn'] + search: { + provider: 'local', + options: { + translations: { + button: { + buttonText: '搜索', + buttonAriaLabel: '搜索' + }, + modal: { + footer: { + selectText: '选择', + navigateText: '切换', + closeText: '关闭', + }, + } + }, } }, - carbonAds: { - code: 'CEBIEK3N', - placement: 'vitejsdev' + docFooter: { + prev: '上一页', + next: '下一页' }, - localeLinks: { - text: '简体中文', - items: [ - { text: 'English', link: 'https://vitejs.dev' }, - { text: '日本語', link: 'https://ja.vitejs.dev' }, - { text: 'Español', link: 'https://es.vitejs.dev' } - ] - }, + // Using WwAds for China + // carbonAds: { + // code: 'CEBIEK3N', + // placement: 'vitejsdev', + // }, footer: { + message: `Released under the MIT License. (${commitRef})`, copyright: - '本中文文档内容版权为 Vite 官方中文翻译团队所有,保留所有权利。' + 'Copyright © 2019-present VoidZero Inc. & Vite Contributors' }, nav: [ + { + component: 'ReleaseTag' + }, { text: '指引', link: '/guide/', activeMatch: '/guide/' }, { text: '配置', link: '/config/', activeMatch: '/config/' }, { text: '插件', link: '/plugins/', activeMatch: '/plugins/' }, { text: '相关链接', items: [ - { text: 'Team', link: '/team' }, + { text: '团队成员', link: '/team' }, + { text: '最新博客', link: '/blog' }, + { text: '发布策略', link: '/releases' }, { - text: 'Twitter', - link: 'https://twitter.com/vite_js' + items: [ + { + text: 'Bluesky', + link: 'https://bsky.app/profile/vite.dev', + }, + { + text: 'Mastodon', + link: 'https://elk.zone/m.webtoo.ls/@vite', + }, + { + text: 'X', + link: 'https://x.com/vite_js', + }, + { + text: 'Discord 聊天室', + link: 'https://chat.vite.dev', + }, + { + text: 'Awesome Vite', + link: 'https://github.com/vitejs/awesome-vite' + }, + { + text: 'ViteConf', + link: 'https://viteconf.org', + }, + { + text: 'Dev.to 社区', + link: 'https://dev.to/t/vite' + }, + { + text: '更新日志', + link: 'https://github.com/vitejs/vite/blob/main/packages/vite/CHANGELOG.md', + }, + { + text: '贡献指南', + link: 'https://github.com/vitejs/vite/blob/main/CONTRIBUTING.md', + }, + ], }, + ] + }, + { + text: '历史版本', + items: [ { - text: 'Discord Chat', - link: 'https://chat.vitejs.dev' + text: 'Vite v6 文档(英文)', + link: 'https://v6.vite.dev' }, { - text: 'Awesome Vite', - link: 'https://github.com/vitejs/awesome-vite' + text: 'Vite v5 文档(英文)', + link: 'https://v5.vite.dev' }, { - text: 'Dev.to 社区', - link: 'https://dev.to/t/vite' + text: 'Vite v4 文档(英文)', + link: 'https://v4.vite.dev' }, { - text: 'Rollup 插件兼容', - link: 'https://vite-rollup-plugins.patak.dev/' + text: 'Vite v3 文档(英文)', + link: 'https://v3.vite.dev' }, { - text: '更新日志', - link: 'https://github.com/vitejs/vite/blob/main/packages/vite/CHANGELOG.md' - } - ] - }, - { - text: 'Version', - items: [ - { - text: 'Vite v2 文档', - link: 'https://v2.vitejs.dev' - } + text: 'Vite v2 文档(英文)', + link: 'https://v2.vite.dev' + }, ] } ], @@ -118,19 +284,32 @@ export default defineConfig({ sidebar: { '/guide/': [ { - text: '指引', + text: '介绍', items: [ { - text: '为什么选 Vite', - link: '/guide/why' + text: '开始', + link: '/guide/', }, { - text: '开始', - link: '/guide/' + text: '理念', + link: '/guide/philosophy', }, + { + text: '为什么选 Vite', + link: '/guide/why', + }, + ], + }, + { + text: '指引', + items: [ { text: '功能', - link: '/guide/features' + link: '/guide/features', + }, + { + text: '命令行接口', + link: '/guide/cli' }, { text: '使用插件', @@ -165,18 +344,26 @@ export default defineConfig({ link: '/guide/backend-integration' }, { - text: '比较', - link: '/guide/comparisons' + text: '故障排除', + link: '/guide/troubleshooting', }, { - text: '故障排除', - link: '/guide/troubleshooting' + text: '性能', + link: '/guide/performance', + }, + { + text: 'Rolldown', + link: '/guide/rolldown', + }, + { + text: '从 v6 迁移', + link: '/guide/migration', }, { - text: '从 v2 迁移', - link: '/guide/migration' - } - ] + text: '破坏性变更', + link: '/changes/', + }, + ], }, { text: 'API', @@ -187,18 +374,43 @@ export default defineConfig({ }, { text: 'HMR API', - link: '/guide/api-hmr' + link: '/guide/api-hmr', }, { text: 'JavaScript API', - link: '/guide/api-javascript' + link: '/guide/api-javascript', }, { text: '配置参考', - link: '/config/' - } - ] - } + link: '/config/', + }, + ], + }, + { + text: '环境 API', + items: [ + { + text: '介绍', + link: '/guide/api-environment', + }, + { + text: '环境实例', + link: '/guide/api-environment-instances', + }, + { + text: '插件', + link: '/guide/api-environment-plugins', + }, + { + text: '框架', + link: '/guide/api-environment-frameworks', + }, + { + text: '运行时', + link: '/guide/api-environment-runtimes', + }, + ], + }, ], '/config/': [ { @@ -234,20 +446,89 @@ export default defineConfig({ }, { text: 'Worker 选项', - link: '/config/worker-options' - } - ] - } - ] - } + link: '/config/worker-options', + }, + ], + }, + ], + '/changes/': [ + { + text: '破坏性变更', + link: '/changes/', + }, + { + text: '现在', + items: [], + }, + { + text: '未来', + items: [ + { + text: '钩子函数中的 this.environment', + link: '/changes/this-environment-in-hooks', + }, + { + text: 'HMR hotUpdate 插件钩子', + link: '/changes/hotupdate-hook', + }, + { + text: '迁移到基于环境的API', + link: '/changes/per-environment-apis', + }, + { + text: '使用 ModuleRunner API 进行服务端渲染', + link: '/changes/ssr-using-modulerunner', + }, + { + text: '构建过程中的共享插件', + link: '/changes/shared-plugins-during-build', + }, + ], + }, + { + text: '过去', + items: [], + }, + ], + }, + }, + transformPageData(pageData) { + const canonicalUrl = `${ogUrl}/${pageData.relativePath}` + .replace(/\/index\.md$/, '/') + .replace(/\.md$/, '') + pageData.frontmatter.head ??= [] + pageData.frontmatter.head.unshift( + ['link', { rel: 'canonical', href: canonicalUrl }], + ['meta', { property: 'og:title', content: pageData.title }], + ) + return pageData }, - markdown: { - anchor: { - permalink: renderPermaLink + // languages used for twoslash and jsdocs in twoslash + languages: ['ts', 'js', 'json'], + codeTransformers: [transformerTwoslash()], + config(md) { + md.use(groupIconMdPlugin) }, - config: (md) => { - md.use(MarkDownItCustomAnchor) - } - } + }, + vite: { + plugins: [ + // @ts-ignore + groupIconVitePlugin({ + customIcon: { + firebase: 'vscode-icons:file-type-firebase', + '.gitlab-ci.yml': 'vscode-icons:file-type-gitlab', + }, + }), + ], + optimizeDeps: { + include: [ + '@shikijs/vitepress-twoslash/client', + 'gsap', + 'gsap/dist/ScrollTrigger', + 'gsap/dist/MotionPathPlugin', + ], + }, + }, + buildEnd, }) diff --git a/.vitepress/rewrite-title/index.js b/.vitepress/rewrite-title/index.js index f310ef33..33308779 100644 --- a/.vitepress/rewrite-title/index.js +++ b/.vitepress/rewrite-title/index.js @@ -1,6 +1,8 @@ -const path = require('path') -const fsp = require('fs').promises -const matterService = require('../utils/frontmatter-service') +import path from 'node:path' +import fsp from 'node:fs/promises' +import matterService from '../utils/frontmatter-service.js' +import { fileURLToPath } from 'node:url' +const __dirname = path.dirname(fileURLToPath(import.meta.url)) const workspacePath = path.resolve(__dirname, '..', '..') const h1MdRegExp = /^#\s+(.+)\s+(\{#([\w-]+)\})$/ @@ -41,4 +43,4 @@ const ergodicDirectory = async (dirPath) => { } } -module.exports = () => ergodicDirectory(workspacePath) +export default () => ergodicDirectory(workspacePath) diff --git a/.vitepress/theme/components/AsideSponsors.vue b/.vitepress/theme/components/AsideSponsors.vue index 789f1e0e..55a52c48 100644 --- a/.vitepress/theme/components/AsideSponsors.vue +++ b/.vitepress/theme/components/AsideSponsors.vue @@ -1,29 +1,34 @@