Loading

解决 Jenkins 环境下 Lingui 构建报错 "btoa is not defined"

问题描述

在 Jenkins CI 环境中构建 React 项目时,遇到了以下错误:

Error: btoa is not defined
  11 | };
  12 | const QkImagePreview = (props: QkImagePreviewType) => {
> 13 |   const { i18n, t } = useLingui();
     |                       ^^^^^^^^^^^
  14 |   const [visible, setVisible] = useState(false);

这个错误发生在使用 @lingui/macro 进行国际化构建时。有趣的是,这个错误只在 Jenkins 环境中出现,在本地 Windows 环境中构建是正常的。

原因分析

  • btoa 函数是浏览器原生提供的 API,用于将二进制字符串转换为 Base64 编码
  • 在 Node.js 环境中,btoa 函数默认是不存在的
  • Lingui 在构建过程中需要使用 btoa 来生成消息 ID
  • Jenkins 使用 Node.js 环境进行构建,所以缺少这个函数

解决方案

1. 创建 Polyfill 文件

创建 src/utils/btoa-polyfill.ts:

// btoa polyfill for Node.js
if (typeof btoa === 'undefined') {
  global.btoa = function (str: string) {
    return Buffer.from(str, 'binary').toString('base64');
  };
}

export {};

2. 在 Vite 配置中引入 Polyfill

修改 vite.config.ts:

import { defineConfig, loadEnv } from 'vite';
// ... 其他导入
import './src/utils/btoa-polyfill';

export default defineConfig(({ mode }) => {
  // ... 配置内容
});

技术要点

  • 这是一个典型的环境差异导致的问题 - 浏览器环境 vs Node.js 环境
  • Polyfill 的实现利用了 Node.js 的 Buffer API 来模拟浏览器的 btoa 功能
  • 在 Vite 配置文件中导入 polyfill 确保它在构建过程的早期被加载

注意事项

1. 这个 polyfill 只在构建时需要,不会影响到生产环境的代码

2. 该解决方案适用于所有使用 Lingui + Vite 的项目在 Node.js 环境下的构建

3. 如果使用其他构建工具(如 webpack),可能需要调整 polyfill 的引入方式

相关依赖版本

{
  "@lingui/core": "^5.1.0",
  "@lingui/macro": "^5.1.0",
  "@lingui/react": "^5.1.0",
  "vite": "^4.3.9"
}

  

posted @ 2025-01-21 11:48  冯叶青  阅读(55)  评论(0)    收藏  举报