通過腳本自動檢查項目中全局的中文

現在越來越多的公司在做出海項目,出海項目首先要解決的就是語言國際化的問題,有很多如l18n、l10n的工具可以用,這些工具可以提供解決方案,但是不能約束開發者的開發行為。開發者仍然可能在代碼中存留沒有做過國際化處理的部分,假設后續 MR 的Code Review也沒有查出來,這就是很大的隱患了,甚至會有監管風險,因為很多項目不想讓別人知道是中國團隊做的,所以要嚴格禁止控制臺輸出中文日志。

我最近也是接到一個這樣的需求,本來需求是讓我人肉檢查一下項目中有沒有輸出中文日志的情況。人肉是不可能人肉的,我覺得這個可以通過寫腳本來實現檢查,因為核心要素其實就兩個點:

  1. 需要檢查中文
  2. 需要全局檢查所有文件

這些要素都可以通過 Node.js 腳本來實現。

公眾號:Code程序人生,個人網站:https://creatorblog.cn

這個腳本會實現以下能力:

  1. 讀取當前項目下所有目錄、所有文件
  2. 能有效檢查文件中是否包含中文字符
  3. 可以提前聲明要忽略的文件夾/文件
  4. 主動忽略所有注釋,包含///* ... */{/* ... */}
  5. 輸出詳細的檢查結果日志,包含 文件路徑、文件行數、相關代碼,并且高亮檢查出來的中文的部分

image.png

在項目根目錄新建一個文件,如check-chinese.js。寫入以下內容:

