Hi,
hate to ask this question for fear of making a newbie mistake.
I uninstall all versions of elixir I had from brew, and reinstalled elixir 1.0.5.
> brew list elixir
/usr/local/Cellar/elixir/1.0.5/bin/elixir
/usr/local/Cellar/elixir/1.0.5/bin/elixirc
/usr/local/Cellar/elixir/1.0.5/bin/iex
/usr/local/Cellar/elixir/1.0.5/bin/mix
/usr/local/Cellar/elixir/1.0.5/lib/eex/ (7 files)
/usr/local/Cellar/elixir/1.0.5/lib/elixir/ (200 files)
/usr/local/Cellar/elixir/1.0.5/lib/ex_unit/ (21 files)
/usr/local/Cellar/elixir/1.0.5/lib/iex/ (13 files)
/usr/local/Cellar/elixir/1.0.5/lib/logger/ (10 files)
/usr/local/Cellar/elixir/1.0.5/lib/mix/ (71 files)
I have phoenix 1.0.0 with a newly generated project following the tutorial:
> mix deps
* fs 0.9.1 (Hex package)
locked at 0.9.2 (fs)
ok
* ranch 1.1.0 (Hex package)
locked at 1.1.0 (ranch)
ok
* poolboy 1.5.1 (Hex package)
locked at 1.5.1 (poolboy)
ok
* decimal 1.1.0 (Hex package)
locked at 1.1.0 (decimal)
ok
* poison 1.5.0 (Hex package)
locked at 1.5.0 (poison)
ok
* cowlib 1.0.1 (Hex package)
locked at 1.0.1 (cowlib)
ok
* cowboy 1.0.2 (Hex package)
locked at 1.0.2 (cowboy)
ok
* plug 1.0.0 (Hex package)
locked at 1.0.0 (plug)
ok
* phoenix_html 2.1.2 (Hex package)
locked at 2.1.2 (phoenix_html)
ok
* phoenix 1.0.0 (Hex package)
locked at 1.0.0 (phoenix)
ok
* phoenix_live_reload 1.0.0 (Hex package)
locked at 1.0.0 (phoenix_live_reload)
ok
* postgrex 0.9.1 (Hex package)
locked at 0.9.1 (postgrex)
ok
* ecto 1.0.0 (Hex package)
locked at 1.0.0 (ecto)
ok
* phoenix_ecto 1.1.0 (Hex package)
locked at 1.1.0 (phoenix_ecto)
ok
I am on OS X 10.9.5
When I change any code in web, the server does not recompile the code, and I have to restart the server for changes to take effect. For example, if I change the HelloController from the tutorial.
However, when I make changes to templates, those changes are picked up at the livereload works as designed.
I did not make any modifications to my dev.exs, and code_reloader: true is set.
Did I miss a step somewhere? I did my best to google/github search for similar issues.
[edit]
continued googling and looking at the FS dependency, i found this issue from josevalim:
https://github.com/synrc/fs/issues/17 which links to https://github.com/phoenixframework/phoenix/issues/920
Is there a workaround for os x yet? or is this a common issue?
Thanks!
Chris
Let's start simple. What editor are you using? Are you using a plugin like syntactic in vim that check for syntax errors? These have been known to cause issues because they mess with ctime/mtime. Can you try a different editor really quickly, i.e. open a controller in TextEdit, save it, then refresh. If you still don't see a recompile, we'll keep digging.
wow, thanks @chrismccord. you nailed it.
i was using vim, and if i switched to atom or something else, it worked fine.
i'm guessing this is a known issue with no other workaround at this time but to disable the plugin?
i'm guessing this is a known issue with no other workaround at this time but to disable the plugin?
yes, unfortunately. What happens is the plugin saves and recompiles the file behind the scenes, so when the next browser request comes in, mix looks at the project and all files are already compiled, and it noops. I'm not aware of any workarounds, so if you aren't married to the plugin, I'd disable.
thanks for the explanation and the help.
Hi,
I had the same issue with Atom linter, which also recompiles the project in the background.
I thought a simple workaround would be to tell the linter to touch the file after it is done,
so that when the next request comes, the reloader compiles the changes.
After giving it a shot, it seems that touching the file just after the project has been recompiled does not have any effect. I had to set the modification timestamp about 800ms after the recompilation for the code reloading to happen.
Is there some threshold value in mtime difference for the files to be recompiled, or is there some other explanation?
Thanks!
Is there some threshold value in mtime difference for the files to be recompiled, or is there some other explanation?
No. The explanation sounds like you are racing the code reloading detecting the changes, issues a new request, and recompiling the project.
@chrismccord Thanks for the quick reply, I am going to try to find a better workaround.
Hi @tuvistavie ! Have you finally found a better workaround? I'm experiencing just the same issue with Atom.io and linter-elixirc :(
Thanks in advance!
Hi @bigardone, I am still using my clumsy timestamp hack, it's not perfect but still much better than working without linter or without code reload for me.
@tuvistavie thanks for the response. I've found that checking the 'Always use elixirc' option in the linter-elixirc package settings makes it work like a charm.

