Starling CLI是一个强大的跨语种国际化命令行工具,用于web、server项目,覆盖扫描、翻译、上传、替换、文案分析等操作,支持代码、注释国际化
js,jsx,ts,tsx,vue,go, python, css,less,scss, java kotlin,c/c++, object-c thrift文件的注释一键快速国际化;Mac: starling cli latest
Linux: starling cli latest
Windows: starling cli latest
根据环境下载对应版本,下载完成解压到指定目录,修改文件名为starling,当前目录下执行 staring [command]
建议创建(全局)符号链接为starling,如:Mac 使用 ln -s path/to/starling-cli /usr/local/bin/starling ( windows 需要配置对应环境变量,请自行配置)
使用 starling -V 命令,检验是否安装配置成功
// 初始化核心配置 见下面【配置介绍 - starling.config.js】 starling init // 初始化流水线 见下面【配置介绍 - starling.pipeline.js】 starling init --pipeline // 执行pipeline 命令,开启流水线,一键实现扫描-上传-翻译-替换 starling pipeline
初始化(starling init)
流水线 (starling pipeline)
使用前先阅读文档和项目readme,同时建议结合上面演示使用,包含react 和 vue, 其他项目类似可参考

注:
分步执行,starling scan、starling replace 可在离线环境下运行
starling scan => (starling upload + 确保翻译【用户处理】) => starling replace
需要在线环境下运行
starling pipeline(集合覆盖到整个项目中所有使用到的starling文案key的收集翻译替换)
starling.pipeline.js 默认配置将自动完成:starling scan => starling upload => 平台机翻 => starling replace 流程
starling.config.js
执行starling init 生成该配置文件,包含 strling cli 核心配置
module.exports = { // {zh} 收集入口 {en} Collection entrance entry: string | string[], // {zh} 剔除路径(glob) {en} Remove path (glob) exclude: [], // {zh} 环境设置 {en} Environment setting env: "prod", // {zh} 预览设置 {en} Preview settings preview: {}, // {zh} Starling项目 {en} Starling project starling: {}, // {zh} 文件加载器 {en} File loader loaders: [], // {zh} 生命周期pugin {en} life cycle plugin plugins: [], // {zh} 扩展命令 {en} Extended command };
用户网络环境是否可访问火山引擎API
{ networkMode: 'offline' | 'online', // offline:离线运行(支持的命令 scan、replace), online:在线运行, 默认值:online }
扫描的入口文件夹路径
{ entry: string | string[] // 扫描入口文件夹相对路径 }
globby扫描排除规则
{ exclude: string[] // globby排除规则 默认值[ "**/@(locale|build|log|output)/**" ] }
Starling cli运行环境,最终文案在平台发布环境
{ env: "prod" | "dev" // 环境 默认值: process.env.NODE_ENV === "production" ? "prod" : "dev" }
该配置项决定数据预览的模式,是否需要终端table展示,是否需要打开浏览器,要输出哪些格式的数据文件
{ preview?: { bar?: 'hidden', // 关闭扫描进度条 profile: boolean // 是否开启终端table报表,默认true browser: boolean // 是否自动打开浏览器,默认true output: { path: string // 扫描输出数据文件夹路径,默认 "./starling" type: Array<"json"|"xlsx"|"html">, // 扫描输出类型,默认值[ "json", "xlsx", "html"] } } }
该配置项表明和国际化翻译平台 关联的的相关数据配置
获取位置,浏览器访问平台对应项目/空间/任务
projectId项目ID,创建项目并进入项目页面后可在页面的URL中获取,例如/project_detail/1000,1000为项目IDnamespace空间ID,创建空间并进入空间页面后可在页面的URL中获取,例如/project_detail/1000/space/2000,2000为空间IDdemand任务ID,创建任务并进入任务页面后可在页面的URL中获取,例如/project_detail/1000/demand/3000,3000为任务IDaccessKey & secretKey:访问火山引擎API的密钥,必需
// {zh} Starling项目 {en} Starling project starling: { accessKey?: string, // 此处可选, 若该处未配置, 需要手动配置环境变量STARLING_ACCESSKEY secretKey?: string, // 此处可选, 若该处未配置, 需要手动配置环境变量STARLING_SECRETKEY projectId: number|string,// 项目ID, 建议使用 projectName?: string, // 项目名, 建议使用projectId namespace: string|number | Array<string|number>, // 空间名或者id demand?: string | number, // 任务名称或者id, 如果想上传到翻译任务ID 则需要设置 (且该翻译任务需要和上面的空间namespace文案同步) mode?: "normal"|"gray"|"test"|"offline", // 拉取文案的状态 normal: 线上环境 gray: 灰度环境 test: 测试环境 offline: 线下环境(需存在翻译) 默认值: normal locale?: string | Array<string>, // 项目中使用的starling语言 (如果不填,则会读取平台starling项目中使用的所有语种) download?: { path?: string, // 下载文案路径 可动态自定义 如: './diy/{namespace}/{lang}.json' 默认值: './locales' extnameType?: 'json' | 'xml' | 'strings', // 如配置动态diy路径 则自识别文件路径后缀 keysToDownload?: Array<string>, // 如:['key1','key2'], //支持 key 可选下载 fallbackLocales?: Array<string>, // 指定fallback的语种 noFallback?: boolean, // 指定是否开启fallback机制,如果为true,则不会有fallback,默认是false, }, upload?: { path?: string, // 指定上传文件路径 (支持xlsx & json) 默认值 "./starling/starling.xlsx" target?: boolean // 是否需要将目标翻译语言同步一起上传 } },
该配置项决定entry文件夹下各文件类型的加载方式,除内置loader之外,每一个外来的loader都必须要具备一个name&parser函数,且parser函数必须要返回指定数据格式的数据。
{ loaders: Array< // 使用内置loader { // 内置loader名称 starling-xxx-loader name: "starling-js-loader" |"starling-vue-loader"|"starling-css-loader"|"starling-go-loader"|"starling-py-loader"|"starling-default-loader ", test?: string // 覆盖内部的扫描glob规则 exclude?: string | string[] // 覆盖内部的排除glob规则 options: { rules: Array<RegExp|string>, /** 仓库中代码被认定已处理的函数正则列表 正则数组 默认为: /\s*(\w+\.)?\$?(t|i18n)\(.+\)\s*/i */ comment: boolean, // 是否开启注释扫描 interpolation?: { // i18n插值语法 prefix: string, // 默认值 "{" suffix: string , // 默认值"}" }, codeLocale?: { locale: string // 源代码语种 默认zh 非zh则会开启非中文文案扫描 loose: boolean | string[] // 宽松下的扫描类型 默认为false,开启后默认会提取[ "title", 'placeholder', 'description', 'message', 'okText', 'cancelText', 'label', 'prefix', 'suffix', ]类型key的value值 }, exactMatch:false // 是否对rules精确匹配,如果不设置,默认是false。默认会对rules里的正则前面加一个^,这样来避免误匹配。 } } // 接入外部用户开发loader { name: string, parser: (code: string, starling: object) => { codeList: Array<{ type: string // 提取文本类型 raw: string // 文案源内容 value: string // 文案内容 status: "handled" | "unhandled" // 文案状态 // 行列优先级较比开始字符位置高 column?: number // 文案起始列 line?: number // 文案起始行 (从1开始) start?: number // 文案起始字符位置 end?: number // 文案结束字符位置 }>, commentsList: Array<{ type: string // 提取文本类型 raw: string // 文案源内容 value: string // 文案内容 status: "handled" | "unhandled" // 文案状态 // 行列优先级较比开始字符位置高 column?: number // 文案起始列 line?: number // 文案起始行 (从1开始) start?: number // 文案起始字符位置 end?: number // 文案结束字符位置 }>, }, } > }
该配置项决定在整个处理文件数据流程中的相关副作用,提供...hooks,除内置plugin之外,每个外来的plugin都具备name&apply函数
{ plugins: Array< // 使用内置plugin { // 内置plugin starling-xxx-plugin (xxx 为hooks名称) name: "starling-key-generator-plugin" | "starling-code-generator-plugin"|"starling-after-replace-plugin"|"starling-emit-plugin", options: { // plugin 相关参数 } } | // 接入外部plugin { name: string, apply: (starling: object) => null // 参数均为Starling实例 } > }
starling.pipeline.js
执行starling init --pipline 生成该配置文件,用于执行 starling pipeline 命令,在setup -> scan -> repalce -> emit 各阶段插入插件,完成指定操作
type Plugin = { name: string // 插件名字 isRecord?: boolean // 是否listener监听 process: (starling: Starling) => { status: "success" | "error" | "doing" message?: string payload?: object } } | "starling-translate-plugin" | "starling-upload-plugin" | "starling-publish-plugin" // ...
{ context: { mode: "auto", // pipeling 运行模式, 目前仅支持 auto /** 插件参数配置 * key是插件名称 camelCase。 * starling-translate-uploaded-plugin -> translateUploaded * value是插件创建参数 */ [key of string]: object } // 监听插件运行,并自定义处理 listener: (pipeline: object , point: object) => void // 可插入生命周期列表 stage: { // 初始化节点 setup: Array<Plugin> // Plugin: 配置插件名 // 扫描节点 scan: { beforeScan: Array<Plugin> afterScan: Array<Plugin> } // 替换节点 replace: { beforeReplace: Array<Plugin> afterReplace: Array<Plugin> } // 输出节点 emit: Array<Plugin> } }
starling [options] <command>
| options | 介绍 |
|---|---|
| -c,--configPath | 指定starling.config.js配置文件读取路径 |
| -V, --version | 获取当前版本信息 |
| -h, --help | 获取帮助信息 |
starling 子命令 -h| 分类 | command | 简介 |
|---|---|---|
核心命令 | init | 按照提示初始化配置文件starling.config.js |
scan | 扫描文件中的中文文案,以及已经国际化的文案(代码&注释) | |
| replace | 将scan的结果数据按照类型规则,替换为符合要求的国际化语言 | |
| pipeline | 流水线化功能点(初始化=>扫描=>上传=>翻译=>替换...) | |
| clean | 清空扫描输出文件 | |
基础命令 | download | 下载指定环境下的文案数据 |
| upload | 上传文案数据到Starling平台 |
该命令用于在当前目录下自动生成 starling.config.js、starling.pipeline.js 配置文件
starling init [options] Usage: starling init [--force|-f|--yes|-y|--type|-t] Initialize configuration file· Options: -f, --force Forced overlay creation -y, --yes Quickly create configuration -t, --type [type] Select project type --pipeline Initialize pipeline configuration file
| options | 介绍 | 备注 |
|---|---|---|
| -f,--force | 覆盖安装 | |
| -t,--type | 自动生成 type 类型的配置文件,type 可选值为 react/vue/go/py | 默认值 default |
| -y, --yes | 跳过其他选项,直接创建配置文件 | |
| --pipeline | 自动生成pipeline配置文件 |
options默认会合并starling.config.js中starling的配置内容
Usage: starling pipeline [options] Core process series Options: --only-scan Only run setup, scan cycles 但仍然会运行扫描与上传!! -x, --context [contexts...] Incoming pipeline plugin dynamic parameters, such as fileDiff.diffBranch=master
| options | 介绍 | 备注 |
|---|---|---|
| --only-scan | 只运行steup、scan生命周期,跳过replace和emit | |
-x --context [contexts...] | 可以动态化注入插件参数,格式: pluginName.optionsKey=value |
options默认会合并starling.config.js中starling的配置内容
该命令用于扫描当前项目下所有的中文文案,并生成扫描报告。
当前版本,扫描文案数具有限制,超过后将不再扫描,可重复执行命令;执行 scan、replace、pipline 命令将会提示具体限制数量
starling scan [options] Usage: starling scan [options] Scan matched result data Options: -e, --entryPath [entryPath] Collection file path -o, --outputPath [outputPath] Data output path --fallback Download the key value used under the project -m --mode [mode] Select the replacement code or comment (default: "all")
执行完成后,会通过浏览器打开页面展示已经处理和未处理的文案信息。同时会在starling.config.js中preview.ouput.path位置生成扫描报告,包含 handled.json, unhandled.json, handled.xlsx, unhandled.xlsx,starling.xlsx 文件;
| options | 介绍 | 备注 |
|---|---|---|
| -e, --entryPath [entryPath] | 扫描入口文件夹路径 | |
| -o, --outputPath [outputPath] | 扫描数据输出文件夹路径 | |
| -m --mode [mode] | 扫描模式 all: 注释 + 代码 comment: 注释 code: 代码 | 模式前提是starling.config.js都开启的,默认: all |
--fallback | 下载项目下使用的key值翻译文案 | 下载语种starling.locale (也可以是starling.locales,优先级比前者低。这种写法是历史包袱,不推荐) |
options默认会合并starling.config.js中starling的配置内容
在线模式(networkMode: online)下,使用该命令,需要先上传文案,使用starling upload 或手动上传平台;
离线模式(networkMode: offline)下,不验证平台是否存在key、文案,直接替换,由用户自己check,效果等同于在线模式下使用-f选项;
Usage: starling replace [options] Replace matched result data Options: -e, --entryPath [entryPath] Collection file path -o, --outputPath [outputPath] Data output path -m --mode [mode] Select the replacement code or comment (default: "all") -f --force Write directly after forced replacement --disable-browser Disable automatic browser opening
该命令会从 Starling 平台拉取文案,并根据文案匹配项目中的所有中文文案,替换为国际化语句。比如将 '我是一个段落' 替换为 I18n.t('paragraph', {}, '我是一个段落')。同时在替换前和替换后都会执行一次 scan 命令,用于查看替换前后的变化。
执行该命令后,项目中的中文文案,如果与 Starling 平台上的文案能匹配上,都会被替换为国际化语句,比如I18n.t('paragraph', {}, '我是一个段落'),其中 'paragraph' 是存储在 Starling 平台上的 key,它对应了文案 '我是一个段落'。同时还会生成一份扫描报告,可以查看哪些文案被成功替换了,哪些没有。
| options | 介绍 | 备注 |
|---|---|---|
| -e, --entryPath [entryPath] | 扫描入口文件夹路径 | |
| -o, --outputPath [outputPath] | 扫描数据输出文件夹路径 | |
| -m --mode [mode] | 扫描模式 all: 注释 + 代码 comment: 注释 code: 代码 | 默认: all |
| --update | Starling项目需要迁移的时候,更新已使用的key值 | 旧项目配置starling.updateFrom |
| -f --force | 不经过数据检查,强制写入文件 | |
| --disable-browser | 禁止打开浏览器 |
Usage: starling clean [options] Clear output data Options: -o, --outputPath [outputPath] Data output path
| options | 介绍 | 备注 |
|---|---|---|
| -o, --outputPath [outputPath] | 文件数据输出路径 | 只会选择性的删除starling.config.js中output.type中的类型文件,并不会误删不相关的文件 |
下载指定项目、空间中文案,可以通过mode参数指定发布的环境。
options默认会合并starling.config.js中starling的配置内容,所以更推荐配置在starling.config.js中的starling.download对象中。
starling.download对象还支持文件格式、fallbackLocales等配置。
Usage: starling download [options] Download the copy in the Starling project Options: -d --distPath [distPath] download file -l --locale [locale] select download language -m --mode [mode] download mode: normal gray test offline
| options | 介绍 | 备注 |
|---|---|---|
| -d --distPath [distPath] | 数据下载的文件夹路径 | 默认:执行命令当前目录下的locale文件夹中 |
| -l --locale [locale] | 需要下载的目标语种 | 多个语言,请用,隔开 |
-m --mode [mode] | 指定Starling文案状态下载 normal 、gray 、test 、offline | normal: 线上环境 |
该命令用于上传 starling.xlsx 文件到平台,用于同步文案。
options默认会合并starling.config.js中starling的配置内容
Usage: starling upload [options] Upload copy to Starling platform Options: -u --uploadPath [uploadPath] upload file -t --target carry target texts when upload
| options | 介绍 | 备注 |
|---|---|---|
| -u --uploadPath [uploadPath] | 上传文件路径 | 当前支持xlsx、 json文件 |
-t --target | 将目标翻译语言也上传。注意:使用此项时,上传的文件格式只能是excel,不支持json上传翻译文案(没有目标语言的概念) | 默认值:true。 |
本节列举的插件是在starling.config.js中配置的plugins
starling-key-generator-plugin
{ name: 'starling-key-generator-plugin', // plugin name // plugin配置项 options: { // remote的配置含义:是否优先用平台已有【相同文案】的key,如果不期望复用已有相同文案的key,则需要去掉该项配置或设置isSkip:true; 仅支持在线模式(networkMode: online) remote?: { source: boolean, // 根据源文案匹配key, 默认值: true locale?: string, // 根据目标翻译语言来匹配, 如果source: false 则需要指定目标语种,默认值: "en" isSkip?: boolean // 是否跳过此选项, 默认值: false } // local的配置含义:是否优先用本地已有【相同文案】的key,如果不期望复用已有相同文案的key,则需要去掉该项配置或设置isSkip:true local?: { path: string, // 自定义json(key: value)文件路径 isSkip?: boolean // 是否跳过此选项, 默认值: false }, // 自定义key生成规则 diy?: { diy: (i18nData: object, filePath: string) => string, // diy 函数,参数i18nData暴露出starling相关信息,参数filePath 文案所在文件路径,具体可打印 isSkip?: boolean // 是否跳过此选项, 默认值: false }, // 自动生成key, 如机翻、hash算法 auto: { // machineTranslate: 仅支持在线模式(networkMode: online) type: 'machineTranslate' | 'crcHash' | 'stringHash' | 'source' | 'nanoid', prefix?: string // 自定义key前缀 suffix?: string // 自定义key后缀 isSkip?: boolean // 是否跳过此选项 默认值: false // 当type为machineTranslate,以下配置项可选 maxLength: number // 默认值 80 机翻后 key 最长字符长度 locale?: string // key语种 默认值 "en" }, } }
starling-code-generator-plugin
{ name: 'starling-code-generator-plugin' options: { // 各类语法规范 statement: string // 占位符 $key、$variable、$defaultMessage 默认值 I18n.t("$key", $variable, "$defaultMessage") 注意,这里这三个占位符必须是参数,而不能是函数名。注意这里必须是一个函数调用表达式 comment?: { bilingual?: boolean, // 是否是需要双语保留 默认值false。注意,如果设置该值为true,那么替换注释时,待替换的注释中如果包含{en}或者{zh}会被认为已被替换从而没有任何变化。 } } }
starling-after-replace-plugin
{ name: 'starling-after-replace-plugin', options: { autoImport: string // 替换后自动导入语句 如前端侧: "import { I18n } from 'i18next';" } }
starling-emit-plugin
{ name: 'starling-emit-plugin', options: { autoTrans: { targetLocale?: Array<string> // 翻译的目标语种 } }, }
- 当使用pipeline模式下,starling-emit-plugin会失效,starling.config.js中preview配置也会失效
- 如果不在pipeline.context传入相对应配置、则会去starling.config.js读取相对应配置
插件名: starling-upload-plugin
插件描述:
自动将key未上传到starling平台的的源文案上传至指定starling空间或者任务,如前面有遗漏翻译文案数据,也会同步上传。
备注:
作用周期: afterScan、beforeReplace
配置参数:
context: { upload?: { // 空间文案路径绑定 namespacePathMap?: { [key: string]: array<string> | string // key为空间名,value为对应子路径 }, }, }
插件名: starling-translate-uploaded-plugin
插件描述:
自动将key未上传到starling平台的的源文案走配置目标语种机器翻译
备注:
starling-translate-uploaded-plugin必须在starling-upload-plugin后面;作用周期: afterScan
配置参数:
context: { translateUploaded?: { useTM:true // 是否启用记忆库翻译,默认为false。注意,记忆库的源语种必须与项目的源语种一致。 targetLocale?: array<string> // 指定翻译语言码,如未填写回退值starling.config.js下starling.locale, 最后以线上项目配置语种作为兜底值。 } }
// starling-disable-file 文件内容 <!-- starling-disable-file --> 文件内容
// starling-disable-block-start 内容块 //starling-disable-block-end <!-- starling-disable-block-start --> 内容块 <!-- starling-disable-block-end -->
// starling-disable-next-line 内容行 <!-- starling-disable-next-line --> 内容行
// starling-disable-line 内容行 <!-- starling-disable-line --> 内容行
默认上线分支、代码路径、排除路径这三个配置决定从仓库的扫描分支进行代码路径下的 Glob 扫描(应用 loader 对应的 test 规则)。 对提取的代码文件进行相应的 loader 的 AST 分析。
利用函数扫描规则,对代码下函数行的形式的内容进行正则匹配,进而通过所配置的 statement 目标语句下的 参数位置,进行国际化数据的提取。
CLI 未直接开放组件式的配置入口,但是内置了常见的国际化框架的组件式写法提取
//vue 组件式(vue loader) <* v-t= key ...> <i18n path= key ...> <i18n path= {path:key} ...> <i18n-t keypath= key > <Translate path= key > //js ts jsx tsx(js loder) 组件式 <FormattedMessage id= key defaultMessage= defaultMessage .../> //js ts jsx tsx(js loder) 函数式 如果 参数 是以对象形式进行包裹的 intl.formattedMessage({id: key ,defaultMessage: defaultMessage }) intl.formatMessage({id: key ,defaultMessage: defaultMessage }) intl.formatHTMLMessage({id: key ,defaultMessage: defaultMessage }) defineMessage({id: key ,defaultMessage: defaultMessage })
8:Q:只想拉取项目中存在key的对应翻译文案,如何处理?
A:推荐使用 starling scan --fallback,具体参考【命令详解-核心命令-scan】