问题描述
在 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" }
标签:Node,defined,polyfill,Lingui,btoa,js,构建,报错,环境 From: https://www.cnblogs.com/yz-blog/p/18683370