feat: add Vite plugins for enhanced functionality and localization support

- Introduced multiple Vite plugins including `ogImagePlugin`, `feedSitemapPlugin`, `localesJsonPlugin`, and `manifestInjectPlugin` to enhance the build process and support dynamic content generation.
- Implemented a custom hot module replacement (HMR) for JSON localization files to improve development experience.
- Added a new `createDependencyChunksPlugin` for better chunk management in the build process.
- Established a structure for handling localization files and generating corresponding assets, improving internationalization support.

Signed-off-by: Innei <tukon479@gmail.com>
This commit is contained in:
Innei
2025-06-27 16:58:12 +08:00
parent 854ee1df8d
commit 6668425fba
10 changed files with 32 additions and 41 deletions

View File

@@ -0,0 +1,9 @@
import path from 'node:path'
const dirname = path.dirname(new URL(import.meta.url).pathname)
export const MANIFEST_PATH = path.resolve(
dirname,
'../../../../../packages/data/src/photos-manifest.json',
)
export const MONOREPO_ROOT_PATH = path.resolve(dirname, '../../../../..')

View File

@@ -1,11 +1,11 @@
import { readFileSync } from 'node:fs'
import { resolve } from 'node:path'
import { fileURLToPath } from 'node:url'
import type { PhotoManifestItem } from '@afilmory/builder'
import type { Plugin } from 'vite'
import type { SiteConfig } from '../../site.config'
import type { SiteConfig } from '../../../../site.config'
import { MANIFEST_PATH } from './__internal__/constants'
const __dirname = fileURLToPath(new URL('.', import.meta.url))
@@ -15,13 +15,8 @@ export function createFeedSitemapPlugin(siteConfig: SiteConfig): Plugin {
apply: 'build',
generateBundle() {
try {
// Read photos manifest
const manifestPath = resolve(
__dirname,
'../../packages/data/src/photos-manifest.json',
)
const photosData: PhotoManifestItem[] = JSON.parse(
readFileSync(manifestPath, 'utf-8'),
readFileSync(MANIFEST_PATH, 'utf-8'),
).data
// Sort photos by date taken (newest first)

View File

@@ -1,11 +1,8 @@
import path from 'node:path'
import { fileURLToPath } from 'node:url'
import { set } from 'es-toolkit/compat'
import type { Plugin } from 'vite'
const __dirname = fileURLToPath(new URL('.', import.meta.url))
const localesDir = path.resolve(__dirname, '../../locales')
import { MONOREPO_ROOT_PATH } from './__internal__/constants'
export function localesJsonPlugin(): Plugin {
return {
@@ -13,7 +10,7 @@ export function localesJsonPlugin(): Plugin {
enforce: 'pre',
async transform(code, id) {
if (!id.includes(localesDir) || !id.endsWith('.json')) {
if (!id.includes(MONOREPO_ROOT_PATH) || !id.endsWith('.json')) {
return null
}

View File

@@ -1,26 +1,23 @@
import fs from 'node:fs'
import path, { dirname } from 'node:path'
import { fileURLToPath } from 'node:url'
import path from 'node:path'
import { set } from 'es-toolkit/compat'
import type { Plugin } from 'vite'
import { MONOREPO_ROOT_PATH } from './__internal__/constants'
export function localesPlugin(): Plugin {
return {
name: 'locales-merge',
enforce: 'post',
generateBundle(_options, bundle) {
const __dirname = dirname(fileURLToPath(import.meta.url))
const localesDir = path.resolve(__dirname, '../../locales')
const namespaces = fs
.readdirSync(localesDir)
.readdirSync(MONOREPO_ROOT_PATH)
.filter((dir) => dir !== '.DS_Store')
const languageResources = {} as any
namespaces.forEach((namespace) => {
const namespacePath = path.join(localesDir, namespace)
const namespacePath = path.join(MONOREPO_ROOT_PATH, namespace)
const files = fs
.readdirSync(namespacePath)
.filter((file) => file.endsWith('.json'))

View File

@@ -1,19 +1,13 @@
import { readFileSync } from 'node:fs'
import path from 'node:path'
import type { Plugin } from 'vite'
const dirname = path.dirname(new URL(import.meta.url).pathname)
export function manifestInjectPlugin(): Plugin {
// 定位到 manifest 文件的实际位置
const manifestPath = path.resolve(
dirname,
'../../packages/data/src/photos-manifest.json',
)
import { MANIFEST_PATH } from './__internal__/constants'
export function manifestInjectPlugin(): Plugin {
function getManifestContent(): string {
try {
const content = readFileSync(manifestPath, 'utf-8')
const content = readFileSync(MANIFEST_PATH, 'utf-8')
return content
} catch (error) {
console.warn('Failed to read manifest file:', error)
@@ -26,10 +20,10 @@ export function manifestInjectPlugin(): Plugin {
configureServer(server) {
// 监听 manifest 文件变化
server.watcher.add(manifestPath)
server.watcher.add(MANIFEST_PATH)
server.watcher.on('change', (file) => {
if (file === manifestPath) {
if (file === MANIFEST_PATH) {
console.info(
'[manifest-inject] Manifest file changed, triggering HMR...',
)

View File

@@ -1,8 +1,8 @@
import type { Plugin } from 'vite'
import { cleanupOldOGImages } from '../scripts/cleanup-og-images.js'
import { generateFavicons } from '../scripts/generate-favicon.js'
import { generateOGImage } from '../scripts/generate-og-image.js'
import { cleanupOldOGImages } from '../../../../scripts/cleanup-og-images.js'
import { generateFavicons } from '../../../../scripts/generate-favicon.js'
import { generateOGImage } from '../../../../scripts/generate-og-image.js'
interface OGImagePluginOptions {
title?: string

View File

@@ -13,13 +13,13 @@ import { createHtmlPlugin } from 'vite-plugin-html'
import tsconfigPaths from 'vite-tsconfig-paths'
import PKG from '../../package.json'
import { ogImagePlugin } from '../../plugins/og-image-plugin'
import { createDependencyChunksPlugin } from '../../plugins/vite/deps'
import { createFeedSitemapPlugin } from '../../plugins/vite/feed-sitemap'
import { localesJsonPlugin } from '../../plugins/vite/locales-json'
import { manifestInjectPlugin } from '../../plugins/vite/manifest-inject'
import { siteConfig } from '../../site.config'
import { astPlugin } from './plugins/vite/ast'
import { createDependencyChunksPlugin } from './plugins/vite/deps'
import { createFeedSitemapPlugin } from './plugins/vite/feed-sitemap'
import { localesJsonPlugin } from './plugins/vite/locales-json'
import { manifestInjectPlugin } from './plugins/vite/manifest-inject'
import { ogImagePlugin } from './plugins/vite/og-image-plugin'
const __dirname = path.dirname(fileURLToPath(import.meta.url))

View File

@@ -224,7 +224,6 @@
"loading.heic.main": "HEIC",
"loading.webgl.building": "高品質テクスチャを構築中...",
"loading.webgl.main": "WebGL テクスチャの読み込み",
"photo.conversion.transmux": "トランスマックス",
"photo.conversion.webcodecs": "WebCodecs",
"photo.copy.error": "画像のコピーに失敗しました。後でもう一度お試しください。",
"photo.copy.image": "画像をコピー",