我正在使用babel插件将环境变量从.env文件加载到React Native项目中,但是直到导入它们的javascript文件更改之前,对.env文件的更改都不会加载。我想要一种告诉 native 打包程序在此文件发生更改的情况下重新编译的方法。我会接受这样的答案:

  • 当特定文件(.env)更改时,只需重新编译整个项目。
  • 仅重新编译包含特定字符串的文件,例如foo

  • 有没有简单的方法可以通过编写插件/中间件来做到这一点?也许有一个单独的后台脚本可以将事件触发给响应者 native 打包程序正在监听的事件?

    [编辑以回复评论]

    我当前的.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打包程序仅监视javascript文件。我认为更改babel配置不会有帮助,除非babel可以以某种方式向上对 native 或值类人员讲话以告知某些文件需要重新编译...

    [编辑2]

    我确定react-native打包程序使用watchman来监视文件。例如,当我在启动打包程序后(以及在完成watchman watch-list之后)执行watchman watch-del-all时,我得到了
    {
        "version": "4.6.0",
        "roots": [
            "/path/to/my/project"
        ]
    }
    

    此外,当我在打包程序运行时删除该 watch 时,什么也没有发生(从它的 Angular 来看,js并没有发生变化,因为它没有收到任何更新),但是当我重新启动打包程序时,它会重新创建这个 watch 并编译所有内容。

    看来,除非有更好的方法,否则我必须创建一个值类触发器来同时(1)杀死react-packager(2)杀死我的应用程序目录中的watch(3)重新启动 Node Packager。这似乎很慢而且很麻烦,但是我想看看它是否还能工作。

    我还没有完全以通用的方式来工作,但是我正在尝试各种方法。

    最佳答案

    自问这个问题以来已经过去了两个星期,所以我将发布我能够解决的(一种糟糕的)解决方法。我将不回答这个问题,并接受比此问题更好(更不容易理解)的任何新答案。

    react native打包程序使用watchman监视文件系统的更改,并在发现某个JS文件已更改的事件后,会查看该文件是否确实已更改,然后进行重新编译。这阻止了我执行像watchman触发器那样的简单操作,使touch成为相关的JS文件,因为react打包程序认为它是如此聪明,以至于可以忽略更新而无需进行差异。任何。

    所以我的解决方案是在.env更改上创建一个守卫触发器,该触发器调用make clear_env_cache,其中clear_env_cacheMakefile中的以下(语音)目标。

    # 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 &
    

    请注意,my_pattern将根据您的项目布局而变化。对我来说,有一个导入所有envvar的文件称为Settings.js,所以模式是"*Settings*"。请注意,每次文件更改时,此目标也基本上会杀死并重新启动打包程序,并且它nohup成为 Node 打包程序,因此您将无法再看到该过程。除非您需要查看打包程序的输出,否则没什么大不了的。

    watchman-cli触发此命令的命令是watchman-make --root . -p .env -t clear_env_cache,为方便起见,我设置了一个生成目标,将nohups用作此命令:
    # 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 &
    

    现在,我可以(每次系统引导一次)运行make hotswap_env,只要.env更改,它将触发,并确保打包程序服务器持续运行。

    免责声明:该脚本可能不可移植,并且绝对易碎。买权人,YMMV和IANAL等等。我们建议对可移植性进行改进。

    10-06 08:49