深度解析 React Native #3:Babel #2 — 真实世界的战场
Source: Dev.to
绝对路径 & 别名 — “同步三角形”
许多开发者配置别名后运行应用,一切正常,但 VS Code 却显示红色错误。或者相反:VS Code 没问题,但应用崩溃。
为什么? 因为必须让三个系统保持一致:
| 系统 | 角色 |
|---|---|
| Babel | 运行时 – 让代码能够执行 |
TypeScript (tsconfig.json) | 开发体验 – 让 VS Code 能够识别导入 |
| Metro | (有时)解析重叠的导入 |
标准配置
安装解析插件:
yarn add -D babel-plugin-module-resolver
babel.config.js
module.exports = {
presets: ['module:@react-native/babel-preset'],
plugins: [
[
'module-resolver',
{
root: ['./src'],
extensions: ['.ios.js', '.android.js', '.js', '.ts', '.tsx', '.json'],
alias: {
'@components': './src/components',
'@utils': './src/utils',
'@assets': './src/assets',
},
},
],
],
};
陷阱 – 忘记 extensions 数组(例如省略 .ts/.tsx)会导致 “Module not found” 错误,因为 Babel 不会对 TypeScript 文件应用别名。
与 tsconfig.json 同步(必需)
{
"compilerOptions": {
"baseUrl": "./src",
"paths": {
"@components/*": ["components/*"],
"@utils/*": ["utils/*"]
}
}
}
为生产环境清理(移除 Console Log)
console.log 在开发阶段非常有价值,但在发布构建中会变成 毒药:
- 放慢 JS 桥接速度(字符串必须在 JS 与原生之间序列化)。
- 如果用户将设备连接到电脑,可能泄露敏感信息。
智能配置(动态)
babel.config.js 可以包含条件逻辑:
module.exports = function (api) {
// 缓存配置以加快构建速度
api.cache(true);
const presets = ['module:@react-native/babel-preset'];
const plugins = [];
// 仅在生产环境移除 console 语句
if (process.env.NODE_ENV === 'production') {
plugins.push('transform-remove-console');
}
return {
presets,
plugins,
};
};
开发者洞见: 使用 api.cache(true)(或 api.cache.using(() => process.env.NODE_ENV))可以防止 Babel 为每个文件重新计算配置,从而显著加快构建速度。
环境变量 & 缓存地狱
使用 react-native-dotenv 时,Babel 会把环境变量替换为字面字符串。
console.log(process.env.API_URL);
// becomes
console.log("https://api.example.com");
致命陷阱
把 .env 中的 API_URL 从 “dev” 改成 “prod” 并重新加载应用,可能仍然显示旧值。
原因: Babel(通过 Metro)缓存了之前的转换。由于源代码行 (process.env.API_URL) 没有变化,Babel 不会重新翻译它。
专家方案
- 在修改 env 文件后,以清除缓存的方式启动 Metro 打包器:
npx react-native start --reset-cache
- 或者在 Babel 配置中把
.env文件加入缓存键(更高级的做法)。
总结 – babel.config.js 的 3 条黄金法则
- 三角形原则: 在 Babel 中更改的任何路径别名都必须在
tsconfig.json中同步。 - 环境区分: 为开发和生产分别配置(例如在生产环境剔除 console 日志)。
- 重置缓存: 每次修改 Babel 或 env 配置后使用
--reset-cache。
console.log("Thanks for reading!");