Скажите реактивному родному упаковщику, чтобы посмотреть файл без javascript

Я использую плагин babel для загрузки переменных среды из файла .env в проект React Native, но изменения в файле .env не загружаются, пока файл javascript не импортирует их. Мне бы хотелось, чтобы рекомпилятор реагировал на собственный пакет, чтобы этот файл изменился. Я бы принял ответ, что:

  • Просто перераспределяет весь проект, когда изменяется конкретный файл (.env).
  • Повторно транслирует только те файлы, которые содержат определенную строку, например foo

Есть ли простой способ сделать это, написав плагин/промежуточное ПО? Может быть, отдельный фон script, который вызывает события для сторожа, которого прослушивает перезаписываемый пакетный агент?

[EDIT в ответ на комментарий]

Мой текущий .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" }]
      ]
    }
  }  
}

Проблема в том, что обработчик-нативный упаковщик просматривает только файлы javascript. Я не думаю, что изменение настройки моего Babel поможет, если только Babel не может как-то говорить вверх, чтобы реагировать на родного или сторожа, чтобы сообщить ему, что какой-то файл нуждается в перекомпиляции...

[ИЗМЕНИТЬ 2]

Я определил, что накладной упаковщик использует сторожа для просмотра файлов. Например, когда я делаю watchman watch-list после запуска упаковщика (и после выполнения watchman watch-del-all), я получаю

{
    "version": "4.6.0",
    "roots": [
        "/path/to/my/project"
    ]
}

Кроме того, когда я удаляю эти часы во время работы пакета, ничего не происходит (с его точки зрения, js не меняется, потому что он не получает никаких обновлений), но затем, когда я перезапускаю упаковщик, он воссоздает эти часы и переворачивает все.

Итак, кажется, что, если нет лучшего способа, я должен создать триггер сторожа для обоих (1) убить реактивный упаковщик (2) убить часы в моем каталоге приложений (3) перезапустить упаковщик node, Это кажется медленным и взломанным, но я хотел бы видеть, может ли он даже работать.

Я не совсем понял, что это работает в общем виде, но я экспериментирую с разными вещами.

Ответ 1

Так как прошло две недели с тех пор, как я задал этот вопрос, я собираюсь опубликовать (вроде ужасное) обходное решение, которое я смог собрать. Я оставлю этот вопрос без ответа и примите новый ответ, который лучше (менее хакерский), чем этот.

Реактивный нативный пакетщик использует watchman для просмотра изменений в файловой системе, а после получения события, которое изменил какой-то JS файл, он смотрит, действительно ли файл действительно изменился, а затем ретранслирует, если это так. Это мешает мне сделать что-то простое, как триггер сторожа, который touch использует соответствующий JS файл, потому что реактивный упаковщик считает его настолько умным, что может игнорировать обновления без diff. Безотносительно.

Итак, мое решение заключается в создании триггера сторожевого таймера при изменении .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 &

Обратите внимание, что my_pattern изменится в зависимости от вашего макета проекта. Для меня один файл импортирует все envvars под названием Settings.js, поэтому шаблон "*Settings*". Обратите внимание, что эта цель также в основном убивает и перезагружает упаковщик при каждом изменении файла, а nohup - упаковщик node, чтобы вы больше не могли видеть этот процесс. Не большое дело, если вам не нужно просматривать выходные данные упаковщика.

Команда watchman-cli запускает это watchman-make --root . -p .env -t clear_env_cache, и для удобства я настроил make-мишень, чтобы 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 изменяет и гарантирует, что сервер-упаковщик будет постоянно работать.

Отказ от ответственности: Этот script, вероятно, не переносимый и, безусловно, хрупкий. Caveat emptor и YMMV и IANAL и все такое. Предлагаемые улучшения переносимости приветствуются.