web-dev-qa-db-fra.com

Comment recompiler un projet Elixir et le recharger depuis iex?

J'apprends actuellement Elixir en parcourant le programme OTP et en combinant des didacticiels sur le site Web elixir-lang, et je ne parviens pas à trouver comment recompiler et recharger le projet à partir de Shell.

Dans Erlang, je ferais make:all([load]) et il compilerait et chargerait tous les changements survenus. Cependant, dans iex, cela dit toujours :up_to_date, ce qui a du sens, car Elixir utilise mix pour répondre à ses besoins de compilation.

Je ne trouve pas d'équivalent dans iex.

49
KallDrexx

Vous pouvez utiliser le IEx.Helpers.recompile/0 fonction.

Recompile l'application de mixage en cours.

Cet assistant ne fonctionne que lorsque IEx est démarré avec un projet Mix, par exemple, iex -S mix. Avant de compiler le code, il arrêtera l’application en cours et le relancera par la suite. L'arrêt des applications est nécessaire pour que les processus de l'arborescence de supervision ne se bloquent pas lorsque le code est mis à niveau à plusieurs reprises sans passer par le mécanisme d'échange de code à chaud approprié.

Changements en mix.exs ou les fichiers de configuration ne seront pas récupérés par cet assistant, mais uniquement les modifications de sources. Le redémarrage du shell et du mixage est requis dans de tels cas.

Si vous souhaitez recharger un seul module, envisagez d'utiliser r ModuleName au lieu.

REMARQUE: cette fonctionnalité est expérimentale et peut être supprimée dans les prochaines versions.

De https://github.com/elixir-lang/elixir/blob/v1.2.4/lib/iex/lib/iex/helpers.ex#L56-L9

82
Dogbert

26 février 2017:

Pour charger à chaud des composants dans un système en cours d’exécution avec le moins de chances que quelque chose se passe mal, utilisez:

case c(filename_ex, :in_memory) do
    [] -> :ignore
    [mod|_] -> r(mod)
end

Réponse originale:

Dans elixir 1.3.0, la recompilation ne redémarre plus l’application. Donc, la manière correcte de vérifier si une source a changé et que le hotload est:

iex> recompile()

REMARQUE: je souhaite ajouter qu'en raison de problèmes liés à la suppression de modules lors de la recompilation, il est fort probable que les processus se bloquent pendant la recompilation si vous avez des messages en vol comme un gen_statem avec state_timeout.

REMARQUE 2: Si vous faites une erreur dans un fichier source à l'aide de recompiler/0, le projet sera compilé avec le fichier source manquant et déchargé.

20
Vans S

Le seul inconvénient de la réponse de @ Dogbert que j'ai trouvée est qu'il arrête et redémarre complètement l'application. Bien que ce soit ok en théorie, cela a échoué dans mon projet actuel car mon projet dépendait de Ranch, mais tout ne s'est pas arrêté correctement. Cela signifiait que les choses se sont cassées quand il a essayé de redémarrer le projet, il a échoué car le socket était déjà utilisé.

Bref, j'ai regardé le code de l'aide et ajouté la fonction suivante à mon module:

  def recompile() do
    Mix.Task.reenable("app.start")
    Mix.Task.reenable("compile")
    Mix.Task.reenable("compile.all")
    compilers = Mix.compilers
    Enum.each compilers, &Mix.Task.reenable("compile.#{&1}")
    Mix.Task.run("compile.all")
  end  

Maintenant je peux entrer MyApp.recompile et tout est rechargé à chaud sans que l'application ne redémarre.

6
KallDrexx