npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2024 – Pkg Stats / Ryan Hefner

@restar-inc/re-i18n

v1.1.0

Published

A tool to manage i18n by extracting keys from source code and generating locale files

Downloads

1,321

Readme

Re-i18n

A tool to manage i18n by extracting keys from source code and generating locale files.

Usage

Locale Locator

Create a module that exports a function that returns the current locale. This function will be used to determine the locale of generated files. The path to this module must be specified in the generate.localeLocatorPath parameter of the configuration file. Depending on the configuration of your project (appType parameter), the implementation of the function will be different (for example, a Vue project may need to use reactivity, while a vanilla project may need to return a simple string).

import type { UseLocaleLocator } from "@restar-inc/re-i18n/lib/vendor/vue";
import { computed, ref } from "vue";

type Locale = "ja" | "en";

const innerLocale = ref<Locale>("ja");

const useLocaleLocator: UseLocaleLocator<Locale> = (locales, defaultLocale) => {
  return computed({
    get: () => innerLocale.value,
    set: (value) => {
      if (locales.includes(value)) {
        innerLocale.value = value;
      } else {
        innerLocale.value = defaultLocale;
      }
    },
  });
};

export default useLocaleLocator;

Formatter (optional)

If you need to format translations, create a module that exports a function that takes a key and a value as parameters and returns a formatted string. The path to this module must be specified in the generate.formatterPath parameter of the configuration file.

import formatString from "my-amazing-formatter-lib"; // just an example
import type { I18nFormatter } from "@restar-inc/re-i18n";

type Locale = "ja" | "en";

const fmt: I18nFormatter<Locale> = (locale, str, opts) => {
  return formatString(str, opts, locale);
};
export default fmt;

Configuration

Create a re-i18n.config.json file in the root of your project. Follow the example below to configure it. Refer to the ./src/schemas/config.ts file for details.

{
  "defaultLocale": "ja",
  "locales": ["ja", "en"],
  "appType": "vue",
  "pattern": "src/{app,lib}/**/*.{ts,vue}",
  "json": {
    "outDir": "./out/json"
  },
  "csv": {
    "outDir": "./out/csv",
    "inputDir": "./out/csv",
    "delimiter": ";"
  },
  "xls": {
    "outDir": "./out/xls",
    "inputDir": "./out/xls"
  },
  "generate": {
    "localeLocatorPath": "./src/i18n/useLocateLocator",
    "formatterPath": "./src/i18n/formatter"
  }
}

Translation Keys

After following the previous steps, you can use the t function to define translation keys in your source code. You can use a different name for the function by setting the funcName parameter in the configuration file.

Let's suppose you have the following code:

// src/lib/myAwesomeModule.ts

function sayHello(name: string) {
  return `こんにちわ${name}さん`;
}

// src/lib/MyAwesomeComponent.vue
<script setup lang="ts">
const props = defineProps({
  name: String,
});

const showAlert = () => alert(`おはようございます${props.name}さん`);
</script>

<template>
  <button @click="showAlert">こんばんは</button>
</template>

Set the keys as follows:

// src/MyAwesomeModule/hello.ts

function sayHello(name: string) {
  return t("こんにちわ{name}さん", { name });
}

// src/MyAwesomeModule/Component.vue
<script setup lang="ts">
const props = defineProps({
  name: String,
});

const showAlert = () => alert(
  t("おはようございます{name}さん", { name: props.name })
);
</script>

<template>
  <button @click=showAlert>{{ t("こんばんは") }}</button>
</template>

Next step is to run comman re-i18n generate. This will generate locale files in the out directory.

src/MyAwesomeModule
├── Component.vue
├── hello.ts
└── locales
    ├── en.json
    ├── index.ts
    └── ja.json
// src/MyAwesomeModule/locales/en.json
{
  "おはようございます{name}さん": "",
  "こんにちわ{name}さん": "",
  "こんばんは": ""
}

// src/MyAwesomeModule/locales/ja.json
{
  "おはようございます{name}さん": "",
  "こんにちわ{name}さん": "",
  "こんばんは": ""
}

