chrome浏览器扩展国际化那些事

2021-09-15 | 2,681浏览 | 0评论 | 标签:chrome插件 chrome扩展国际化

背景

最近在为浏览器插件《油管评论翻译机》迭代,涉及到国际化(切换国家语种),记录一下。

技术选型:vue+element-ui+chrome扩展+i18n+Express

实现过程

本扩展涉及到国际化的地方有:弹窗页(page_action:default_popup)、选项页(options_page或options_ui:page)、注入页(content_scripts)、chrome扩展管理页、后端接口。

如果项目中没有手动切换语种的要求,那直接使用chrome扩展的chrome.i18n.getMessage('name')轻松实现国际化。反之,就需要多想点办法了。我总结为以下三种方式。

一、使用vue+element-ui+vue-i18n实现国际化

切换语言

这和chrome扩展没依赖关系,是element-ui官方推荐的国际化方案。具体实现参考官方文档(element-ui国际化文档),如果不是很清楚,推荐看这两篇文章: 《vue+elementUI+vue-i18n 实现国际化》、 《vue实现多语言国际化(vue-i18n),结合element ui、vue-router、echarts以及joint等》。

其中有几点值得提一下:

1. 数据结构不同

element-ui定义的数据结构和chrome扩展的不同。

以下是element-ui的locale文件,取自element-ui/lib/locale/lang/zh-CN.js

exports.default = {
  el: {
    colorpicker: {
      confirm: '确定',
      clear: '清空'
    },
    datepicker: {
      now: '此刻',
      today: '今天',
    }
    ...
  }

以下是chrome扩展要求的结构,取自_locales/zh_CN/messages.json (该文件需自建,后面细说)

{
  "name": {
    "message": "油管评论翻译机",
    "description":""
  },
  "desc": {
    "message": "一款轻松翻译YouTube评论的浏览器扩展,支持多国语言、双语对照、评论导出、样式修改等。",
    "description":""
  }
}

看出区别了吗? chrome扩展有固定的格式,不一致会导致获取失败,所以需要按chrome的格式来写,再转化结构来供element-ui使用,当然你也可以分开做两份。

2.定义默认语言

element-ui定义默认语言可通过上面提到的vue-i18n来实现,即:


const i18n = new VueI18n({
    locale: 'zh_CN', //默认中文(简)
    ...
})

3.切换语言

在vue下拉菜单中切换,直接更改this.$i18n.locale的值即可。


changeLanguage(lang) {
   this.$i18n.locale = lang
}

4.渲染

在vue模板中,直接使用$t调用:

<span>{{$t('name')}}</span>

同理,在vue js中使用:

const name = this.$t('name')

二、chrome扩展自身国际化

上文介绍的都是vue能控制的范围,但像下面这种,以及在注入页(content_scripts), 后台运行页(background)等,就需要chrome扩展自带的国际化方法来实现。

chrome扩展自身国际化.jpg

具体实现方式参考360翻译的官方文档《chrome扩展国际化》,以及民间文章《Chrome插件i18n多语言实现》,讲得非常详细。

总结起来就是:

1. 定义语种

如果manifest.json里配置了default_locale属性,chrome就会去根目录寻找_locale下对应的语种,比如中文简体为:_locale/zh_CN/messages.json,具体格式上面有简单提到。

chrome扩展支持的所有语种:am ar bg bn ca cs da de el en en_GB en_US es es_419 et fi fil fr gu he hi hr hu id it ja kn ko ltlv ml mr nl or pl pt pt_BR pt_PT ro ru sk sl sr sv sw ta te th tr uk vi zh zh_CN zh_TW。

2. 调用

① 在js中调用

chrome.i18n.getMessage('name')

这里的getMessage还支持第2个参数,用于占位,可带入变量。用法如下:


//messages.json定义
{
  "hello": {
    "message": "你好, $USER$",
    "placeholders": {
      "user": {
        "content": "$1",
        "example": "李四"
      }
    }
  }
}


//js调用
const msg = chrome.i18n.getMessage('hello','张三')

② 在manifest.json或css中调用

使用字符变量__MSG_xxxx__,或调用方法getMessage("_xxxx_")


//manifest.json:
{
   "name": "__MSG_name__",
   "description": "__MSG_desc__",
   "default_locale" : "zh_CN",
   "manifest_version": 2,
   ...
}


// css:
#app{
  width: __MSG_width__;
}

写到这里出现一个问题,如果你使用chrome.i18n.getMessage,用户想切换语言,除了在浏览器设置语种后重启,暂时还没发现热切换的方法。我的做法是除非必要,尽量避免使用chrome.i18n.getMessage,通过vue+element-ui那套方式来实现,并把选中的语种保存在缓存中,还可供后端接口调用,这就引出了下面这种场景。

三、后端接口国际化

前端可把语种封装到headers统一传给后端,就像这样:

// 前端 axios

const locale = 'zh_CN';

axios.interceptors.request.use(
    config => {
      config.headers.locale = locale;  //和后端约定一个属性
      return config
    }
    ...
  )


//后端 Express 

const getInfo = async (req, res, next) => {
  let { locale } = req.headers;
  ...
}

后端已拿到语种,国际化就好办了,已超出前端范畴,略。

总结

浏览器扩展是个好东西,能大大提高生产力。目前我也只写过两个扩展,一个是《油管评论翻译机》,另一个是几年前写的《基金助手》,每次写都能发现新大陆,建议大家亲手试试。

(本篇完。有疑问欢迎留言探讨)

留言:

*

* (方便回复通知)

打赏
编辑代码 运行结果
退出