前端国际化-插件模式

文章目录

  • [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 中引入翻译文件,动态切换语言。
相关推荐
橙子家2 小时前
浏览器缓存之【身份与会话管理】:Cookies 和 Private state tokens
前端
最新资讯动态3 小时前
HDC 2026 | 对话鲸鸿动能:存量时代,品牌如何夺回营销“主动权”?
前端
最新资讯动态3 小时前
游戏出海,从产品走向体系
前端
最新资讯动态3 小时前
20人团队跑出百万DAU、大厂也来抢量:谁在鸿蒙生态跑出加速度
前端
最新资讯动态3 小时前
千万开发者背后,鸿蒙商业化的B面
前端
爱勇宝5 小时前
AI 时代:智商决定起点,情商决定走多远
前端·ai编程
kyriewen5 小时前
用了半年 Claude Code 后,我尝试关掉它写了一周代码——结果比想象中严重
前端·javascript·ai编程
IT_陈寒6 小时前
Vite的静态资源打包让我熬夜到三点,这坑千万别跳
前端·人工智能·后端
徐小夕7 小时前
万字拆解 JitWord:企业级实时协同文档底层架构 + 大模型 AI 融合完整实践
前端·vue.js·github
一份执念7 小时前
uni-app 小程序分包限制处理与主包体积优化实战
前端·微信小程序