-
-
Notifications
You must be signed in to change notification settings - Fork 409
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
implement i18n package #613
Conversation
Created `initializeWSS` function to encapsulate WebSocket setup. Modified watch-rebuild-plugin to use this new function, promoting code reuse and simplifying maintenance.
Moved HMR code extraction logic to a new `getTranspiledHMRCode` module. This improves code organization and simplifies the `watch-rebuild-plugin.ts` file by removing file reading and path resolution logic.
Integrated multilingual support for the Chrome extension by adding an i18n package with locale files for English and Korean. Implemented translation functions for both development and production environments. Updated `turbo.json` to include i18n build outputs and added necessary configurations and scripts.
Integrate i18n library to handle translations in the NewTab component. Updated the package dependencies and made necessary code changes to utilize i18n for text rendering.
This reverts commit 04cc2fb.
This reverts commit a59a181.
Added detailed usage instructions and installation guide to README. Refactored the i18n translation functions to streamline message key substitutions, removing unnecessary options and simplifying the API.
Added a caution note to use placeholders with spaces in messages. Adjusted example code in `messages.json` to reflect the correct placeholder format.
A minor correction was made to the example code in the README.md for accurate representation of the formatted output. This change ensures that the spacing in the console.log output aligns with expected results.
Renamed i18n_dev.ts to i18n-dev.ts and i18n_prod.ts to i18n-prod.ts. Updated import statements to reflect the new file names. This change ensures consistency and improves readability in the codebase.
Renamed the import alias `mock` to `t_dev_or_prod` for the i18n module. This change ensures a clearer and more accurate representation of the import's purpose in both development and production environments.
Introduce scripts to auto-generate locale message imports and types. This improves maintainability by ensuring consistency across locale handling and reduces manual intervention by automatically generating necessary files from existing locales.
Add script to automate the i18n file generation. Modify build and ready scripts to include i18n generation step, ensuring the latest localization data is always included.
Removed excessive punctuation from the "toggleTheme" message. This improves readability and aligns with other translations.
Introduce documentation on how to add or delete languages in the i18n package. Simplify type checking logic in generate-i18n.mjs to ensure language keys are correctly validated.
Deleted the redundant `messages.json` file from the `en` locale folder in the Chrome extension. This cleanup helps in maintaining a more streamlined codebase by removing unnecessary files.
Moved esbuild configurations and logic into a shared build function in build.mjs. Created build.prod.mjs and simplified build.dev.mjs to use the new build function.
Removed .tsx files from the build entry points to avoid unnecessary bundling of React components. This ensures the build process only includes TypeScript files under the ./lib directory.
Renamed the `genenrate-i8n.mjs` file to `genenrate-i18n.mjs`. Updated the script in `package.json` to reflect this change, ensuring consistency and correct execution.
Refactor default locale logic to check for exact and region-less matches from supported locales. This enhances accuracy and fallbacks by considering predefined locales before defaulting to the first available locale.
Replace double quotes with single quotes in locale JSON string and ensure consistent single quotes in locale handling. This resolves potential issues with locale detection in different environments.
Reorder the "message" and "description" fields for consistency in both English and Korean locale files. This change improves readability and maintainability of the translation files.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
- pnpm script for generating, should be located in the root(I think good idea is create a pointing script, which run this nested(from i18n) script in root), like other scripts, because until now we was using only root package.json and magic happened in the subfolders :)
I think this should work on the same way. - There's no function to change language in real time, i mean by user(switching between languages).
- Move all 'build.' and 'generate ...' file into 'builders' folder(maybe it should be inside lib?)
After all it's amazing, because it works in all pages, if you want to implement it without turborepo/modules pattern, it's tricky to work properly in background because i was implementing it on legacy version on my project ;)
|
||
export function getMessageFromLocale(locale: string) { | ||
switch (locale) { | ||
${locales.map((locale) => ` case '${locale}': |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
${locales.map((locale) => ` case '${locale}': | |
const {message} = await import('../locales/${locale}/messages.json').join("\n") | |
if (message) { | |
return message | |
}else { | |
throw new Error('Unsupported locale'); | |
} |
That's pseudocode, what do you think about this?
https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/import
I think it's better to use dynamic import for that because of so many languages we have.
I know it's build file, but anyway, it could be smaller, each language is next switch case.
With my approach it's almost one liner.
If sb want to use 30 languages, have 30 cases and 30 imports.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
When we use dynamic import, we have the constraint that the function must be called asynchronously.
However, the problem you suggest is reasonable and I'll have to think about it.
I'm currently maintaining a product in my company that supports 15 different languages, and each language file is about 500kB in size, so obviously the issue of optimizing for multiple languages and dynamic importing becomes very important at this scale.
But what if it's a Chrome extension, not a webpage, and the issue only occurs during the development phase...?
I guess it doesn't really matter. 🤔
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It depends of the extension complexity, as you say.
This solution is good, but if you have better idea, try to implement it, sth more generic.
} | ||
|
||
export const t = (...args: Parameters<typeof translate>) => { | ||
return removePlaceholder(translate(...args)); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I looking for that, and my thoughts about it have destroyed xD
I think substitusion is placeholders.
PLS create more examples and explanation in README 🔥
|
||
const NewTab = () => { | ||
const theme = useStorageSuspense(exampleThemeStorage); | ||
const isLight = theme === 'light'; | ||
const logo = isLight ? 'new-tab/logo_horizontal.svg' : 'new-tab/logo_horizontal_dark.svg'; | ||
|
||
console.log(t('hello', 'World')); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
OO there's some example, but as i type above, this should be also in README 😸
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I thought I documented it well enough in the README.md in the i18n package, but what do you think?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think, if you implement 'placeholder' filed in json, there's no need to create more clarification, but no it's a little tricky to use it 😆
I didn't test the behavior in the background! I'll check the behavior, and it's true that it does rely on the behavior of Turborepo (more precisely on the watch function). I thought it would be a good way to do it with less effort :) |
@Jonghakseo It's working good in background in this version :)
I was implementing language switching on my project some times ago. I think if it will be build in, this could be good to our users, let's think about it a little 😸 |
I've been thinking about it again,
|
|
@Jonghakseo Now users can define 'placeholder' prop in json? |
Co-authored-by: PatrykKuniczak <64608510+PatrykKuniczak@users.noreply.github.com>
I added example on README.md :) |
@PatrykKuniczak I'm gonna merge this for now, and enahnce the documentation! |
Priority*
Purpose of the PR*
Add I18n Package for internationalize in chrome extension
Changes*
Add I18n Package
The i18n package has two main functions.
First, it offers the
t
(translate) function, ensuring strong type safety and ease of development for managing multiple languages.The
t
function behaves exactly the same aschrome.i18n.getMessage
in production. However, it is implemented as a dev-only function to allow developers to see quick results without reloading the extension.This ensures that features like HMR work as expected while also providing strong type safety by inferring the key values of the messages entered in message.json.
Secondly, developers do not need to manually update the utility functions for type inference whenever adding or removing languages. Through the
generate-i18n.mjs
file, simply creating or deleting folders and new JSON files is sufficient to prepare support for new languages.Add Usage into
NewTab.tsx
How to check the feature
2024-07-27.11.28.03.mov
Reference
https://developer.chrome.com/docs/extensions/reference/api/i18n
https://developer.chrome.com/docs/extensions/how-to/ui/localization-message-formats#placeholders