react-native - 使用 Create React Native App 和 Expo 在 React Native 的构建时自定义代码
问题描述
一般来说,有没有办法在构建步骤中自定义应用程序代码?
具体来说,通常需要从应用程序向本地后端([1]、[2]、[3]、[4])发出请求。
localhost
不起作用,因为服务器和应用程序位于不同的主机上(使用 Android 模拟器或实际物理设备时)。- 同一网络中主机的实际 IP 地址可以工作,但在多开发人员项目中,每个人不断将代码中的常量 IP 更改为他们开发机器的 IP 地址是一件麻烦事。
使用 Webpack 可以解决类似的情况,使用DefinePlugin将占位符替换为正在构建的机器的 IP 地址。
解决方案
我们最终使用了受变形金刚react-native-typescript-transformer
或react-native-sass-transformer
. 它的想法几乎等同于提到DefinePlugin
的Webpack。
首先,项目目录中的一些转换器文件(您可以随意命名它们,只需更新引用即可):
configBuildReplacements.js
// whatever logic you need
module.exports = {
API_HOST_PLACEHOLDER: `http://${getLocalNetworkAddress()}:3000`,
SOME_OTHER_DYNAMIC_VALUE: someFun(),
}
configBuildReplaceTransformer.js
const semver = require('semver')
let upstreamTransformer = null
const reactNativeVersionString = require('react-native/package.json').version
const reactNativeMinorVersion = semver(reactNativeVersionString).minor
if (reactNativeMinorVersion >= 56) {
upstreamTransformer = require('metro/src/reactNativeTransformer')
}
else if (reactNativeMinorVersion >= 52) {
upstreamTransformer = require('metro/src/transformer')
}
else if (reactNativeMinorVersion >= 47) {
upstreamTransformer = require('metro-bundler/src/transformer')
}
else if (reactNativeMinorVersion === 46) {
upstreamTransformer = require('metro-bundler/build/transformer')
}
else {
// handle RN <= 0.45
const oldUpstreamTransformer = require('react-native/packager/transformer')
upstreamTransformer = {
transform({ src, filename, options }) {
return oldUpstreamTransformer.transform(src, filename, options)
},
}
}
module.exports.transform = function (src, filename, options) {
// handle RN >= 0.46
if (typeof src === 'object') {
({ src, filename, options } = src)
}
const replacements = require('./configBuildReplacements')
const modifiedSrc = Object.keys(replacements).reduce(
(src, replacementKey) => src.replace(
new RegExp(replacementKey, 'g'),
replacements[replacementKey],
),
src,
)
return upstreamTransformer.transform({
src: modifiedSrc,
filename,
options,
})
}
导出transform
函数使用从前一个文件中导出的对象configBuildReplacements.js
作为字典,将源代码中的键子字符串替换为值子字符串,然后将此代码交给默认(上游)转换器。
并将这个新变压器连接到项目:
使用 Expo,将
transformer
打包程序选项添加到app.json
:{ "expo": { "packagerOpts": { "transformer": "configBuildReplaceTransformer.js" } } }
在没有 Expo 的情况下,添加
getTransformModulePath()
到rn-cli.config.js
(这是 React Native CLI 的可选配置文件的默认路径,在撰写本文时该文件的文档非常少):module.exports = { getTransformModulePath() { return require.resolve('./configBuildReplaceTransformer') }, }
完成后,就像 with 一样DefinePlugin
,代码如下
get('API_HOST_PLACEHOLDER/info')
会变成类似的东西
get('http://192.168.42.23:3000/info')
推荐阅读
- java - @CreationTimestamp 和 @UpdateTimestamp 不适用于 JPA 2.0.2
- c# - 如何为 Swagger UI 定义参数的默认值?
- arrays - 添加新值时使用 onEdit(e) 更新单元格
- excel - 在 Sub VBA 中调用用户定义的函数
- c# - 制作类来封装 isLong/isDouble 函数
- python - SAM 命令失败:ImportError: cannot import name AliasedEventEmitter
- node.js - 使用节点数组创建 JSON 对象
- c# - 使用特定的数组计数
- python - 如何在 Django 休息框架中获取具有父模型的前键的子模型?
- jquery - jQuery:anime.js 到多个相同的目标