前端国际化-插件模式

文章目录

  • [Webpack 插件开发](#Webpack 插件开发)
  • 解析中文
  • [调用有道翻译 API](#调用有道翻译 API)
  • [生成 JSON 语言文件](#生成 JSON 语言文件)
  • [React 国际化实现](#React 国际化实现)

Webpack 插件开发

  • 创建 i18n-webpack-plugin.js 插件:
  • 在 src 目录下扫描所有文件
  • 使用 babel-parser 解析 JavaScript/JSX 代码
  • 识别中文文本
  • 通过有道翻译 API 翻译
  • 生成 locales/en.json(英语)和 locales/zh.json(中文)
javascript 复制代码
const fs = require("fs");
const path = require("path");
const parser = require("@babel/parser");
const traverse = require("@babel/traverse").default;
const fetch = require("node-fetch");

class I18nWebpackPlugin {
  constructor(options) {
    this.options = options || {};
    this.localeDir = path.resolve(process.cwd(), "locales");
    this.zhJsonPath = path.join(this.localeDir, "zh.json");
    this.enJsonPath = path.join(this.localeDir, "en.json");
  }

  async extractChinese(content) {
    const ast = parser.parse(content, { sourceType: "module", plugins: ["jsx"] });
    const chineseTexts = new Set();

    traverse(ast, {
      StringLiteral({ node }) {
        if (/[\u4e00-\u9fa5]/.test(node.value)) {
          chineseTexts.add(node.value);
        }
      },
      JSXText({ node }) {
        if (/[\u4e00-\u9fa5]/.test(node.value.trim())) {
          chineseTexts.add(node.value.trim());
        }
      }
    });

    return Array.from(chineseTexts);
  }

  async translateText(text) {
    const apiKey = "your-app-key";
    const apiSecret = "your-app-secret";
    const url = `https://openapi.youdao.com/api?q=${encodeURIComponent(text)}&from=zh-CHS&to=en&appKey=${apiKey}`;
    
    const response = await fetch(url);
    const data = await response.json();
    return data.translation ? data.translation[0] : text;
  }

  async apply(compiler) {
    compiler.hooks.emit.tapAsync("I18nWebpackPlugin", async (compilation, callback) => {
      const srcDir = path.resolve(process.cwd(), "src");
      const files = fs.readdirSync(srcDir).filter(file => file.endsWith(".js") || file.endsWith(".jsx"));

      let translations = {};
      for (const file of files) {
        const content = fs.readFileSync(path.join(srcDir, file), "utf-8");
        const chineseTexts = await this.extractChinese(content);
        
        for (const text of chineseTexts) {
          if (!translations[text]) {
            translations[text] = await this.translateText(text);
          }
        }
      }

      if (!fs.existsSync(this.localeDir)) {
        fs.mkdirSync(this.localeDir);
      }

      fs.writeFileSync(this.zhJsonPath, JSON.stringify(translations, null, 2), "utf-8");
      fs.writeFileSync(this.enJsonPath, JSON.stringify(translations, null, 2), "utf-8");

      console.log("✅ 国际化 JSON 文件已生成!");
      callback();
    });
  }
}

module.exports = I18nWebpackPlugin;

解析中文

  • 使用 babel-parser 解析代码,提取 JSX 内的中文文本和 JavaScript 代码中的字符串中文。

调用有道翻译 API

有道 API 示例:

javascript 复制代码
const fetch = require('node-fetch');

async function translate(text, from = 'zh-CHS', to = 'en') {
  const appKey = 'your-app-key';
  const appSecret = 'your-app-secret';
  const url = `https://openapi.youdao.com/api?q=${encodeURIComponent(text)}&from=${from}&to=${to}&appKey=${appKey}`;

  const response = await fetch(url);
  const data = await response.json();
  return data.translation[0]; // 返回翻译结果
}

生成 JSON 语言文件

扫描所有 src 目录的文件后,创建 locales/en.json 和 locales/zh.json 语言包,格式如下:

javascript 复制代码
{
  "首页": "Home",
  "你好": "Hello"
}

React 国际化实现

  • 使用 react-intl 或 i18next 进行国际化支持,并在 App.js 中引入翻译文件,动态切换语言。
相关推荐
OpenTiny社区8 分钟前
生成式UI,AI交互的下一个十年?OpenTiny在QCon 2026的深度分享
前端·开源·github
gyx_这个杀手不太冷静16 分钟前
大人工智能时代下前端界面全新开发模式的思考(六)
前端·架构·ai编程
yngsqq18 分钟前
编译的dll自动复制到指定目录并重命名
java·服务器·前端
研☆香31 分钟前
聊一聊js中的正则表达式的应用
前端·javascript·正则表达式
开心就好202533 分钟前
使用Edge和ADB进行Android Webview远程调试的完整教程
前端·ios
用泥种荷花1 小时前
从 0 到 1 做一个支持 NFC 写入的小程序,需要哪些 API?
前端
90程序员1 小时前
纯浏览器解析 APK 信息,不用服务器 | 开源了一个小工具
前端·apk
用户11481867894841 小时前
Vosk-Browser 实现浏览器离线语音转文字
前端·javascript
江上清风山间明月1 小时前
Vite现代化的前端构建工具详解
前端·webpack·nodejs·vite
PBitW1 小时前
apijson 让前端自己定义接口 —— 但不推荐
前端·apijson