diff --git a/build/plugins/i18n.js b/build/plugins/i18n.js deleted file mode 100644 index 1d56c79..0000000 --- a/build/plugins/i18n.js +++ /dev/null @@ -1,29 +0,0 @@ -import fs from 'node:fs/promises'; -import path from 'node:path'; - -export default (locale) => { - const map = fs - .readFile( - path.resolve(import.meta.dirname, '../../locales/', `${locale}.json`), - { encoding: 'utf8' }, - ) - .then(JSON.parse); - return { - resolveId(id) { - if (id.startsWith('at/i18n/')) { - return id; - } - return null; - }, - async load(id) { - if (id.startsWith('at/i18n/')) { - const key = id.replace(/at\/i18n\/(.+)/, '$1'); - const value = (await map)[key]; - if (!value) { - throw new Error('i18n key not found'); - } - return `export default ${JSON.stringify(value)}`; - } - }, - }; -}; diff --git a/build/rollup.js b/build/rollup.js index fbeb435..f0fcd7c 100644 --- a/build/rollup.js +++ b/build/rollup.js @@ -1,6 +1,5 @@ import devServer from './plugins/dev-server/index.js'; import generateTemplate from './plugins/generate-template.js'; -import i18n from './plugins/i18n.js'; import { readJson, ensureValue } from './utils.js'; import alias from '@rollup/plugin-alias'; import commonjs from '@rollup/plugin-commonjs'; @@ -14,7 +13,10 @@ import virtual from '@rollup/plugin-virtual'; import { dataToEsm } from '@rollup/pluginutils'; import autoprefixer from 'autoprefixer'; import cssnano from 'cssnano'; +import fs from 'node:fs/promises'; import { resolve } from 'node:path'; +import path from 'node:path'; +import * as R from 'remeda'; import postcss from 'rollup-plugin-postcss'; import { swc } from 'rollup-plugin-swc3'; import { visualizer } from 'rollup-plugin-visualizer'; @@ -26,16 +28,28 @@ const release = await readJson('./release.json'); export async function rollupOptions(config) { async function buildInputOptions() { + const i18nMap = await fs + .readFile( + path.resolve( + import.meta.dirname, + '../locales/', + `${config.locale}.json`, + ), + { encoding: 'utf8' }, + ) + .then(JSON.parse); /** @type {import('rollup').InputOptions} */ return { input: 'entry', plugins: [ - i18n(config.locale), virtual({ 'at/options': dataToEsm(templates[config.id]), 'at/locale': dataToEsm({ locale: config.locale, }), + 'at/i18n': dataToEsm( + R.mapKeys(i18nMap, (key) => `t${R.capitalize(key)}`), + ), entry: buildEntry(), }), replace({ diff --git a/src/components/about.tsx b/src/components/about.tsx index 04cdc01..be513c2 100644 --- a/src/components/about.tsx +++ b/src/components/about.tsx @@ -1,4 +1,4 @@ -import packageJson from '../../package.json'; +import { version } from '../../package.json'; import { locale } from 'at/locale'; import clsx from 'clsx'; @@ -21,7 +21,7 @@ export const EnAbout = () => (

- Current version: {packageJson.version},{' '} + Current version: {version},{' '} check update
@@ -44,7 +44,7 @@ export const ZhAbout = () => (

- 当前版本: {packageJson.version},{' '} + 当前版本: {version},{' '} 检查更新
diff --git a/src/components/card-shell.tsx b/src/components/card-shell.tsx index 657d70d..0e3feb2 100644 --- a/src/components/card-shell.tsx +++ b/src/components/card-shell.tsx @@ -13,10 +13,7 @@ import { import { TimerBlock } from './timer'; import { useBack } from '@/hooks/use-back'; import { useField } from '@/hooks/use-field'; -import tAbout from 'at/i18n/about'; -import tAnswer from 'at/i18n/answer'; -import tBack from 'at/i18n/back'; -import tTemplateSetting from 'at/i18n/templateSetting'; +import { tAbout, tAnswer, tBack, tTemplateSetting } from 'at/i18n'; import { locale } from 'at/locale'; import clsx from 'clsx'; import { useAtomValue } from 'jotai'; diff --git a/src/components/settings.tsx b/src/components/settings.tsx index 6d7add0..6f71555 100644 --- a/src/components/settings.tsx +++ b/src/components/settings.tsx @@ -1,18 +1,20 @@ import { About } from './about'; import { Checkbox } from './checkbox'; import { atomWithLocalStorage } from '@/utils/storage'; -import tBiggerText from 'at/i18n/biggerText'; -import tBlurOptions from 'at/i18n/blurOptions'; -import tBlurOptionsDetail from 'at/i18n/blurOptionsDetail'; -import tHideAbout from 'at/i18n/hideAbout'; -import tHideQuestionType from 'at/i18n/hideQuestionType'; -import tHideQuestionTypeDetail from 'at/i18n/hideQuestionTypeDetail'; -import tHideTimer from 'at/i18n/hideTimer'; -import tNoScroll from 'at/i18n/noScroll'; -import tRandomOption from 'at/i18n/randomOption'; -import tRandomOptionDetail from 'at/i18n/randomOptionDetail'; -import tSelMenu from 'at/i18n/selMenu'; -import tSelMenuDetail from 'at/i18n/selMenuDetail'; +import { + tBiggerText, + tBlurOptions, + tBlurOptionsDetail, + tHideAbout, + tHideQuestionType, + tHideQuestionTypeDetail, + tHideTimer, + tNoScroll, + tRandomOption, + tRandomOptionDetail, + tSelMenu, + tSelMenuDetail, +} from 'at/i18n'; import { id } from 'at/options'; import { useAtom } from 'jotai'; import { FC } from 'react'; diff --git a/src/components/timer.tsx b/src/components/timer.tsx index 13c1a73..d3c18d4 100644 --- a/src/components/timer.tsx +++ b/src/components/timer.tsx @@ -4,17 +4,19 @@ import { hideTimerAtom } from './settings'; import { atomWithLocalStorage } from '@/utils/storage'; import useCountDown from 'ahooks/es/useCountDown'; import useCreation from 'ahooks/es/useCreation'; -import tClose from 'at/i18n/close'; -import tDay from 'at/i18n/day'; -import tDefaultTimerTitle from 'at/i18n/defaultTimerTitle'; -import tHour from 'at/i18n/hour'; -import tMinute from 'at/i18n/minute'; -import tSecond from 'at/i18n/second'; -import tSetting from 'at/i18n/setting'; -import tTargetDate from 'at/i18n/targetDate'; -import tTimer from 'at/i18n/timer'; -import tTimerSetting from 'at/i18n/timerSetting'; -import tTimerTitle from 'at/i18n/timerTitle'; +import { + tClose, + tDay, + tDefaultTimerTitle, + tHour, + tMinute, + tSecond, + tSetting, + tTargetDate, + tTimer, + tTimerSetting, + tTimerTitle, +} from 'at/i18n'; import { useAtom, useAtomValue } from 'jotai'; import { FC, useState } from 'react'; diff --git a/src/entries/basic.tsx b/src/entries/basic.tsx index ddb5f61..414e0f7 100644 --- a/src/entries/basic.tsx +++ b/src/entries/basic.tsx @@ -2,7 +2,7 @@ import { CardShell } from '../components/card-shell'; import { AnkiField } from '@/components/field'; import { FIELD_ID } from '@/utils/const'; import { isFieldEmpty } from '@/utils/field'; -import tQuestion from 'at/i18n/question'; +import { tQuestion } from 'at/i18n'; import clsx from 'clsx'; export default () => { diff --git a/src/entries/mcq.tsx b/src/entries/mcq.tsx index 83c2d74..3e5e2f8 100644 --- a/src/entries/mcq.tsx +++ b/src/entries/mcq.tsx @@ -17,12 +17,14 @@ import { useAutoAnimate } from '@formkit/auto-animate/preact'; import useCreation from 'ahooks/es/useCreation'; import useMemoizedFn from 'ahooks/es/useMemoizedFn'; import useSelections from 'ahooks/es/useSelections'; -import tCorrectAnswer from 'at/i18n/correctAnswer'; -import tMissedAnswer from 'at/i18n/missedAnswer'; -import tMultipleAnswer from 'at/i18n/multipleAnswer'; -import tQuestion from 'at/i18n/question'; -import tSingleAnswer from 'at/i18n/singleAnswer'; -import tWrongAnswer from 'at/i18n/wrongAnswer'; +import { + tCorrectAnswer, + tMissedAnswer, + tMultipleAnswer, + tQuestion, + tSingleAnswer, + tWrongAnswer, +} from 'at/i18n'; import { locale } from 'at/locale'; import { fields } from 'at/options'; import clsx from 'clsx'; diff --git a/src/entries/tf.tsx b/src/entries/tf.tsx index 93b32d8..ab16ec4 100644 --- a/src/entries/tf.tsx +++ b/src/entries/tf.tsx @@ -7,8 +7,7 @@ import { extractTfItems } from '@/utils/extract-tf-items'; import { isFieldEmpty } from '@/utils/field'; import useCreation from 'ahooks/es/useCreation'; import useMemoizedFn from 'ahooks/es/useMemoizedFn'; -import tQuestion from 'at/i18n/question'; -import tYourWrongAnswer from 'at/i18n/yourWrongAnswer'; +import { tQuestion, tYourWrongAnswer } from 'at/i18n'; import clsx from 'clsx'; import { CheckCircle, XCircle, Triangle } from 'lucide-react'; import { useCallback } from 'react'; diff --git a/src/global.d.ts b/src/global.d.ts index f8342dc..c8b3647 100644 --- a/src/global.d.ts +++ b/src/global.d.ts @@ -7,10 +7,7 @@ declare module 'at/locale' { export const locale: 'en' | 'zh'; } -declare module 'at/i18n/*' { - const value: string; - export default value; -} +declare module 'at/i18n'; declare module '*.png' { const content: string;