A full process toolchain to improve i18n performance and efficiency.
Please visit @ts-intl/integration.
Package | Version |
---|---|
@ts-intl/integration | |
@ts-intl/dependency | |
@ts-intl/dictionary | |
@ts-intl/eslint-plugin-ts-intl | |
@ts-intl/shared | |
@ts-intl/translator |
type ProjectConfig = {
path: {
base: string; // project base path(root)
// paths below all relative to base
dictionary: string; // locale dictionary(direction) path
entry: string; // entry(directory) path to collect dependencies
cache: string; // cache(directory) path to store dependencies cache
};
locale: {
basic: string; // basic locale, fallback to this locale when key not found in current locale
others: string[]; // other locales
};
syntax: {
nsDivider: string; // namespace divider
keyDivider: string; // key divider
};
integration: {
funcNamePattern: string; // translate function name pattern to match
hookNamePattern: string; // hook(generate translate function) name pattern to match
richNamePattern: string; // translate rich function name pattern to match
};
translator?: {
// translator options
completionOptions?: {
preset?: {
override?: boolean;
presets?: {
role: 'system' | 'user' | 'assistant';
content: string;
name?: string;
}[];
};
};
descriptions?: Record<string, string | undefined>;
};
madgeConfig: MadgeConfig; // https://github.com/DefinitelyTyped/DefinitelyTyped/blob/master/types/madge/index.d.ts
};
pnpm i @ts-intl/shared
npx ts-intl-init
Then edit ts-intl.config.ts
to fit your project.
import { Project } from '@ts-intl/shared';
// rootPath is dir path where ts-intl.config.ts is located
const project = new Project(rootPath);
// when config file is stable
const projectSingleton = Project.getSingleton(rootPath);
pnpm i @ts-intl/eslint-plugin-ts-intl
npx ts-intl-rules
Extends ts-intl.eslintrc.js
in your eslint config file.
pnpm i @ts-intl/translator
npx ts-intl-init-translator
Then edit translator-flow.yml
and translator-shared.yml
to fit your project.
pnpm i @ts-intl/dictionary
import { Project } from '@ts-intl/shared';
import { extractProjectDictionary, extractProjectDictionaryWithLocale } from '@ts-intl/dictionary';
const project = new Project(rootPath);
const dictionary = extractProjectDictionary(project, { reader }); // optional: custom reader to cache read file
const dictionaryWithLocale = extractProjectDictionaryWithLocale(project, locale, {
reader,
include, // include ns path
exclude, // optional: exclude ns path
entry, // optional: entry path to match keys in dependencies cache file
});
Then inject dictionary into HTML.
Directly use it if dictionaryWithLocale
is injected,
otherwise if dictionary
is injected:
import { extractDictionary } from '@ts-intl/dictionary';
const dictionaryWithLocale = extractDictionary(
dictionary[locale],
dictionary[basicLocale],
include, // include ns path
exclude, // optional: exclude ns path
);
pnpm i @ts-intl/dependency
import { Project } from '@ts-intl/shared';
import { cacheDependenciesRes } from '@ts-intl/dependency';
const project = new Project(rootPath);
cacheDependenciesRes(project);
Recommend use it in production
:
- build with script above
- pass
entry
toextractProjectDictionaryWithLocale
Which would optimize dictionary size by only including keys which current page really used.
Work with VSC extension lokalise.i18n-ally
Help to make project more substantial and efficient.
.vscode/settings.json
:
{
"i18n-ally.localesPaths": ["src/locales"], // your locale dictionary path
"i18n-ally.enabledParsers": ["js", "ts", "json"],
"i18n-ally.keystyle": "nested",
"i18n-ally.pathMatcher": "{locale}/{namespaces}.json",
"i18n-ally.namespace": true,
"i18n-ally.extract.parsers.html": {
"attributes": ["text", "title", "alt", "placeholder", "label", "aria-label"], // you can add more
"ignoredTags": ["script", "style"], // you can add more
"inlineText": true
}
}
.vscode/extensions.json
:
{
"recommendations": ["lokalise.i18n-ally"]
}
.vscode/i18n-ally-custom-framework.yml
:
# .vscode/i18n-ally-custom-framework.yml
languageIds:
- javascript
- typescript
- javascriptreact
- typescriptreact
usageMatchRegex:
# The following example shows how to detect `t("your.i18n.keys")`
# the `{key}` will be placed by a proper keypath matching regex,
# you can ignore it and use your own matching rules as well
- "[^\\w\\d]t\\(['\"`]({key})['\"`]"
- "[^\\w\\d]t\\.rich\\(['\"`]({key})['\"`]"
# If set to true, only enables this custom framework (will disable all built-in frameworks)
monopoly: true