SDK和Nest语言国际化

408 阅读4分钟

前言

之前在做编辑器Paas平台时收到一个上级的需求。为了支持业务团队能够自定义一些文案因此sdk需要提供接口来更改SDK的一些文案,以及支持海外用户使用因此NestJs中间层服务返回的一些系统信息也需要国际化。 接下来就来讲解一下NestJS如何国际化以及SDK如何让业务团队自定义一些文案

NestJs语言国际化

针对NestJs语言国际化需要使用的是nestjs-i18n来进行实现。

  • 安装
pnpm add nestjs-i18n
  • 设置翻译文件
    一般在将文件src -> i18n -> ZH/EN.../目录下 640.png 需要注意如下两点:
  1. 目前不支持ts\js文件,只支持json\yaml..
  2. 目前文件必须有EN\ZH目录(文件名自定义)不能直接i18n/ZH.json没有中间那一层目录,这里的ZH/EN文件名language为域,该域名会在后续调用使用到
  • 配置module层 只需要根module中注册它即可,因为I18nModule是一个全局的module只需注册一次,其就可以在全局使用了 640.png

  • 在service/controller层使用 只需要通过构建器或者@Inject装饰器I18nService注入进去即可调用translate的方法 640.png

function helloWork(@Body() options: Ioptions){
    this.i18n.translate( 
        'language.app_switch_language_successfully',
        { lang: options.i18nLanguage }
    )
}

client端携带options.i18nLanguage参数用于表示当前client端所处的语言环境。其实也很好理解一个中层服务同时服务于很多客户端的,因此接口返回的语言是有客户端语言环境决定的 image.png

  1. 在后端是没有统一设置language语言的,不像前端可以统一设置I18N.changeLanguage('EN')这种。因为服务器是针对多个用户的

640.png

  1. 一般都是通过http请求参数来进行语言的设置
  2. throwlogger不需要国际化,只有面向用户的文本才需要
  • 配置nest-cli设置 在NestJs在编译时不会自动将静态文件打包进去,因此我们需要配置compilerOptions
    这里需要注意 在NestJs中配置assets包含的静态目录只对src下的目录生效,如果你的静态目录不在src目录下那么只能手动copy或者写个shell脚本复制到dist目录
{  
...
"compilerOptions": {  
    "assets": [  
        { "include": "..、i18n/**/*", "watchAssets": true }  
    ]  
  }  
}

因为我的仓库类型是多包(monorepo)的类型,因为我这边还需要多设置一个outDir属性

{  
...
"compilerOptions": {  
    "assets": [  
        { 
            "include": "..、i18n/**/*",
            "watchAssets": true,
            "outDir":'./dist/apps/i18n'  -> 打包之后输出的文件目录
        }  
    ]  
  }  
}

至此我们就完成了NestJS的国际化功能

sdk自定义文案

接下来实现给业务团队自定义sdk内部文案,因为sdk内部组件已经使用了i18n来进行文案国际化,因此这里依旧借助i18naddResources能力来更新SDK内部组件文案

  • 初始化
    首先在初始化SDK时定义当前语言(language)需要更替的文案资源(languageResource)。当然languageResource的数据里key必须跟sdk内部定义的language.jsonkey保持一致(如果你有更好的方案或者能够忽略这层映射关系可以留言哦~)
new AKclown({
    language:'ZH',
    languageResource:[
        { lang:'ZH', resource: { key: 'value' } 或者json数据都行 },
        { lang:'EN', resource: { key: 'value' } 或者json数据都行 }
    ]
})
  • SDK内部实现
    除了在初始化sdk时调用initI18进行初始化,还需要给提供updateLanguageResource方法允许业务团队中途变更文案,使其更加灵活
class AKclown{
    constructor(params:Iparams){
       initI18(params)
    }
    
    // 初始化文案资源
    initI18(params:Iparams){
        for(let item of params.languageResource){
            i18next.addResources( item.lang, 'translation', item.resources )
        }
        i18next.changeLanguage(params.language)
    }
    
    // 中途更新文案资源
    updateLanguageResource(payload){
        for(let item of payload){
            i18next.addResources( item.lang, 'translation', item.resources )
        }
    }
}

经过如上两步骤我们就实现了SDK自定义文案了,是不是so easy

总结

通过如上步骤我们学会了如何做NestJS语言国际化需求以及SDK中提供业务方自定义文案能力
在这里感谢My Boss让我学到了,哈哈哈

其他

react项目中需要使用useTralatewith...才会自动更新,如果直接使用i18n.t()..需要手动刷新才生效