Skip to content

Commit

Permalink
fix(lowcode-i18n-extract): fix RegExp test and function i18n var inje…
Browse files Browse the repository at this point in the history
…ct issues
  • Loading branch information
Carrotzpc committed Mar 19, 2024
1 parent 8b76a21 commit 7c9e8e7
Show file tree
Hide file tree
Showing 7 changed files with 264 additions and 161 deletions.
1 change: 1 addition & 0 deletions .github/workflows/release.yml
Original file line number Diff line number Diff line change
Expand Up @@ -49,6 +49,7 @@ jobs:
GITHUB_TOKEN: ${{ secrets.GH_TOKEN }}
NPM_TOKEN: ${{ secrets.NPM_TOKEN }}

# @Todo: should check if relase successfully
- name: Sync to cnpm
run: |
npm install -g cnpm
Expand Down
19 changes: 12 additions & 7 deletions packages/lowcode-i18n-extract/src/extract.ts
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
/* eslint-disable unicorn/prefer-regexp-test */
import { IPublicTypePageSchema, IPublicTypeProjectSchema } from '@alilc/lowcode-types';
import * as babelParser from '@babel/parser';
import * as babelTraverse from '@babel/traverse';
Expand Down Expand Up @@ -35,7 +36,11 @@ function findTextInJs(code: string, type: string, path: string[]) {
babelTraverse.default(ast, {
StringLiteral({ node }) {
const { start, end, value } = node as babelTypes.StringLiteral;
if (value && DOUBLE_BYTE_REGEX.test(value)) {
// 注意这里不能是用 `DOUBLE_BYTE_REGEX.test()`,如果正则表达式设置了全局标志 `g`,
// `test()` 的执行会改变正则表达式 `lastIndex` 属性。连续的执行 `test` 方法,
// 后续的执行将会从 `lastIndex` 处开始匹配字符串,(`exec()` 同样改变正则本身的 `lastIndex` 属性值)
// 详见 https://yi-love.github.io/articles/regexp-test
if (value && value.match(DOUBLE_BYTE_REGEX)) {
const range = { start: start - offset, end: end - offset };
jsMatches.matches.push({
range,
Expand All @@ -47,7 +52,7 @@ function findTextInJs(code: string, type: string, path: string[]) {
TemplateLiteral({ node }) {
const { start, end } = node as babelTypes.TemplateLiteral;
const templateContent = fixedCode.slice(start, end);
if (DOUBLE_BYTE_REGEX.test(templateContent)) {
if (templateContent.match(DOUBLE_BYTE_REGEX)) {
const range = { start: start - offset, end: end - offset };
jsMatches.matches.push({
range,
Expand All @@ -62,7 +67,7 @@ function findTextInJs(code: string, type: string, path: string[]) {
if (babelTypes.isJSXText(child)) {
const { value, start, end } = child;
const range = { start: start - offset, end: end - offset };
if (DOUBLE_BYTE_REGEX.test(value)) {
if (value.match(DOUBLE_BYTE_REGEX)) {
jsMatches.matches.push({
range,
text: value.trim(),
Expand Down Expand Up @@ -96,6 +101,9 @@ const findI18n = (obj: Record<string, any>, path: string[] = [], matches: I18nMa
if (jsMatches.matches.length === 0) {
continue;
}
// 调整文案顺序,保证从后面的文案往前替换,避免位置更新导致替换出错
jsMatches.matches = sortBy(jsMatches.matches, match => -match.range.start);
matches.push(jsMatches);
// 需要对 methods 中的 source 进行特殊处理
if (value.source) {
const sourceJsMatches = findTextInJs(value.source, value.type, [
Expand All @@ -108,9 +116,6 @@ const findI18n = (obj: Record<string, any>, path: string[] = [], matches: I18nMa
);
matches.push(sourceJsMatches);
}
// 调整文案顺序,保证从后面的文案往前替换,避免位置更新导致替换出错
jsMatches.matches = sortBy(jsMatches.matches, match => -match.range.start);
matches.push(jsMatches);
} catch (error) {
console.warn(`parse '${newPath.join(' > ')}' failed, code is: ${value.value}`, error);
}
Expand All @@ -133,7 +138,7 @@ const findI18n = (obj: Record<string, any>, path: string[] = [], matches: I18nMa
findI18n(value, newPath, matches);
continue;
}
if (valueType === 'string' && DOUBLE_BYTE_REGEX.test(value)) {
if (valueType === 'string' && value.match(DOUBLE_BYTE_REGEX)) {
matches.push({
path: newPath,
text: value,
Expand Down
8 changes: 5 additions & 3 deletions packages/lowcode-i18n-extract/src/replace.ts
Original file line number Diff line number Diff line change
Expand Up @@ -105,9 +105,11 @@ export const replaceAndUpdateJsCode = (matches: I18nMatch[], jsCode: string, typ
newCode = code;
i18nRecords[match.key] = text;
}
// 函数类型的 code 在函数体首行增加 i18n 函数变量声明,可以避免一些 this 指向引起的 i18n 无法获取的问题
if (IS_ADD_I18N_VAR) {
newCode = newCode.replace(JS_FUNCTION_PREFIX_REG, `$1\n const __I18N = this.i18n;\n`);
const I18N_VAR_EXPRESSION = 'const __I18N = this.i18n;';
// 函数类型的 code 在函数体首行增加 __I18N 函数变量声明,可以避免一些 this 指向引起的 i18n 无法获取的问题
// 需要判断函数体内部是否已经添加过 __I18N 变量,避免重复添加
if (IS_ADD_I18N_VAR && !newCode.includes(I18N_VAR_EXPRESSION)) {
newCode = newCode.replace(JS_FUNCTION_PREFIX_REG, `$1\n ${I18N_VAR_EXPRESSION}\n`);
}
return {
code: newCode,
Expand Down
101 changes: 73 additions & 28 deletions packages/lowcode-i18n-extract/tests/data/results/matches.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
[
{
"path": ["componentsTree", "0", "methods", "paginationShowTotal", "source"],
"path": ["componentsTree", "0", "methods", "paginationShowTotal", "value"],
"matches": [
{
"range": {
Expand All @@ -14,7 +14,7 @@
]
},
{
"path": ["componentsTree", "0", "methods", "paginationShowTotal", "value"],
"path": ["componentsTree", "0", "methods", "paginationShowTotal", "source"],
"matches": [
{
"range": {
Expand All @@ -28,33 +28,61 @@
]
},
{
"path": ["componentsTree", "0", "methods", "getStatusText", "source"],
"path": ["componentsTree", "0", "methods", "getHelloWorldText", "value"],
"matches": [
{
"range": {
"start": 465,
"end": 518
"start": 92,
"end": 96
},
"text": "絮黎",
"isString": true,
"key": "i18n-xu-li"
}
]
},
{
"path": ["componentsTree", "0", "methods", "getHelloWorldText", "source"],
"matches": [
{
"range": {
"start": 92,
"end": 96
},
"text": "絮黎",
"isString": true,
"key": "i18n-xu-li"
}
]
},
{
"path": ["componentsTree", "0", "methods", "getStatusText", "value"],
"matches": [
{
"range": {
"start": 570,
"end": 623
},
"text": "审核未通过:${this.state.value === 1 ? '姓名未通过' : '地址未通过'}",
"isString": true,
"key": "i18n-shen-he-wei-tong-guo"
},
{
"range": {
"start": 325,
"end": 329
"start": 423,
"end": 437
},
"text": "进度",
"isString": true,
"key": "i18n-jin-du"
},
{
"range": {
"start": 301,
"end": 316
"start": 342,
"end": 368
},
"text": "审核中(",
"isString": false,
"isString": true,
"key": "i18n-shen-he-zhong"
},
{
Expand All @@ -78,33 +106,33 @@
]
},
{
"path": ["componentsTree", "0", "methods", "getStatusText", "value"],
"path": ["componentsTree", "0", "methods", "getStatusText", "source"],
"matches": [
{
"range": {
"start": 570,
"end": 623
"start": 465,
"end": 518
},
"text": "审核未通过:${this.state.value === 1 ? '姓名未通过' : '地址未通过'}",
"isString": true,
"key": "i18n-shen-he-wei-tong-guo"
},
{
"range": {
"start": 423,
"end": 437
"start": 325,
"end": 329
},
"text": "进度",
"isString": true,
"key": "i18n-jin-du"
},
{
"range": {
"start": 342,
"end": 368
"start": 301,
"end": 316
},
"text": "审核中(",
"isString": true,
"isString": false,
"key": "i18n-shen-he-zhong"
},
{
Expand All @@ -127,6 +155,23 @@
}
]
},
{
"path": [
"componentsTree",
"0",
"children",
"0",
"children",
"0",
"children",
"0",
"props",
"children"
],
"text": "国际化文案提取测试",
"isString": true,
"key": "i18n-guo-ji-hua-wen-an"
},
{
"path": [
"componentsTree",
Expand Down Expand Up @@ -176,7 +221,7 @@
"children",
"0",
"children",
"2",
"3",
"children",
"0",
"children",
Expand Down Expand Up @@ -205,7 +250,7 @@
"children",
"0",
"children",
"2",
"3",
"children",
"0",
"children",
Expand Down Expand Up @@ -234,7 +279,7 @@
"children",
"0",
"children",
"2",
"3",
"children",
"0",
"children",
Expand Down Expand Up @@ -263,7 +308,7 @@
"children",
"0",
"children",
"2",
"3",
"children",
"1",
"children",
Expand All @@ -288,7 +333,7 @@
"children",
"0",
"children",
"2",
"3",
"children",
"1",
"children",
Expand All @@ -313,7 +358,7 @@
"children",
"0",
"children",
"2",
"3",
"children",
"1",
"children",
Expand All @@ -338,7 +383,7 @@
"children",
"0",
"children",
"2",
"3",
"children",
"1",
"children",
Expand All @@ -363,7 +408,7 @@
"children",
"0",
"children",
"2",
"3",
"children",
"1",
"children",
Expand All @@ -388,7 +433,7 @@
"children",
"0",
"children",
"2",
"3",
"children",
"1",
"children",
Expand Down Expand Up @@ -419,7 +464,7 @@
"children",
"0",
"children",
"2",
"3",
"children",
"1",
"children",
Expand Down
Loading

0 comments on commit 7c9e8e7

Please sign in to comment.