我正在使用babel插件将 .env
文件中的环境变量加载到React Native项目中,但在导入它们的javascript文件发生更改之前,不会加载对 .env
文件的更改 . 我想要一种方法来告诉react-native packager在这个文件发生变化的情况下重新编译 . 我会接受一个答案:
-
当特定文件(
.env
)发生变化时,只需重新编译整个项目 . -
仅重新转换包含特定字符串的文件,例如
foo
有没有一种简单的方法来编写插件/中间件?也许是一个单独的后台脚本,它会向反派原生包装器正在监听的守望者发起事件?
[编辑回复评论]
我当前的 .babelrc
如下,其中 babel-plugin-react-native-config
是我写的一个插件,用于与 react-native-config
包一起进行热变量交换 .
{
"presets": [
"react-native"
],
"plugins": [
["babel-plugin-espower", {
"sourceRoot": "./App"
}],
"transform-flow-strip-types"
],
"env": {
"production": {
"plugins": [
"babel-plugin-unassert",
]
},
"development": {
"plugins": [
["babel-plugin-react-native-config", { envfile: ".env" }]
]
}
}
}
问题是react-native packager只监视javascript文件 . 我不认为改变我的babel配置会有所帮助,除非babel可以某种方式向上反应本地或守望者通知它某些文件需要重新编译...
[编辑2]
我确定react-native packager使用watchman来观看文件 . 例如,当我在启动包装工具后(以及在做了 watchman watch-del-all
之后) watchman watch-list
时,我得到了
{
"version": "4.6.0",
"roots": [
"/path/to/my/project"
]
}
此外,当我在打包器运行时删除这个 Watch 时,没有任何反应(从它的角度来看,js没有改变,因为它没有收到任何更新),但是当我重新启动打包器时它会重新创建这个 Watch 并转换所有内容 .
所以看来,除非有更好的方法,否则我必须创建一个守望者触发器(1)杀死react-packager(2)杀死我的app目录上的监视(3)重启节点打包器 . 这看起来很慢而且很笨拙,但我想看看它是否能奏效 .
我还没有完全按照通用的方式工作,但我正在尝试各种各样的事情 .
1 回答
自从我提出这个问题已经过去两周了,我将发布我能够拼凑的(那种可怕的)解决方法 . 我将不回答这个问题,接受任何比这个更好(更少hacky)的新答案 .
react native packager使用
watchman
来监视文件系统更改,并且在获得某个JS文件已更改的事件时,它会查看文件是否实际已更改,然后重新传输(如果是这样) . 这可以防止我做一些像监视器触发器那样简单的事情,因为反应包装器认为它非常聪明,可以忽略没有差异的更新 . 随你 .所以我的解决方案是在
.env
上更改调用make clear_env_cache
创建一个守望者触发器,其中clear_env_cache
是Makefile
中的以下(虚假)目标 .请注意,
my_pattern
将根据您的项目布局而更改 . 对我来说,有一个文件导入所有名为Settings.js
的envvars,因此模式是"*Settings*"
. 请注意,每次文件更改时,此目标基本上也会杀死并重新启动打包程序,并且它将成为节点打包程序,因此您将无法再查看该过程 . 除非您需要查看打包器的输出,否则不是什么大问题 .用于触发此操作的watchman-cli命令是
watchman-make --root . -p .env -t clear_env_cache
,为方便起见,我设置了一个make目标nohups
此命令:现在我可以(每次系统启动一次)运行
make hotswap_env
并且只要.env
更改它就会触发并确保打包服务器持续运行 .Disclaimer: 这个脚本可能不是便携式的,而且非常脆弱 . 需要注意的是Emptor和YMMV以及IANAL等等 . 我们欢迎建议改进便携性 .