Next step is to import t function from locale folder:

// src/MyAwesomeModule/hello.ts
import { t } from "./locales";
...

// src/MyAwesomeModule/Component.ts
<script setup lang="ts">
import { t } from "./locales";
...
</script>

Now you can put the translations in the locale files.

For more details, see the example directory.

Vendor Specific Features

Vue Reactivity

By default, the translation function returns a string. If you want to use reactivity, you can use the composable function useReI18n or its shortcut t.$.

// re-i18n.config.json
{
  "funcName": "t",
  "composableName": "useMyReI18n" // default `useReI18n`
}
// Component.vue
<script setup lang="ts">
import { t, useMyReI18n } from "./locales";

const MSG_1 = t("メッセージ 1"); // MSG_1 is `string`
const MSG_2 = t.$("メッセージ 2"); // MSG_2 is `ComputedRef<string>`
const MSG_3 = useMyReI18n("メッセージ 3"); // MSG_3 is `ComputedRef<string>`
</script>

NOTE: t.$ is just a shortcut for useReI18n, it works exactly the same way. A typical use in the <script setup> section is to use t.$ in nested object fields:

// Instead of this
import { t, useMyReI18n } from "./locales";
const msg1 = useMyReI18n("メッセージ 1");
const msg2 = useMyReI18n("メッセージ 2");

const MESSAGES = {
  msg1,
  msg2,
};

// You can do this
const MESSAGES = {
  msg1: t.$("メッセージ 1"),
  msg2: t.$("メッセージ 2"),
};

IMPORTANT: If you use t.$ inside object fields, such as const obj = { msg: t.$("message") }, reactivity will work, but you will have to manually unwrap the value with obj.msg.value. This is not related to this package, but is a limitation of Vue.

<script setup lang="ts">
import { t } from "./locales";

const MSG_1 = t.$("メッセージ 1");
const MSG_2 = {
  msg: t.$("メッセージ 2");
}
</script>
<template>
  <p>{{ MSG_1 }}</p><!-- メッセージ 1 -->
  <p>{{ MSG_2.msg }}</p><!-- "メッセージ 2" -->
  <p>{{ MSG_2.msg.value }}</p><!-- メッセージ 2 -->
</template>

Vue Component

You can also use vendor specific features. For example, if you are using Vue, you can use the ReI18n component to display translation keys in source code and use VDOM nodes as parameters.

IMPORTANT: If you use t inside child nodes, reactivity will not work

First you need to specify the component name in the configuration file.

{
  "componentName": "MyI18n" // default `ReI18n`
}

Then you can use it in your source code.

<script setup lang="ts">
import { MyI18n } from "./locales";
</script>

<template>
  <MyI18n msg="赤い:{0} 緑:{1} 青い:{2}">
    <div class="bg-red-400 w-10 h-10 rounded-full"></div>
    <div class="bg-green-400 w-10 h-10 rounded-full"></div>
    <div class="bg-blue-400 w-10 h-10 rounded-full"></div>
  </MyI18n>
</template>

Commands

Depending on your project configuration (funcName param),

This package provides the CLI command re-i18n. Run it in the root of your project.

re-i18n --help

generate

Generates locale files from source code. Uses the pattern and appType parameters defined in the configuration file to parse the source code, read the i18n keys, generate the i18n files, and write them to the dirName directory. It also uses the generator.localeLocatorPath and generator.formatterPath functions defined in the config file to generate the main module in each locale directory.

export-json

Creates a JSON file from the source code and the i18n keys found. This is essentially an AST representation of the code used to generate i18n files. It is not intended for direct use.

export-csv

For each language, a CSV file is created from the source code and the i18n keys found.

export-xls

Creates an XLS file from the source code and the i18n keys found.

import-csv

For each locale, it will read the CSV file and overwrite the i18n files with the new values.

import-xls

Reads the XLS file and overwrites the i18n files with the new values.

stats

Displays statistics on the number of keys in each locale.

lint

Checks for missing and obsolete keys in the source code and i18n files.