Comments (9)
For now, you can use a hack like this:
<script>
window.WebSocket = class HackWebSocket extends WebSocket {
constructor(urlParam) {
const url = new URL(urlParam);
if (looksLikeElmWatch(url)) {
url.port = "1234";
}
super(url);
}
}
function looksLikeElmWatch(url) {
return url.port === "4321";
// or return url.pathname === "/elm-watch";
}
</script>
This works great - thanks for the tip!
Ok, one more question: If I were to add cert configuration to elm-watch.json, would it look something like this for you then?
{
"sslCertificate": {
"cert": "./ssl/le-certs/foo.crt",
"key": "./ssl/le-certs/foo.key"
},
"targets": {}
}
Yes, this would be perfect.
So far, I’ve only found HAProxy that concatenates them. And even in that case, couldn’t you “just” keep three files on disk?
In fact HAProxy doesn't concatenate them - it just expects all the files in the same folder.
from elm-watch.
Hi again!
I’m missing something – if you’re running everything on your laptop, why can’t you use like any random port for elm-watch then? Why does it need to be behind the proxy?
from elm-watch.
Hi - thanks for responding so quickly!
I didn't try using a random port before as I wanted to avoid the self-signed certificate as I already had a valid certificate for the domain which is handled by `haproxy and does the SSL handoff.
However, I have now tried with a random port and this work on Firefox after accepting the self-signed cert from elm-watch
.
However, it does not work in Chrome (which is my preferred browser for development) even after accepting the self-signed cert. I think this is because Chrome only accepts the certificate for the current page, and going to a different URL on the same domain or even just refreshing the page requires re-accepting the self-signed cert every time.
I just keep getting logs like this in the browser console:
elm.js:988 WebSocket connection to 'wss://foo.bar.com:53853/elm-watch?elmWatchVersion=1.1.0&targetName=Foo&elmCompiledTimestamp=1667594645328' failed:
The Chrome version is 107.0.5304.87 on an M1 Mac.
from elm-watch.
Oh, you don’t use localhost? I only tested Chrome (and other browsers) with localhost. Good to know. Edit: I added 127.0.0.1 foo.bar.com
to /etc/hosts
(on macOS) and went to https://foo.bar.com:8001/
in Chrome, and went through the self-signed certificate stuff. elm-watch then connected as expected. I used the example to test it. So I’m not sure why it didn’t work for you?
Do you have to files on your computer – like a .key
and a .crt
– for haproxy? I’ve been waiting for someone with this setup to see if an idea I’ve had makes sense. I have been thinking of adding configuration in elm-watch.json that lets you point out those two files so elm-watch can use the same certificate for its SSL stuff. Does that make sense?
Finally, I’m curious why you are running HTTPS locally. We used to do that at work, because we thought it was good to have the local environment be as similar as possible as the production environment. However, we noticed that the HTTPS part never caught any bugs or anything for us, so we tried switching to HTTP and everything got simpler (save for having to conditionally set the Secure
flag of two session cookies).
from elm-watch.
I'll test the example later to see if this works for me.
However, to answer your other questions:
Do you have to files on your computer – like a .key and a .crt – for haproxy?
Yes, I have the Let's Encrypt .key
and .crt
files in a ssl/le-certs
folder on my laptop that is referenced by haproxy. Similar to what you tried, I also set the domain to point to 127.0.0.1
in /etc/hosts
It's a pretty simple haproxy setup - something like:
frontend https-in
bind *:443 ssl crt ssl/le-certs
# I would like to use the following line, but would
# need the to configure elm-watch server to run on port 4001
# use_backend elm-watch if { path_reg ^/elm-watch }
use_backend phoenix if { path_reg ^/ }
backend phoenix
server node1 0.0.0.0:4000
# backend elm-watch
# server node 1 0.0.0.0:4001
I have been thinking of adding configuration in elm-watch.json that lets you point out those two files so elm-watch can use the same certificate for its SSL stuff. Does that make sense?
I'm not sure. I know that you do support SSL hand-off in elm-watch currently, but do you think it is necessary? As you say in "What elm-watch is not", it is "not a file server" and "Let elm-watch excel at compiling Elm quickly and reliably, and own the rest of the stack yourself."
If a user is using HTTPS for development they will need to have the file server/web server that they use for the non-Elm stuff do SSL hand off anyway, so maybe it's simpler to just let them do this in one place with a proxy like nginx or haproxy. (Although of course to do this, you need to be able to configure elm-watch
to run on port 443
in the client and a different port on the server :) )
Although haproxy lets you put all your .key
and .crt
files in the same folder, I expect different web servers/proxies rely on different setups, e.g. putting the files in different folders, joining the files, or using .pem
files instead. With Let's Encrypt certs you need to renew them frequently, so a user will need to regularly update the files in the correct format and location for their own web server/proxy and elm-watch (although of course they could script this).
I’m curious why you are running HTTPS locally
I have found that browser features increasingly only work with HTTPS and so this is the only option for testing in a development environment. These include:
- Copy to clipboard (using
navigator.clipboard
) - Service workers
- Push notifications
I have also read that Chrome (although I cannot find the original source of the story from Google :( ) will eventually stop supporting HTTP completely (although I suppose for localhost
it will always be allowed). I suspect that sites with self-signed certs will also not be supported in the future - so you won't be able to click the "Advanced" button and agree to continue. I think this is already the case for real certs that have expired, which up to a few months ago, allowed you to still click the "Advanced" button.
In my use case I cannot use localhost
(even if I wasn't testing the browser HTTPS only features) as I have a couple of microsites running on different domains with a single sign on between them.
from elm-watch.
If a user is using HTTPS for development they will need to have the file server/web server that they use for the non-Elm stuff do SSL hand off anyway, so maybe it's simpler to just let them do this in one place with a proxy like nginx or haproxy.
Yeah, I’m not sure what’s simpler either. elm-watch currently contains a hardcoded certificate, so being able to point out two files is not far from what we have today. And that might be easier to do for end users than proxying? Supporting different ports for backend and frontend also sounds easy (I think), but from my experience with Docker it’s easy to confuse oneself with port mappings (which port is used where).
I have found that browser features increasingly only work with HTTPS and so this is the only option for testing in a development environment.
FYI: As far as I understand, http://localhost
is an exception. I know for sure that clipboard and service workers work there, but I haven’t tested push notifications.
Either way, I’m not sure which path I want to take here and don’t feel like thinking more about it right now, so I’m going to let this one sit for a while. Maybe some other HTTPS-locally user pops up and gives more insight.
For now, you can use a hack like this:
<script>
window.WebSocket = class HackWebSocket extends WebSocket {
constructor(urlParam) {
const url = new URL(urlParam);
if (looksLikeElmWatch(url)) {
url.port = "1234";
}
super(url);
}
}
function looksLikeElmWatch(url) {
return url.port === "4321";
// or return url.pathname === "/elm-watch";
}
</script>
from elm-watch.
Ok, one more question: If I were to add cert configuration to elm-watch.json, would it look something like this for you then?
{
"sslCertificate": {
"cert": "./ssl/le-certs/foo.crt",
"key": "./ssl/le-certs/foo.key"
},
"targets": {}
}
In other words, the paths are relative to the elm-watch.json file, and should work for any contributor, not just on your machine. (Config in elm-watch.json should be correct for everyone; things that differ for different contributors go in environment variables (ELM_WATCH_OPEN_EDITOR
) or can be changed via the browser UI (compilation mode, UI position, error overlay).)
I checked Node.js, Go, Ruby, Python, nginx, Apache, and they all take two files as input. So far, I’ve only found HAProxy that concatenates them. And even in that case, couldn’t you “just” keep three files on disk?
from elm-watch.
Just some extra info for anyone else using a setup with HAProxy: To prevent elm-watch
from frequently reloading, you will need to add something like this to your HAProxy config in the backend
section for elm-watch
timeout tunnel 1h
from elm-watch.
The current plan is to solve this via #74
from elm-watch.
Related Issues (20)
- elm-watch beta: CLI gives https:// links by default in Bun HOT 6
- Running 'example-minimal' in devcontainer wsl2 - not picking up changes to *.elm HOT 2
- Runtime error after build with --optimize HOT 10
- Getting the error `Error: spawn Unknown system error -8` when using Node 18 HOT 9
- Allow overriding the output file for a target HOT 6
- Allow building a file with the hot-reload code inserted HOT 1
- File changes made don't trigger hot reload - WSL2
- RFC: Overhaul HTTPS support HOT 13
- how would you use elm-optimize-level-2 with elm-watch? HOT 2
- Command line is too long error HOT 1
- dynamically specifying output location HOT 6
- using a known hostname but dynamic port HOT 8
- Add output to postprocess arguments HOT 2
- Permission denied when running as root HOT 2
- elm-watch hangs on error HOT 6
- watching through symlinks HOT 1
- elm-watch hangs on error in dependency stage HOT 5
- The port showing as "0" (http://localhost:0) in the terminal when elm-watch is concatenated with the "cat" command
- errors display below <dialog>s HOT 3
- Broken link in the docs
Recommend Projects
-
React
A declarative, efficient, and flexible JavaScript library for building user interfaces.
-
Vue.js
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
-
Typescript
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
-
TensorFlow
An Open Source Machine Learning Framework for Everyone
-
Django
The Web framework for perfectionists with deadlines.
-
Laravel
A PHP framework for web artisans
-
D3
Bring data to life with SVG, Canvas and HTML. 📊📈🎉
-
Recommend Topics
-
javascript
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
-
web
Some thing interesting about web. New door for the world.
-
server
A server is a program made to process requests and deliver data to clients.
-
Machine learning
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
-
Visualization
Some thing interesting about visualization, use data art
-
Game
Some thing interesting about game, make everyone happy.
Recommend Org
-
Facebook
We are working to build community through open source technology. NB: members must have two-factor auth.
-
Microsoft
Open source projects and samples from Microsoft.
-
Google
Google ❤️ Open Source for everyone.
-
Alibaba
Alibaba Open Source for everyone
-
D3
Data-Driven Documents codes.
-
Tencent
China tencent open source team.
from elm-watch.