Is it possible to use Ember CLI's Live Reload support from Nitrious.io?


#1

The only caveat I thought there’d be would be to ember serve with a --live-reload-port number between 1024-9999. Live Reload doesn’t work though. I get the following browser console error in the example case of running the command ember serve --live-reload-port 4300:

GET http://localhost:4300/livereload.js?snipver=1 net::ERR_CONNECTION_REFUSED

So the app’s index.html file is dynamically being plugged with a script tag pointing to that URL. Is there way I can provide another host besides localhost in this case?


#2

Nitrous had port forwarding last time I used it, so you can use live-reload as you usually would


#3

The problem though is the {{content-for "head"}} expression in the index.html file. It outputs a meta and the script tag I described above. How can I get the output script tag to point at my Nitrious.io domain instead of localhost? Then there’s the issue of the content security policy thing.


#4

Those are two separate issues, actually. Content Security Policy you’re going to have to start whitelisting. That script tag is fine, though. Are you serving the app inside nitrous and working from your local? Or are you working with Nitrous, on the website?


#5

Serving the app inside Nitrous and working from Nitrous’ web IDE. And yes since I posted I’ve read up on the CSP stuff so I can handle that if I get to that point I think. So the only issue is about changing the host name Ember CLI plugs into the script tag {{content-for 'head'}} generates.


#6

I’ve been able to get live reload to work with nitrous.io and ember-cli 0.0.46. I’m sure everything should still apply. As you can read here, you may only forward a specific port range, so first thing you need to do is start ember serve with a custom live reload port as the default port is well beyond the allowed range:

ember serve --live-reload-port 4202

Since the hostname is dynamic, you will need to dynamically add the live reload script element in index.html:

<script>
  var script = document.createElement('script');
  var src = window.location.protocol + '//' + window.location.hostname + ':4202/livereload.js?snipver=1';
  script.setAttribute('src', src);
  script.setAttribute('type', 'text/javascript');
  document.body.appendChild(script);
</script>

#7

Thanks for the tip nkgm.

Doing that or simply hardcoding my Nitrous URL into a script tag does indeed work to load the livereload.js script, and after today’s Ember CLI update the CSP module isn’t a problem anymore since its in report only mode by default.

The problem then becomes my Live Reload Chrome Extension is stuck on ‘Connecting’. After adding some breakpoints in the livereload.js script at some connection logic like say, line 143

this._uri = "ws" + (this.options.https ? "s" : "") + "://" + this.options.host + ":" + this.options.port + "/livereload";

I can see that this.options.port is correctly the value I set via the --live-reload-port option, but this.options.host is localhost. If I edit the this.options.host value to my correct Nitrous host the extension connects and Live Reload works as expected finally.

So even if I manually (or dynamically as suggested above) add the correct script tag to the index.html file, the livereload.js script defaults to pointing to localhost for its WebSocket connection.

I think nothing will help me short of a --live-reload-host option for ember serve since it seems livereload.js accepts that option. Am I correct in that assumption?


#8

Have you tried disabling the extension? It is not necessary in order to use livereload. In fact, the pure js solution is best if you intend to develop on devices (method 1).


#9

Yes, same deal with the Chrome Extension disabled. The issue is the livereload.js script that Ember CLI serves sends “localhost” as the host in the options hash. So even if the script itself is served from the right location, it attempts a WebSocket connection at the wrong location.

Here’s what I mean visually:

So in that instance I launched with ember serve --live-reload-port 4300.

Since I can get things working by simply changing “localhost” to the correct host from the Chrome debugger, the most intuitive solution seems there should be a --live-reload-host option for ember serve, but that doesn’t exist or anything that’d accomplish the same as far as I can tell.


#10

The host and port settings are extracted from the script element sourcing livereload:

Line 349 runs a regex check against the src attribute of all script elements until it finds livereload and then extracts further options from the regex match, so I can’t see how in your case the options object ends up with options.host='localhost'. Wouldn’t mind taking a look if you’d be willing to share the nitrous url.


#11

So the simple fix was just hardcode the correct script tag ahead of where Ember CLI’s generated tag would appear. Like:

<script src="http://dev.usw1-2.nitrousbox.com:4300/livereload.js?snipver=1" type="text/javascript"></script>
{{content-for 'head'}}

The reason why the correct livereload.js script tag has to be before the {{content-for 'head'}} generated tags is livereload.js iterates over every script tag on the page and finds the first that includes livereload.js, and from that found script tag it parses out host, port, and any other options added via query strings. The issue before with your solution nkgm was that it appended the correct livereload.js script tag to the bottom of the body tag, so Ember CLI’s livereload.js script tag was found first, parsed, and populated the option hash with the correct port but wrong host.

Hope that makes sense but basically my problem is fixed for now, but seems like having a --live-reload-host option to change what the `{{content-for ‘head’}}’ generates would’ve been a ton more intuitive a solution. If only I were competent enough for a pull request.

Thanks for the help.