const fs = require('fs');
const path = require('path');// 中文字符的正則表達式
const chineseRegex = /[\u4e00-\u9fa5]/;// 要忽略的文件或目錄
const ignorePatterns = ['node_modules','.git','.next','public','locales','dist','build','check-chinese'
];// 要檢查的文件擴展名
const extensions = ['.ts', '.tsx', '.js', '.jsx'];// 控制臺顏色
const colors = {reset: '\x1b[0m',bright: '\x1b[1m',dim: '\x1b[2m',underscore: '\x1b[4m',blink: '\x1b[5m',reverse: '\x1b[7m',hidden: '\x1b[8m',black: '\x1b[30m',red: '\x1b[31m',green: '\x1b[32m',yellow: '\x1b[33m',blue: '\x1b[34m',magenta: '\x1b[35m',cyan: '\x1b[36m',white: '\x1b[37m',bgBlack: '\x1b[40m',bgRed: '\x1b[41m',bgGreen: '\x1b[42m',bgYellow: '\x1b[43m',bgBlue: '\x1b[44m',bgMagenta: '\x1b[45m',bgCyan: '\x1b[46m',bgWhite: '\x1b[47m'
};// 使用第三方庫來解析代碼和注釋
function parseFileContent(content, filePath) {// 首先通過簡單的方式移除所有注釋let processedContent = content;// 1. 移除多行注釋 /* ... */processedContent = processedContent.replace(/\/\*[\s\S]*?\*\//g, match => {// 保留換行符以保持行號return match.replace(/[^\n\r]/g, ' ');});// 2. 移除單行注釋 // ...processedContent = processedContent.replace(/\/\/.*$/gm, match => {// 保留相同長度的空格return ' '.repeat(match.length);});// 3. 移除JSX注釋 {/* ... */}processedContent = processedContent.replace(/\{\/\*[\s\S]*?\*\/\}/g, match => {// 保留換行符以保持行號return match.replace(/[^\n\r]/g, ' ');});return processedContent;
}// 檢查文件中的中文字符
function checkFileForChinese(filePath) {try {const content = fs.readFileSync(filePath, 'utf8');// 處理文件內容,移除注釋const processedContent = parseFileContent(content, filePath);// 按行檢查處理后的內容const lines = processedContent.split('\n');const originalLines = content.split('\n');const results = [];lines.forEach((line, index) => {// 檢查行中是否包含中文字符if (chineseRegex.test(line)) {results.push({file: filePath,line: index + 1,content: originalLines[index].trim()});}});return results;} catch (error) {console.error(`${colors.red}無法讀取文件 ${filePath}: ${error.message}${colors.reset}`);return [];}
}// 遞歸遍歷目錄
function traverseDirectory(dir) {const results = [];try {const files = fs.readdirSync(dir, { withFileTypes: true });for (const file of files) {const fullPath = path.join(dir, file.name);// 檢查是否應該忽略此路徑if (ignorePatterns.some(pattern => fullPath.includes(pattern))) {continue;}if (file.isDirectory()) {results.push(...traverseDirectory(fullPath));} else if (file.isFile() && extensions.includes(path.extname(file.name))) {results.push(...checkFileForChinese(fullPath));}}} catch (error) {console.error(`${colors.red}無法讀取目錄 ${dir}: ${error.message}${colors.reset}`);}return results;
}// 高亮顯示中文字符
function highlightChinese(text) {return text.replace(/([\u4e00-\u9fa5]+)/g, `${colors.bgYellow}${colors.black}$1${colors.reset}`);
}// 主函數
function main() {console.log(`${colors.cyan}${colors.bright}=== 開始掃描中文字符... ===${colors.reset}`);const results = traverseDirectory('.');if (results.length === 0) {console.log(`${colors.green}${colors.bright}? 沒有找到非注釋中的中文字符!${colors.reset}`);} else {console.log(`${colors.yellow}${colors.bright}! 找到 ${results.length} 處可能需要國際化的中文字符:${colors.reset}\n`);// 按文件分組const fileGroups = {};results.forEach(result => {if (!fileGroups[result.file]) {fileGroups[result.file] = [];}fileGroups[result.file].push(result);});// 輸出分組結果Object.keys(fileGroups).forEach(file => {console.log(`${colors.blue}${colors.bright}文件: ${file}${colors.reset}`);fileGroups[file].forEach(result => {console.log(`  ${colors.magenta}${result.line}:${colors.reset} ${highlightChinese(result.content)}`);});console.log(''); // 空行分隔不同文件});console.log(`${colors.yellow}${colors.bright}請檢查上述中文字符,并考慮使用國際化方案替換它們。${colors.reset}`);}
}// 執行主函數
main();

然后通過node ./check-chinese.js來執行腳本

也可以在package.json中新增一個scripts

{..."scripts": {..."check-chinese": "node ./check-chinese.js"},
}

然后通過npm run check-chinese來執行腳本

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/diannao/80927.shtml
繁體地址,請注明出處:http://hk.pswp.cn/diannao/80927.shtml
英文地址,請注明出處:http://en.pswp.cn/diannao/80927.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

軟件分析師-第三遍-章節導圖-13/14

系統設計,按步驟分:概要設計、詳細設計。另一種分類方式:按設計內容和設計方法分。設計內容:處理流程、輸入/輸出原型、人機交互。設計方法:結構化、面向對象、設計模式。 軟件實現&測試,分為實現、測…

通過全局交叉注意力機制和距離感知訓練從多模態數據中識別橋本氏甲狀腺炎|文獻速遞-深度學習醫療AI最新文獻

Title 題目 Hashimoto’s thyroiditis recognition from multi-modal data via globalcross-attention and distance-aware training 通過全局交叉注意力機制和距離感知訓練從多模態數據中識別橋本氏甲狀腺炎 01 文獻速遞介紹 橋本氏甲狀腺炎(HT)&a…

刀客doc:小紅書商業技術負責人蒼響離職

根據大廠日爆的爆料,小紅書商業化再度迎來高層人事變動,原商業平臺技術負責人蒼響(薯名),職級L2,已于本月正式離職,其下屬團隊現由電商業務負責人接管。 根據刀客doc獲得的資料,蒼響…

Manus AI多語言手寫識別技術全解析:從模型架構到實戰部署

簡介 Manus AI作為當前多語言手寫識別領域的領軍技術,其核心創新在于融合三維卷積網絡、動態特征融合引擎和混合解碼系統,實現了對112種語言的98.7%識別準確率和8ms延遲的實時處理能力。本文將深入探討Manus AI的架構設計、特征提取方法、數據預處理策略…

華為云Astro大屏從iotda影子設備抽取數據做設備運行狀態的大屏實施步驟

目錄 背景與意義 1. 準備階段 2. IoTDA 開放影子查詢API 3. Astro輕應用創建連接器 4. Astro大屏設計界面 5. 數據綁定與交互邏輯 6. 發布與測試 小結(流程復盤) 背景與意義 隨著物聯網技術的快速發展,越來越多的設備接入云端&#x…

為什么要學習《易經》?

《易經》精華解讀:變易之道與人生智慧 《易經》(《周易》)是中國最古老的經典之一,被譽為“群經之首,大道之源”。它不僅是占卜之書,更是一部哲學經典,揭示了宇宙運行的規律和人生處世的智慧。…

逆傳播AIGEO營銷:破局生成式搜索時代,讓AI成為品牌代言人!

當GS(Generative Search生成式搜索)成為用戶的新“搜索入口”,你的品牌還在進行傳統軟文發布嗎? Gartner分析師預測"到2026年70%企業將把生成式AI整合進核心營銷系統",傳統SEO的正被AI搜索徹底重構。用戶的搜索行為發生史詩級轉變&#xff0…

WPF(Windows Presentation Foundation)的內容模型

WPF(Windows Presentation Foundation)的內容模型(Content Model)是其核心架構之一,定義了UI元素如何組織和呈現內容。以下是WPF內容模型的系統化解析: 1. 內容模型基礎概念 WPF通過邏輯樹和可視化樹管理內…

52.[前端開發-JS實戰框架應用]Day03-AJAX-插件開發-備課項目實戰-Lodash

常用JavaScript庫 1 認識前端工具庫 前端工具類庫 2 Lodash vs underscore underscore庫 VS Lodash庫 Lodash庫 的安裝 手寫精簡版的Lodash ;(function(g) {function Lodash() {}// 添加類方法Lodash.VERSION 1.0.0Lodash.join function(arr, separater) {// todo ......…

前端Ui設計工具

PS 稿、藍湖、Sketch 和 Figma 前端 UI 設計工具的對比分析 PS 稿(Adobe Photoshop) 提供精準設計細節:PS 稿能讓前端更精準地理解頁面布局、元素尺寸、顏色等,通過精確測量和查看信息面板,把握設計元素的空間關系、…

映射關系5

明白!🚀 你要我 繼續擴展,在這套 C98 代碼里加一個功能: 根據完整的5位ID,反查出對應的路徑。 OK,我直接接著上面那版來,給你補充 getPathFromId 方法,并且保持整體風格統一&#…

編譯原理:由淺入深從語法樹到文法類型

文法與語言基礎:從語法樹到文法類型 文法(Grammar)和語言(Language)是計算機科學和語言學中解析和理解語言結構的核心概念。無論是編程語言的編譯器設計,還是自然語言處理(NLP)中的…

第十三步:vue

Vue 1、上手 1、安裝 使用命令:npm create vuelatestvue文件后綴為.vueconst app createApp(App):初始化根組件app.mount("#app"):掛載根組件到頁面 2、文件 script標簽:編寫jstemplate標簽:編寫htmls…

Pytest-mark使用詳解(跳過、標記、參數 化)

1.前言 在工作中我們經常使用pytest.mark.XXXX進行裝飾器修飾,后面的XXX的不同,在pytest中有不同的作 用,其整體使用相對復雜,我們單獨將其抽取出來做詳細的講解。 2.pytest.mark.skip()/skipif()跳過用例 import pytest #無條…

基于 Spring Boot 的井字棋游戲開發與實現

目錄 引言 項目概述 項目搭建 1. 環境準備 2. 創建 Spring Boot 項目 3. 項目結構 代碼實現 1. DemoApplication.java 2. TicTacToeController.java 3. pom.xml 電腦落子策略 - Minimax 算法 findBestMove 方法 minimax 方法 運行游戲 總結 引言 在軟件開發領域&…

【算法筆記】貪心算法

一、什么是貪心算法? 貪心算法是一種在每一步選擇中都采取當前看起來最優(最“貪心”)的策略,從而希望得到全局最優解的算法設計思想。 核心思想:每一步都做出局部最優選擇,不回退。適用場景:…

現代c++獲取linux所有的網絡接口名稱

現代c獲取linux所有的網絡接口名稱 前言一、在linux中查看網絡接口名稱二、使用c代碼獲取三、驗證四、完整代碼如下五、總結 前言 本文介紹一種使用c獲取本地所有網絡接口名稱的方法。 一、在linux中查看網絡接口名稱 在linux系統中可以使用ifconfig -a命令列舉出本機所有網絡…

打印及判斷回文數組、打印N階數組、蛇形矩陣

打印回文數組 1 1 1 1 1 1 2 2 2 1 1 2 3 2 1 1 2 2 2 1 1 1 1 1 1方法1: 對角線對稱 左上和右下是對稱的。 所以先考慮左上打印, m i n ( i 1 , j 1 ) \text min(i1,j1) min(i1,j1),打印出來: 1 1 1 1 1 2 2 2 1 2 3 3 1 2 …

詳解UnityWebRequest類

什么是UnityWebRequest類 UnityWebRequest 是 Unity 引擎中用于處理網絡請求的一個強大類,它可以讓你在 Unity 項目里方便地與網絡資源進行交互,像發送 HTTP 請求、下載文件等操作都能實現。下面會詳細介紹 UnityWebRequest 的相關內容。 UnityWebRequ…

UE5 在旋轉A的基礎上執行旋轉B

用徑向slider實現模型旋轉時,得到的結果與ue編輯器里面的結果有很大出入。 問題應該是 兩個FRotator(0,10,0)和(10,20,30), 兩個FRotator的加法結果為&…