@bigardone This works great, thanks!
Has anyone found a fix for vim/syntastic users?
@mollerhoj this is what I use with Neomake, which I assume can translate to Syntastic.
let g:neomake_elixir_enabled_makers = ['elixir']
let g:neomake_elixir_elixir_maker = {
\ 'exe': 'elixirc',
\ 'args': [
\ '--ignore-module-conflict', '--warnings-as-errors',
\ '--app', 'mix', '--app', 'ex_unit',
\ '-o', '$TMPDIR', '%:p'
\ ],
\ 'errorformat':
\ '%E** %s %f:%l: %m,' .
\ '%W%f:%l'
\ }
If you look closely, I had to change the warning format for Elixir 1.3 from what's in the source (https://github.com/neomake/neomake/blob/ae6639b3cf6c263a54239648ce6522b569eaced7/autoload/neomake/makers/ft/elixir.vim#L11). This is not ideal, and I've opened https://github.com/elixir-lang/elixir/issues/5143 to address it.
Thankfully I found this else I would have wasted way too much time debugging something that was working just fine. I figured I'd post my workaround in case it helps other people. I too use VIM, along with Ale for linting (https://github.com/w0rp/ale).
Ale provides a hook to execute an arbitrary function after linting is complete. What I did was disable Ale, sleep for a small amount of time, resave the file, and enable Ale again. Unfortunately I couldn't get it to work without the sleep...but then again i didn't invest a ton of time into this. Below 500ms it would work sometimes and fail other times. If someone can come up with a more elegant solution that would be awesome! Below are my .vimrc related to Ale:
" Settings for Ale
let g:ale_lint_on_text_changed = 'never'
let g:ale_sign_column_always = 1
let g:ale_statusline_format = ['⨉ %d', '⚠ %d', '⬥ ok']
let g:ale_javascript_eslint_executable = 'eslint_d'
let g:ale_sign_error = '✗'
let g:ale_sign_warning = '⚠'
augroup AleGroup
autocmd!
autocmd User ALELint call TouchOpenFile()
augroup END
func! TouchOpenFile()
let g:ale_enabled = 0
sleep 500m
w
let g:ale_enabled = 1
endfunc
Just stumble into this as a Vim Ale user. After testing, I found that the reason reloading isn't working is that when a mix task doesn't exist, mix would compile the current source then complain about the missing task.
Step to replicate this behaviour:
cd /tmp
mix phx.new hello
cd hello
mix compile
mix dogma # Since it's compiled in the previous step, you won't see a compile message, you'll just see a complaint
echo '' >> lib/hello_web/controllers/page_controller.ex
mix dogma # Since the source was modified in the previous, you'll see a compile message, and also the same complaint
# Now add `{:dogma, "~> 0.1", only: :dev},` to the mix.exs file
mix deps.get
mix compile
mix dogma # No compile message here of course
echo '' >> lib/hello_web/controllers/page_controller.ex
mix dogma # No compile message here again!!
mix compile # This proves that mix dogma stops compiling source if the task exists
Based on the knowledge that mix missing_task recompiles and that the default linters for ale for elixir are credo and dogma, we have a conclusion that if you don't have either credo or dogma, you're in a pickle.
So the simple workarounds here are:
However, I believe the ultimate solution would be looking into the mix command and see if it's possible to not recompile if the task is not found. Since this is a problem that's gonna exist in all editors.
I had a vs-code-elixir-linter package installed in VSCode that caused this. Just disabling or uninstalling fixed the issue 👍🏼
I had this problem with VSCode's elixir language server... the problem is that the files get recompiled by the external editor, but not re-loaded by the code-reloader module in the running Erlang VM, because the compiler does nothing when everything looks up-to-date.
I while back I extended a module someone designed for non-Phoenix use, which is based on the built-in Phoenix.CodeReloader, to take into account the modification time of the build manifest files, and checks if they have changed since the last request; this then works with external compilations made by editor modules and other tools, and could be folded back into Phoenix.
See the fork here: https://github.com/Financial-Times/code_reloader, in particular the https://github.com/Financial-Times/code_reloader/blob/master/lib/code_reloader/server.ex mix_compile_unless_stale_config/2 and reload_modules/0.
The main change is that if the manifests are found to have been modified on the file-system since the last check, then after forcing a compilation (which may do nothing), the :code module is used to purge and load all modified modules (where modified means "the in-memory version isn't the same as the filesystem version").
A quick fix is just making the vscode/atom/whatever elixir language server use MIX_ENV=test instead of the default dev too. Though it would be very nice to fix the code reloader.
Sticking let $MIX_ENV='test' in my .vimrc fixed this issue for me.
Most helpful comment
Thankfully I found this else I would have wasted way too much time debugging something that was working just fine. I figured I'd post my workaround in case it helps other people. I too use VIM, along with Ale for linting (https://github.com/w0rp/ale).
Ale provides a hook to execute an arbitrary function after linting is complete. What I did was disable Ale, sleep for a small amount of time, resave the file, and enable Ale again. Unfortunately I couldn't get it to work without the sleep...but then again i didn't invest a ton of time into this. Below 500ms it would work sometimes and fail other times. If someone can come up with a more elegant solution that would be awesome! Below are my .vimrc related to Ale: