Jer*_*Kun 10 javascript node.js babeljs react-native
我正在使用babel插件将环境变量从.env文件加载到React Native项目中,但是.env在导入它们的javascript文件发生更改之前,不会加载对文件的更改.我想要一种方法来告诉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" }]
]
}
}
}
Run Code Online (Sandbox Code Playgroud)
问题是react-native packager只监视javascript文件.我不认为改变我的babel配置会有所帮助,除非babel可以某种方式向上反应本地或守望者通知它某些文件需要重新编译...
[编辑2]
我确定react-native packager使用watchman来观看文件.例如,当我watchman watch-list在启动打包机之后(以及在做完之后watchman watch-del-all),我得到了
{
"version": "4.6.0",
"roots": [
"/path/to/my/project"
]
}
Run Code Online (Sandbox Code Playgroud)
此外,当我在打包器运行时删除这个手表时,没有任何反应(从它的角度来看,js没有改变,因为它没有收到任何更新),但是当我重新启动打包器时它会重新创建这个手表并转换所有内容.
所以看来,除非有更好的方法,否则我必须创建一个守望者触发器(1)杀死react-packager(2)杀死我的app目录上的监视(3)重启节点打包器.这看起来很慢而且很笨拙,但我想看看它是否能奏效.
我还没有完全按照通用的方式工作,但我正在尝试各种各样的事情.
因为我问这个问题已经过去两周了,所以我将发布我能够拼凑出来的(有点糟糕的)解决方法。我将不回答这个问题,并接受任何比这个更好(不那么老套)的新答案。
React Native 打包器使用watchman监视文件系统更改,并在收到某个 JS 文件已更改的事件时,它会查看该文件是否确实已更改,如果已更改,则重新编译。这阻止了我做一些简单的事情,比如touch使用相关 JS 文件的 watchman 触发器,因为 React 打包器认为它非常智能,可以忽略没有差异的更新。任何。
所以我的解决方案是创建一个监视程序触发器来.env更改哪个调用make clear_env_cache,其中clear_env_cache以下(虚假)目标在Makefile.
# get the PID of the react packager
pid := $(shell lsof -i:8081 | grep node | awk '{print $$2;}' | head -n 1)
# Kill files that the packager uses to determine whether it needs to
# re-transpile a js file, then restart the packager
clear_env_cache:
find ${TMPDIR}/react-native-packager-cache-* -name "my_pattern" | xargs rm
kill -9 $(pid) || echo "no packager running"
nohup node node_modules/react-native/local-cli/cli.js start > /dev/null 2>&1 &
Run Code Online (Sandbox Code Playgroud)
请注意,这my_pattern将根据您的项目布局而变化。对我来说,有一个文件导入所有名为 的环境变量Settings.js,因此模式是"*Settings*". 请注意,每次文件更改时,此目标基本上也会杀死并重新启动打包程序,并且它nohup是节点打包程序,因此您将无法再看到该进程。除非您需要查看打包器的输出,否则没什么大不了的。
触发此命令的 watchman-cli 命令是watchman-make --root . -p .env -t clear_env_cache,为了方便起见,我设置了该nohups命令的 make 目标:
# Run `make hotswap_env` to allow envvar changes to show up in the react-native packager.
hotswap_env:
nohup watchman-make --root . -p .env -t clear_env_cache > /dev/null 2>&1 &
Run Code Online (Sandbox Code Playgroud)
现在我可以(每次系统启动一次)运行make hotswap_env,只要发生变化就会触发.env并确保打包服务器持续运行。
免责声明:这个脚本可能不可移植,而且绝对脆弱。买者自负、YMMV 和 IANAL 等等。欢迎提出有关可移植性的改进建议。