vue-i18n-customized-extractor
Version:
A CLI tool to extract text and i18n keys from Vue.js files.
308 lines (235 loc) • 10.6 kB
Markdown
# vue-i18n-customized-extractor
`vue-i18n-customized-extractor` is a CLI tool designed to streamline translation efforts in Vue.js projects. It helps developers efficiently manage translation keys by identifying text requiring translation and extracting existing keys used in the codebase. This ensures translation files are optimized, comprehensive, and up-to-date.
## Features
- **Translation Key Extraction**: Extract i18n keys and values from Vue.js templates, scripts, and `.js` or `.ts` files.
- **Custom Component Prop Extraction**: Extract text requiring translation from user-defined component props, configurable via a mapping file.
- **Key Usage Tracking**: Optionally extract used i18n keys to identify unused keys for cleanup and detect missing keys to ensure comprehensive translations.
- **Localization Efficiency**: Streamline the process of translating English content into other languages.
- **Translation File Generation**: Automatically generate `src/locales/en.json` and `src/locales/en-TranslateAsWholePointer.json` files after running the tool, ensuring extracted keys are organized and ready for translation.
### Key Depth Limitation
The tool enforces a maximum depth of two levels for `$t()` call keys. For example:
- **Recommend**: `TestPage['Hello']`
- **Not Recommend**: `TestPage['HiKKT nested { name }']['nested name']`
Keys exceeding this depth won't be divided into multiple levels but will be displayed as a single cohesive unit. For example:
- `TestPage['HiKKT nested { name }']['nested name']` will be extracted as:
```json
{
"TestPage['HiKKT nested { name }']['nested name']": "TestPage['HiKKT nested { name }']['nested name']"
}
```
### Translation Key Depth Approach
The tool enforces a maximum depth of two levels for `$t()` keys, simplifying translation mapping and debugging. The first level typically represents the page or section, such as `TestPage`, reducing conflicts between different pages or sections. The second level contains specific translation keys, ensuring simplicity and ease of maintenance for the mapping for each page or section. By limiting the depth, the tool streamlines tracing and debugging of `$t()` keys, promoting organized and efficient mapping for each page or section.
## Installation
### Local Installation (Recommended)
```bash
npm install vue-i18n-customized-extractor
```
### Global Installation
```bash
npm install -g vue-i18n-customized-extractor
```
## Usage
To use the CLI tool, run it in your project directory:
### Local Installation
If the tool is installed locally within your project:
```bash
npx vue-i18n-customized-extractor [options]
```
### Global Installation
If the tool is installed globally:
```bash
vue-i18n-customized-extractor [options]
```
### Options
- `--path=<target>`: Specify the target file or folder to analyze. Defaults to `./src` if not provided.
- `--include-t`: Include `$t()` function calls in the extraction process for a comprehensive overview of active translation keys.
- `--config=<path>`: Specify a custom configuration file (`.cjs`) for advanced settings. Defaults to `vue-i18n-customized-extractor.config.cjs` in the project directory.
- `--keys=<key1,key2,...>`: Extract translation keys for specific components based on mappings in the configuration file.
- `--template-only`: Extract only from the template part of `.vue` files.
- `--help`: Display help information.
### Examples
1. Extract i18n keys from the `src` directory:
```bash
vue-i18n-customized-extractor --path=./src
```
2. Extract i18n keys from `src/components` and include `$t()` calls:
```bash
vue-i18n-customized-extractor --path=./src --include-t
```
3. Extract together with keys for specific components under `TestPage` and `OrderPage`:
```bash
vue-i18n-customized-extractor --path=./src --include-t --keys=TestPage,OrderPage
```
After running the tool, the extracted keys are saved into two files:
- `src/locales/en.json`: Contains regular translation keys.
- `src/locales/en-TranslateAsWholePointer.json`: Contains keys extracted from elements marked with `translate-as-whole-pointer`.
## Configuration
Create a configuration file (`vue-i18n-customized-extractor.config.cjs`) for customized component mappings:
### Configuration File Structure
The configuration file (`vue-i18n-customized-extractor.config.cjs`) must include a fixed field name `customizedComponentsTranslationMap`. This field defines the mapping of custom components to their translatable props. Below is an example configuration:
```javascript
module.exports = {
// Mapping of custom components to their translatable props
customizedComponentsTranslationMap: {
ResponsiveButton: ['display_name'],
SimplifiedNotification: ['title', 'content'],
HelloWorldPage: {
ResponsiveButton: ['display_name']
},
}
};
```
### Key Mapping Example
- `TestPage` may include `SimplifiedNotification: ['title']`.
- `OrderPage` may include `SimplifiedNotification: ['content']` and `ResponsiveButton: ['display_name']`.
When multiple keys are specified, the tool consolidates mappings for streamlined management:
```javascript
{
SimplifiedNotification: ['title', 'content'],
ResponsiveButton: ['display_name']
}
```
If no keys are specified, the tool parses the entire mapping under `customizedComponentsTranslationMap`, ensuring all translatable props are extracted.
## Element Extraction
Elements marked with `translate-as-whole-pointer` are extracted as a single cohesive unit, ensuring all text and translation keys within the element are captured accurately.
### Regular Examples
1. **Static Text**:
```html
<div>Welcome to the app</div>
```
**Result**: `"Welcome to the app": "Welcome to the app"`
2. **Dynamic Content**:
```html
<div>Hello, {{ user.name }}</div>
```
**Result**: `"Hello, { user.name }": "Hello, { user.name }"`
3. **Translation Function `$t()`**:
```html
<div>{{$t('welcome_message')}}</div>
```
**Result**: `"welcome_message": "welcome_message"`
*Note: This will only be extracted when using the `--include-t` option. Without this option, `$t()` calls will be skipped.*
4. **Dynamic Content with Interpolation**:
```html
<div>Hi {{ name }}</div>
```
**Result**: `"Hi { name }": "Hi { name }"`
5. **Template Literal Interpolation**:
```html
<div>{{ `Hei ${name} literal` }}</div>
```
**Result**: `"Hei ${name} literal": "Hei {name} literal"`
6. **Translation Function with Interpolation**:
```html
<div>{{$t("TestPage['HiKKT { name }']", {name: name})}}</div>
```
**Result**:
```json
{
"TestPage": {
"HiKKT { name }": "HiKKT { name }"
}
}
```
*Note: This will only be extracted when using the `--include-t` option. Without this option, `$t()` calls will be skipped.*
7. **Translation Function with Static Key**:
```html
<div>{{$t('Hello')}}</div>
```
**Result**: `"Hello": "Hello"`
*Note: This will only be extracted when using the `--include-t` option. Without this option, `$t()` calls will be skipped.*
8. **Translation Function with Dynamic Key**:
```html
<div>{{$t('Hit { name }', {name: name})}}</div>
```
**Result**: `"Hit { name }": "Hit { name }"`
*Note: This will only be extracted when using the `--include-t` option. Without this option, `$t()` calls will be skipped.*
9. **Conditional Interpolation**:
```html
<div>{{name ? "interpolation 1" : "interpolation 2"}}</div>
```
**Result**: `"interpolation 1": "interpolation 1", "interpolation 2": "interpolation 2"`
10. **Conditional Translation Function**:
```html
<div>{{name ? $t("TestPage['interpolation 1 tkey']") : $t("TestPage['interpolation 2 tkey']")}}</div>
```
**Result**:
```json
{
"TestPage": {
"interpolation 1 tkey": "interpolation 1 tkey",
"interpolation 2 tkey": "interpolation 2 tkey"
}
}
```
*Note: This will only be extracted when using the `--include-t` option. Without this option, `$t()` calls will be skipped.*
11. **Logical Expression with Static Text**:
```html
<div>{{test_array?.['1'] ?? "Logical Expr 1"}}</div>
```
**Result**: `"Logical Expr 1": "Logical Expr 1"`
12. **Logical Expression with Template Literal**:
```html
<div>{{test_array?.['1'] ?? `Logical Expr 1 ${name} literal`}}</div>
```
**Result**: `"Logical Expr 1 { name } literal": "Logical Expr 1 { name } literal"`
13. **Logical Expression with Translation Function**:
```html
<div>{{test_array?.['1'] ?? $t("TestPage['Logical Expr ${name} t keys']")}}</div>
```
**Result**:
```json
{
"TestPage": {
"Logical Expr { name } t keys": "Logical Expr { name } t keys"
}
}
```
*Note: `$t()` calls will only be extracted when using the `--include-t` option. Without this option, `$t()` calls will be skipped.*
### Nested Examples
1. **Static Text with Nested Elements**:
```html
<div class="translate-as-whole-pointer">test <span>bold</span></div>
```
**Result**: `"test <bold>": "test <bold>"`
2. **Dynamic Content with Nested Elements**:
```html
<div class="translate-as-whole-pointer">123 {{ name }} <span> bold </span></div>
```
**Result**: `"123 { name } < bold >": "123 { name } < bold >"`
3. **Translation Function `$t()` with Nested Elements**:
```html
<div class="translate-as-whole-pointer">{{$t('TestPage[key1]')}} <span>{{$t('TestPage[key2]')}}</span></div>
```
**Result**:
```json
{
"TestPage": {
"key1": "key1",
"key2": "key2"
}
}
```
*Note: These keys will be grouped under "Existing $t() calls' keys for translate-as-whole-pointer" in `en-TranslateAsWholePointer.json`.*
## Supported Cases
### Parsing and Extraction
- Extract translation keys from Vue templates, scripts, and `.js` or `.ts` files.
- Extract text from user-defined component props.
- Detect unused and missing keys for cleanup and comprehensive translations.
### Result Expectations
- **Comprehensive Key Coverage**: Complete overview of active and missing keys.
- **Optimized Translation Files**: Up-to-date and free of unused keys.
## Contribution
Feel free to contribute by submitting issues or pull requests to improve the tool.
## License
This project is licensed under the MIT License.