前端国际化-插件模式

文章目录

  • [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 中引入翻译文件,动态切换语言。
相关推荐
发渐稀1 分钟前
vue项目引入tailwindcss
前端·javascript·vue.js
用户26834842239591 分钟前
前端换肤功能最佳实践:从基础实现到高级优化
前端·css
前端掘金者H2 分钟前
Chrome插件实现WebPush推送通知的功能
前端·chrome
yinke小琪3 分钟前
快速开始 - TypeScript 入门指南
前端·typescript
青花雅月4 分钟前
封装标记📌前后数据比较的表格
前端·javascript
Kjjia5 分钟前
将内容明文存储在indexDB后,被指着鼻子骂道赶紧把数据隐藏...
前端·安全
冷凌爱11 分钟前
总结HTML中的文本标签
前端·笔记·html
小李小李不讲道理27 分钟前
「Ant Design 组件库探索」二:Button组件
前端·react.js·ant design
互联网搬砖老肖1 小时前
Web 架构之 CDN 加速原理与落地实践
前端·架构
会飞的鱼先生1 小时前
javascript中Cookie、BOM、DOM的使用
前端·javascript·chrome