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 🙏

© 2025 – Pkg Stats / Ryan Hefner

@fatesigner/i18n

v2.0.0

Published

i18n 国际化工具库

Downloads

5

Readme

i18n

npm download commitizen

i18n 国际化工具库

安装

npm i -S @fatesigner/i18n

使用

src/i18n/messages.ts

import { createLocaleMessages } from '@fatesigner/i18n';

// 先创建一份本地化环境对象并导出
export const i18nMessages = createLocaleMessages({
  app: {
    name: '',
    sidebar: {
      shrink: '',
      unfold: ''
    },
    settings: {
      title: ''
    }
  }
});

// 导出本地化环境对象类型
export type I18nMessagesType = typeof i18nMessages;
<template>
  <!-- 传统方式:字符串 -->
  <div class="flex items-center p-5 border-4 border-indigo-600">
    <p>app.name: {{ $t('app.name') }}</p>
    <p>app.sidebar.shrink: {{ $t('app.sidebar.shrink') }}</p>
  </div>
  <!-- I18nx createLocaleMessages 创建的 messages 可直接通过变量方式传入 $t,结合 typescript 从而获得强类型提示和检查的特性 -->
  <div class="flex items-center p-5 border-4 border-indigo-600">
    <p>app.name: {{ $t(i18nMessages.app.name) }}</p>
    <p>app.sidebar.shrink: {{ $t(i18nMessages.app.sidebar.shrink) }}</p>
  </div>
</template>

<script lang="ts">
import { defineComponent } from 'vue';

import { i18nMessages } from './i18n/messages';

export default defineComponent({
  setup(){
    // 将输出: "app.name"
    console.log(i18nMessages.app.name);
    return {
      i18nMessages
    }
  }
});
</script>

src/i18n/langs/zh-CN.ts

根据类型配置对应的语言环境消息

import { I18nMessagesType } from '../messages';

// 中文
export default {
  app: {
    name: 'i18n 国际化',
    sidebar: {
      shrink: '折叠',
      unfold: '展开'
    },
    settings: {
      title: '标题'
    }
  }
} as I18nMessagesType;

src/i18n/langs/en-US.ts

import { I18nMessagesType } from '../messages';

// 英语
export default {
  app: {
    name: 'i18n locale',
    sidebar: {
      shrink: 'Shrink',
      unfold: 'Unfold'
    },
    settings: {
      title: 'Title'
    }
  }
} as I18nMessagesType;

src/i18n/index.ts

import { I18nLanguageType, createVueI18n } from '@fatesigner/i18n';

// 定义默认显示语言,该变量可从缓存、环境变量中获取
const defaultLang: I18nLanguageType = 'zh_CN';

// 创建 i18n 实例
export const i18n = createVueI18n(
  {
    locale: defaultLang,
    messages: {
      // 同步加载默认语言包,因为使用按需加载的方式,所以在此不导入其他语言包
      [defaultLang]: require(`./langs/${defaultLang}`).default
    },
    // 是否使用 vue-i18n Legacy API 模式,默认为 true
    legacy: true,
    // 当前不存在 message 键时,将会显式回退到指定的语言环境
    fallbackLocale: defaultLang,
    // 只保留那些完全没有翻译给定关键字的警告
    silentFallbackWarn: true
  },
  {
    // 定义您的本地化环境信息加载的方式,当调用 i18n.set('zh-CN') 时执行
    loadLocale(langs) {
      return import(`./langs/${langs}`).then(async (msg) => {
        return msg.default;
      });
    }
  }
);

// 注册勾子,当语言包加载完成后执行
i18n.hooks.afterSet.tap(function (langs: I18nLanguageType) {
  // 动态改变您的 http request header,让服务器能提供支持的语言
  Axios.defaults.headers.common['Accept-Language'] = langs;
  // 改变当前 html 的 langs 标签
  document.querySelector('html').setAttribute('langs', langs);
});

src/plugins/dayjs.ts

如果您的应用使用了类似 dayjs 的插件,这些插件拥有自己的国际化加载方式,您可以注册 i18n 的 afterSet 钩子

import dayjs from 'dayjs';

import { i18n } from '../i18n';

// 定义 dayjs 的语言包加载方式
const loadDayjsLang = async (langs: I18nLanguageType) => {
  if (langs === 'zh-CN') {
    import('dayjs/locale/zh-cn').then(() => {
      dayjs.locale('zh-cn');
    });
  } else {
    // 其他环境统一使用英文
    import('dayjs/locale/es-us').then(() => {
      dayjs.locale('es-us');
    });
  }
};

// 加载初始语言包
loadDayjsLang(i18n._.global.locale);

// 注册 i18n 勾子,每当切换语言之后,重新加载 dayjs 的语言包
i18n.hooks.afterSet.tapAsync(loadLang);

src/plugins/moduleA.ts

如果您的应用包含多个模块,它们有各自的本地化语言信息,您可以注册 i18n 的 beforeSet 钩子,将 messages 合并

import { merge } from 'lodash-es';

// 定义该 moduleA 的语言包加载方式
const loadModuleALang = async (langs: I18nLanguageType) => {
  if (langs === 'zh-CN') {
    import('./langs/zh-cn').then((res) => {
      return res.default;
    });
  } else {
    // 其他环境统一使用英文
    import('./langs/es-us').then((res) => {
      return res.default;
    });
  }
};

// 加载初始语言包
loadModuleALang(i18n._.global.locale).then((res) => {
  merge(i18n._.global.messages[i18n._.global.locale], res);
});

// 注册 i18n 勾子,每当切换语言之前,将会执行
i18n.hooks.beforeSet.tapAsync((langs: I18nLanguageType, locale) => {
  return loadModuleALang(langs).then((res) => {
    // 合并 message 对象
    return merge(locale, res);
  });
});

合并后,新的 i18n messages 对象结构为:

// i18n._.global.messages
{
  app: {
    sidebar: {
      shrink: '',
        unfold: ''
    },l
    settings: {
      title: ''
    }
  },
  moduleA: {
    title: '',
    message: ''  
  }
}

Vue3

src/main.ts

import { createApp } from 'vue';

import App from './App.vue';
import { i18n } from './i18n';

// 将 i18n._ 安装至 vue 实例中
const app = createApp(App).use(i18n._);

app.mount('#app');

src/App.vue

<template>
  <div class="p-20">
    <div class="flex items-center p-5 mb-6 border-4 border-indigo-600">
      <div>选择语言:</div>
      <select @change="onLanguageChange" v-model="language">
        <option v-for="item in languages" :value="item.value">{{item.text}}</option>
      </select>
    </div>
    <div class="flex items-center p-5 border-4 border-indigo-600">
      <p>app.name: {{ $t(i18nMessages.app.name) }}</p>
      <p>app.sidebar.shrink: {{ $t(i18nMessages.app.sidebar.shrink) }}</p>
    </div>
  </div>
</template>

<script lang="ts">
import { I18nLanguageType } from '@fatesigner/i18n';
import { defineComponent, ref } from 'vue';

import { i18n, i18nMessages } from './i18n';

export default defineComponent({
  setup(){
    // 当前选中的语言
    const language = ref<I18nLanguageType>(i18n._.global.locale);

    // 定义语言列表
    const languages = [
      {
        name: 'CN',
        value: 'zh-CN',
        text: '简体中文'
      },
      {
        name: 'US',
        value: 'en-US',
        text: 'English'
      }
    ];

    // 用户切换语言
    const onLanguageChange = () => {
      i18n.set(language);
    };

    return {
      i18nMessages,
      language,
      languages,
      onLanguageChange
    }
  }
});
</script>