adzerk-oss / boot-reload Goto Github PK
View Code? Open in Web Editor NEWBoot task providing live-reload of browser css, images, etc.
License: Eclipse Public License 1.0
Boot task providing live-reload of browser css, images, etc.
License: Eclipse Public License 1.0
I have a piece of cljc shared between frontend and backend. This piece doesn't seem to be recompiled/reloaded.
Any suggestions on how to patch this in?
When main.js
produced by boot-cljs
in unified mode is reloaded, Chrome emits following errors:
Failed to execute 'write' on 'Document': It isn't possible to write into a document from an asynchronously-loaded external script unless it is explicitly opened. main.js?zx=h93a6tbm99kb:2
Failed to execute 'write' on 'Document': It isn't possible to write into a document from an asynchronously-loaded external script unless it is explicitly opened. main.js?zx=h93a6tbm99kb:3
Failed to execute 'write' on 'Document': It isn't possible to write into a document from an asynchronously-loaded external script unless it is explicitly opened. main.js?zx=h93a6tbm99kb:4
I see two options here: somehow checking that it's the unified mode and basically hardcoding main.js
to be skipped, or rewriting main.js
in such a way that it's idempotent. Wasn't sure where to open this issue, but it's related to reloading, so I guess it's ok to discuss it here.
We use clojurescript and boot with Rails as a backend.
The problem with default boot-reload setup is that Rails (Sprockets actually) serves its assets as "/assets/something.js". The prefix path itself could be changed, but it is required to avoid confilct with the other routes.
The following setup
(deftask dev
"Watch/compile clojurescript files in development"
[]
(comp
(watch)
(speak)
(reload :on-jsload 'hb.core/render-app)
(cljs-repl)
(cljs :compiler-options {:asset-path "/assets/main.out"})
(target :dir #{"lib/assets/cljs"})))
write files to "lib/assets/cljs", which is treated by Sprockets as static root path. Therefore, main.js is accessible at "/assets/main.js".
The :asset-path option of cljs fixes paths in main.js itself, so we have correct document.write('<script src="/assets/main.out/cljs_deps.js"></script>');
etc in it.
However, reload doesn't work, because it tries to load "/main.out/somewhere/something.js", while we need "/assets/main.out/somewhere/something.js".
Currently it could be hacked with :asset-host option as "localhost:8080/assets", however, this won't work reliably among all devs machines and CI.
Could we have :asset-path-fn, so it would be a dev responsibility to prepend or subtract prefix from current URL?
I have an issue with boot-reload when switching from default build (with implicit .cljs.edn file) to multiple builds configuration.
When reloading a file I receive an updated js file via jsloader, however, core.js is not received, instead TypeError: Cannot read property 'addCallbacks' of undefined
is raised.
I've managed to create a sample app to reproduce the issue: https://github.com/nashbridges/boot-reload-issue. In reality it is a Rails application, therefore the strange "lib/assets/cljs" path to compiled assets.
boot dev
For some reason boot-reload ignores :cljs-asset-path
in this configuration, thus jsloader tries to load title.js from a default path. However, the mentioned exception is still visible.
It looks like this function was added to Closure in release 20160619, relatively recently. The changelog for 0.4.11 makes no mention of the fact that you'd need to update the Closure library, and I'm not certain how to do this outside of updating ClojureScript itself. You might want to make a note that the new version requires a newer Closure lib, CLJS version, or revert to the previous method of updating the HUD.
This project reproduces the problem:
When I change a CSS file, I see the following error in the JS console (on Safari):
[Error] Load failed: Jsloader error (code #0): Error while loading script /out/orion/main.js?zx=2rrysh6jbfqe
(anonymous function) (reload.js, line 223)
fire_ (deferred.js, line 627)
updateResult_ (deferred.js, line 296)
errback (deferred.js, line 337)
base (base.js, line 1598)
errback (deferredlist.js, line 176)
handleCallback_ (deferredlist.js, line 160)
(anonymous function) ([native code], line 0)
fire_ (deferred.js, line 627)
updateResult_ (deferred.js, line 296)
errback (deferred.js, line 337)
onerror (jsloader.js, line 179)
The whole thing reloads again, but no subsequent changes reload CSS or produce the error.
Using:
[adzerk/boot-reload "0.2.0" :scope "provided"]
Some files, such as the main shim, the deps.js and such are non-reloadable. Boot-reload will still try reloading those if they change which happens when changing :require
on cljs.edn: boot-clj/boot-cljs#108
This usually causes follwing exception:
Failed to execute 'write' on 'Document': It isn't possible to write into a document from an asynchronously-loaded external script unless it is explicitly opened.
This would be fixed by using Figwheel client.
Pros:
Cons:
Please discuss 😄
I think this bit:
;; Thanks, lein-figwheel & lively!
(defn patch-goog-base! []
(set! (.-provide js/goog) (.-exportPath_ js/goog))
(set! (.-CLOSURE_IMPORT_SCRIPT (.-global js/goog)) (fn [file]
(when (.inHtmlDocument_ js/goog)
(jsloader/load file)))))
breaks with :advanced
and really it probably shouldn't be supported anyways.
patch-goog-base!
also changed in fighwheel a bit — maybe it's worth updating it in boot-reload
?
Disclaimer: first weekend trying to use boot, so forgive me if I'm asking an ignorant question.
I am using this boot project:
https://github.com/borkdude/lein2boot/
I have an http server (serve task) serving the files from the target directory.
My handler (animals.api/handler) serves files under the "public" directory.
When I change a clojurescript file, the browser tries to reload the file using "/public/" but then I get a 404. How do I get it to reload from "/" instead?
I have a slightly strange setup where I serve compiled JS at localhost:3333
and load it in an HTML file at localhost:3000
. On first load everything is correctly loaded from e.g.:
http://localhost:3333/app.out/goog/dom/browserfeature.js
but when a reload event is triggered the reload code tries to reload from port 3000:
http://localhost:3000/app.out/com/gridacy/aura/app.js?zx=7r56fmv4tbeo
Screenshot in case it's not clear what I meant:
I'll probably give this a go some time if someone already sees how this could be fixed, any pointers appreciated :)
the file for/bar.js with {:asset-path "/static/some.out"} should generate path like this: /static/some.out/for/bar.js
This means we'll need a sequential collection instead of a set to contain the changes.
When rendering he HUD and reloading CSS the ClojureScript code uses the DOM. While most projects certainly run in a browser context there is also React Native now which does not have a DOM.
To avoid runtime errors when using React Native any usage of the DOM should be done after checking if a DOM is available. Probably just (exists? js/document)
would be enough.
A non-shared web worker does not have a window. But when such a web worker returns, a reference to window is made when using boot-reload. Specifically, window.location.protocol is referenced.
Uncaught ReferenceError: window is not defined(anonymous function) @ worker.js:2556
goog.events.EventTarget.fireListeners @ worker.js:2037
goog.events.EventTarget.dispatchEventInternal_ @ worker.js:2039
goog.events.EventTarget.dispatchEvent @ worker.js:2034goog.net.WebSocket.onOpen_ @ worker.js:2350
When I update a source file, new includes are being added to the html without removing old ones, which I think is causing the new code to fail to run correctly:
<link href="/css/main.css" rel="stylesheet" type="text/css">
<script type="text/javascript" charset="UTF-8" src="/js/app.out/ui/views/campaign_detail.js?zx=2mv0nsa82fsc"></script>
<script type="text/javascript" charset="UTF-8" src="/js/app.out/ui/parse/routes.js?zx=152jvlqd1ell"></script>
<script type="text/javascript" charset="UTF-8" src="/js/app.out/ui/main.js?zx=2yvaq9m9xlra"></script>
<script type="text/javascript" charset="UTF-8" src="/js/app.out/ui/views/campaign_detail.js?zx=oq0sdtqyldgo"></script>
<script type="text/javascript" charset="UTF-8" src="/js/app.out/ui/main.js?zx=8tiljqdeee8i"></script>
<script type="text/javascript" charset="UTF-8" src="/js/app.out/ui/views/campaign_detail.js?zx=agdm71jxsatw"></script>
<script type="text/javascript" charset="UTF-8" src="/js/app.out/ui/main.js?zx=kjlzljkgdu9j"></script>
<script type="text/javascript" charset="UTF-8" src="/js/app.out/ui/views/campaign_detail.js?zx=76d2w5bv8jzx"></script>
<script type="text/javascript" charset="UTF-8" src="/js/app.out/ui/main.js?zx=q9lylen9qckv"></script>
</head>
I've managed to get this running of a quick projet.
Really cool stuff.
But i had to use the the serve task.
At first i've tried to use npm's http-server.
I'm pretty ok with this. But it will be much more nice is this relationship could be explicit.
At least on the readme.
Keep on the good work
Hello Deraen, this requires a bit more explanation, my website fetches css
files from another server, kind of simulating a CDN, so the href in the html looks like:
<link href="{{asset-endpoint}}/css/app.css" rel="stylesheet">
Where asset-endpoint
is dynamic.
The reload-css
function however, here sets something different. By doing some debugging I see that:
But I am still digging on the reason why the ownerNode
's href is localhost:3000
and not my localhost:8000
.
Maybe I need some guidance here or on Slack when you have some minutes.
As discovered in #2 sometimes files have not been reloaded even though they changed on disk. #4 has been an easy fix for this but isn't 100% exact. Imagine the following html:
<!doctype html>
<html>
<head>
<title>hi, world!</title>
<link rel="stylesheet" href="main.css" type="text/css">
<link rel="stylesheet" href="//some.cdn.com/framework/main.css" type="text/css">
</head>
<body>
<script type="text/javascript" src="js/app.js"></script>
</body>
</html>
Whenever main.css
changes all other stylesheets ending in main.css
will also be reloaded. It's probably not problematic in most cases but it'd be nice to get 100% exact reloading.
I'm trying to pinpoint the issue I'm having here, and was wondering if anyone has experience with something similar? I feel like the root of my problems is that boot-reload might be caching something that it ought not to be.
I'm running a cljs.test suite that serves up test.html
where my namespaces are loaded via the following:
<script>
function run_tests() {
load_namespaces() // hack that uses goog.require internals, but it works.
cljs.core.set_print_fn_BANG_(testPrintLn)
testing_util.runner.run()
}
function rerun_tests() {
run_tests()
}
window.addEventListener('load', run_tests);
</script>
And I'm using the boot hook for reloading as follows: (reload :on-jsload 'testing-util.runner/rerun)
. This simply invokes the following inside of my testing util:
(ns testing-util.runner
(:require [cljs.test :refer-macros [run-all-tests]]))
(enable-console-print!)
(defn ^:export run []
(run-all-tests #".*-test\z"))
(defn ^:export rerun
"Expose this function so boot-reload can invoke it in the context of
resources/test.html after a file has changed. Ultimately, the test.html
will simply invoke the run function above."
[]
(.rerun_tests js/window))
Now, here's the weird part. When I run the boot environment the first time, no tests are run. Even if I save a test file and see the reload message in a console.log
, no tests are run. It's not until I save my testing_util/runner.cljs
do I actually get any tests to run. Here is the reload message I get when saving the runner:
main.out/adzerk/boot_reload.cljs.cache.edn
main.out/testing_util/runner.js.map
main.out/testing_util/runner.cljs.cache.edn
main.out/testing_util/runner.js
After a safe of the runner, suddenly all my tests namespaced *-test
are run. Similarly, if I comment out a complete (deftest ...)
block, then save that file- the tests are run as if I didn't comment out the block at all.
The reload looks like:
main.out/some_tests/some_test.js.map
main.out/some_tests/some_test.cljs
main.out/some_tests/some_test.js
What's more confusing, though, is if I change a test to fail, then save the test file, it will fail as expected. So it seems like there are some namespaces being overwritten, but only some of the time, and I can't figure out the secret sauce. Is this aggressive caching that's causing the issue? Is it namespaces not being properly reloaded that need to (something to do with the run-all-tests
macro)?
I'm trying to do some dev work on the train (no WiFi) and I keep getting a websocket handshake error: unexpected response code 414.
No idea if a connection is actually required just I haven't changed anything since I ran the code earlier today. Any ideas?
It would be cool if there would be a way for other tasks to send messages to the HUD.
e.g. a SASS task might encounter an error during compilation that could be shown to the user.
Hello! I am using boot-reload
with a custom setup that has an external server for the assets therefore I specified asset-host
to be my http://localhost:8000
.
However, I get a big red error saying so:
reload.cljs?rel=1465762643152:51 Load failed: Jsloader error (code #0): Error while loading script http://localhost%3A8000/main.out/boot/cljs/main20000.js?zx=iq6caq3ogki8
Am I doing everything right?
I see the colon is encoded so that might be a misuse on my part or a bug.
Thank you Deraen as usual for you lib!
Converted https://github.com/MarcoPolo/servant-demo from lein to boot here: https://github.com/aatree/aademos/tree/master/servant-demo
Everything works when you use lein, but when you use boot you get an error:
Uncaught ReferenceError: window is not defined
clojure.string.includes_QMARK_=function(a,b){return goog.string.contains(a,b)};adzerk.boot_reload.reload={};adzerk.boot_reload.reload.page_uri=new goog.Uri(window.location.href);adzerk.boot_reload.reload.ends_with_QMARK_=function(a,b){return cljs.core.EQ.call(null,b,cljs.core.subs.call(null,a,cljs.core.count.call(null,a)-cljs.core.count.call(null,b)))};adzerk.boot_reload.reload.reload_page_BANG_=function(){return window.location.reload()};adzerk.boot_reload.reload.normalize_href_or_uri=function(a){a=new goog.Uri(a);return adzerk.boot_reload.reload.page_uri.resolve(a).getPath()};
The issue is that the same .js file is used for both the web page and the webworkers, which is what shared webworkers do.
The workaround is to comment reload out in boot.build.
Here's something interesting. I'm trying to get live reloading with the following build.boot:
(set-env!
:source-paths #{"src/cljs"}
:resource-paths #{"html"}
:dependencies '[[adzerk/boot-cljs "1.7.228-1"]
[pandeiro/boot-http "0.7.3"]
[adzerk/boot-reload "0.4.8"]
[org.clojure/clojurescript "1.9.76"]
[cljs-ajax "0.5.5"]
[reagent-utils "0.1.8"]
[reagent "0.6.0-rc"]
[reagent-forms "0.5.24"]])
(require '[adzerk.boot-cljs :refer [cljs]]
'[pandeiro.boot-http :refer [serve]]
'[adzerk.boot-reload :refer [reload]])
(deftask dev
"Fake a Figwheel"
[]
(comp
(serve :dir "target")
(watch)
(reload)
(cljs)
(target :dir #{"target"})))
However, live reloading fails. In Safari (most recent version on OS X), I get
WebSocket network error: The operation couldn’t be completed. Cannot allocate memory
followed by
Reload websocket connection closed.
On Chrome, by contrast, I get this:
websocket.js:283 Uncaught SyntaxError: Failed to construct 'WebSocket': The URL 'ws://:62480' is invalid.
In either case, however, live reloading fails.
With :recompile-dependents
option Cljs will recompile all files which depend on a changed namespace. This has a side-effect that when a file is changed, all files which depend on that file are rewritten by Cljs compiler. If all changed files were reloaded, the main namespace would be reloaded and probably it would automatically cause the application to be "restarted".
Boot-reload currently only reloads files which contents have changed: https://github.com/adzerk-oss/boot-reload/blob/master/src/adzerk/boot_reload.clj#L20
After removing the :hash
option files will be reloaded also when only the modification time has changed. Unfortunately this will cause boot-reload to also try to reload files which shouldn't be reloade, e.g. the Cljs shim.
I'm using a transpiler. Previously it was JSON but now I using EDN for better IR. But then I got errors. Do you have any idea of this error?
compile file: respo/render/expander.cljc.edn
compile file: respo/schema.cljs.edn
compile file: respo/updater/core.cljc.edn
compile file: respo/component/zero.cljc.edn
compile file: respo/render/make_dom.cljs.edn
Writing main.cljs.edn...
Compiling ClojureScript...
• main.js
Writing target dir(s)...
Elapsed time: 19.162 sec
compile file: respo/component/todolist.cljc.edn
Adding :require adzerk.boot-reload.init1194 to time.cljs.edn...
java.lang.IllegalArgumentException: Key must be integer
...
clojure.core/assoc/invokeStatic core.clj: 191
clojure.core/update-in/invokeStatic core.clj: 5950
clojure.core/update-in core.clj: 5939
...
adzerk.boot-reload/add-init!/invokeStatic boot_reload.clj: 75
adzerk.boot-reload/add-init! boot_reload.clj: 67
adzerk.boot-reload/eval378/fn/fn/fn boot_reload.clj: 136
cirru-sepal.core/eval763/fn/fn/fn core.clj: 55
boot.task.built-in/fn/fn/fn/fn/fn/fn built_in.clj: 264
boot.task.built-in/fn/fn/fn/fn/fn built_in.clj: 264
boot.task.built-in/fn/fn/fn/fn built_in.clj: 261
boot.core/run-tasks core.clj: 794
boot.core/boot/fn core.clj: 804
clojure.core/binding-conveyor-fn/fn core.clj: 1938
...
Elapsed time: 0.212 sec
Our project is setup to serve assets from /resources/public
. Task options is like this:
(task-options!
cljs {:compiler-options {:asset-path "/application.out"}}
reload {:asset-path "public" :on-jsload 'filemporium.client.core/on-reload})
When I'm at
http://localhost:3000/users/1/folder/1
on save it tries to reload url
http://localhost:3000/users/1/folder/application.out/filemporium/client/ui/profile_new.js
instead of
http://localhost:3000/application.out/filemporium/client/ui/profile_new.js
Currently adzerk.boot-reload.websocket/transmit
fires .send
unconditionally; checking that the socket is open with adzerk.boot-reload.websocket/open?
first would only send messages when the socket is actually open.
The use-case for this is when boot-reload is loaded in browser environments (e.g. headless browsers) that may not have full websocket support, for instance in testing. Since boot-cljs doesn't currently support multiple :optimizations :none
builds (and boot-reload would try to add itself to each .cljs.edn
spec anyway, as currently written), this change would facilitate doing both development and testing with a single build even if it includes boot-reload.
Hi,
When I use this task I'm getting:
temp-dir! was deprecated, please use tmp-dir! instead
tmppath was deprecated, please use tmp-path instead
Is this related to which version of boot i'm using?
Thank you!
My css files did not seem to reload so I did some debugging with the following code:
(defn- changed-href? [href-or-uri changed]
(when href-or-uri
(let [uri (goog.Uri. href-or-uri)
path (.getPath (.resolve page-uri uri))]
(.log js/console "path" path)
(.log js/console "changed" (.getPath (.resolve page-uri (goog.Uri. (first changed)))))
(.log js/console "ends-with?" (ends-with? path (first changed)))
(.log js/console "ends-with-original" (ends-with? (first changed) path))
(when (not-empty (filter #(ends-with? (.getPath (.resolve page-uri (goog.Uri. %))) path) changed))
uri))))
When I try to reload a css file it always fails because path gets normalized so css/main.css
will become /css/main.css
and the changes file does not have this /
before the path so ends-with? always fails. If you normalize it by doing .getPath this get's fixed. I could make a pull request but I am not sure this will break it for others.
When :ids
is specified, reload
should only send changed files to the browser that are a part of that build's dependency graph (or are non-JS assets such as CSS, etc). Otherwise compiled namespaces from any other builds will get loaded, resulting in uncaught exceptions:
goog.require could not find: foo.tests @ base.js:619 ...
base.js:662 Uncaught Error: goog.require could not find: foo.tests
I can't find any information about how to get this started. Please add a short how-to to the README.
When modifying Reagent components, I have to manually refresh the page to see the changes to the DOM. I am currently forcing the DOM re-render in the REPL with (reagent/force-update-all)
but I would love to have boot-reload take care of this.
I stumbled upon this conversation with the same issue, but I am not sure the solution of adding a reload hook: http://clojurians-log.mantike.pro/reagent/2016-01-22.html
We are running a cordova application that targets browser, ios and android.
The default reload address ws:localhost:..
works wonder with the browser and the ios simulator, allowing us to push the changes to both simultaneously.
However the Android emulator remaps localhost
to 10.0.2.2
. I can change my build.boot
to use (reload :ws-host "10.0.2.2")
, but this way we cannot develop with a single reloaded workflow on all three platform simultaneously.
Our ultimate dream is: having the three platform screens side by side and see our changes propagate to all of them in realtime ⭐ I wonder if boot has a way to accomplish this with.
In electron, window.location.hostname seems to return an empty string instead of "localhost". It would be nice if resolve-url could default to "localhost" in this case, instead of returning an invalid url.
Sample code checked in here: https://github.com/aatree/aademos/tree/master/servant-demo
The web page loads and runs just fine. But when the source is updated, an error occurs on the server.
Running with (serve :port 9000 :init-params {"org.eclipse.jetty.servlet.Default.useFileMappedBuffer" "false"}) resulted in java.nio.file.AccessDeniedException.
Running with (serve :port 9000) resulted in the less interesting can't delete I-O exception.
So here is the result with useFileMappedBuffer set to false:
C:\Users\Bill\Documents\aatree\aademos\servant-demo>boot dev
Starting reload server on ws://localhost:62979
Writing boot_reload.cljs...
Writing boot_cljs_repl.cljs...
Starting file watcher (CTRL-C to quit)...
nREPL server started on port 62980 on host 127.0.0.1 - nrepl://127.0.0.1:62980
Writing main.cljs.edn...
Compiling ClojureScript...
ò main.js
Starting Jetty on port 9000...
2016-02-02 11:14:48.093:INFO::clojure-agent-send-off-pool-0: Logging initialized @30748ms
2016-02-02 11:14:48.151:INFO:oejs.Server:clojure-agent-send-off-pool-0: jetty-9.3.1.v20150714
2016-02-02 11:14:48.250:INFO:oejw.StandardDescriptorProcessor:clojure-agent-send-off-pool-0: NO JSP Support for /, did not find org.eclipse.jetty.jsp.JettyJspServlet
2016-02-02 11:14:48.277:INFO:oejsh.ContextHandler:clojure-agent-send-off-pool-0: Started o.e.j.w.WebAppContext@544365d5{/,file:///C:/Users/Bill/.boot/cache/tmp/Users/Bill/Documents/aatree/aademos/servant-demo/4hw/s0070k/,AVAILABLE}
2016-02-02 11:14:48.292:INFO:oejs.ServerConnector:clojure-agent-send-off-pool-0: Started ServerConnector@2a75f2b8{HTTP/1.1,[http/1.1]}{0.0.0.0:9000}
2016-02-02 11:14:48.297:INFO:oejs.Server:clojure-agent-send-off-pool-0: Started @30952ms
Implicit target dir is deprecated, please use the target task instead.
Set BOOT_EMIT_TARGET=no to disable implicit target dir.
Elapsed time: 27.237 sec
Writing main.cljs.edn...
Compiling ClojureScript...
ò main.js
java.util.concurrent.ExecutionException: java.nio.file.AccessDeniedException: target\main.out\servant_demo\core.js
java.nio.file.AccessDeniedException: target\main.out\servant_demo\core.js
file: "target\main.out\servant_demo\core.js"
sun.nio.fs.WindowsException.translateToIOException
sun.nio.fs.WindowsException.rethrowAsIOException
sun.nio.fs.WindowsException.rethrowAsIOException
sun.nio.fs.WindowsFileCopy.copy
sun.nio.fs.WindowsFileSystemProvider.copy
...
boot.filesystem/copy! filesystem.clj: 51
boot.filesystem/patch! filesystem.clj: 82
...
clojure.core/apply/invokeStatic core.clj: 652
clojure.core/partial/fn core.clj: 2534
...
boot.core/fileset-syncer/fn/iter/fn/fn/fn core.clj: 777
clojure.core/binding-conveyor-fn/fn core.clj: 1938
...
Elapsed time: 5.867 sec
It looks like the file path being sent to the client is relative to the target directory. The client then checks to see if the file path sent is within any hrefs on the page, which are usually relative to the page. Ex: "/public/css/navigation.css" is being sent to the client and "css/navigation.css" is an href on the page. Those two will never match, and css won't reload.
(defn- changed-href? [href-or-uri changed]
(when href-or-uri
(let [uri (goog.Uri. href-or-uri)]
(when (contains? changed (.getPath (.resolve page-uri uri)))
uri))))
boot_reload/display.js:155: ERROR - Function argument is a variable logo which is not a constant assigned from a string literal
return goog.dom.constHtmlToNode(goog.string.Const.from(logo));
this happens because you're passing a variable to goog.dom.Const.from
. The Closure compiler must ensure it is a constant at compile time.
For example, components dependend on each other like this:
container -> sidebar -> group-line
As I edit group-line
, what is supposed to happen?
I tried and put some results on Twitter https://twitter.com/jiyinyiyong/status/744196209259094016 Actually I got confused.
Hi.
My setup is the following: css files and application.cljs.edn
are stored in /resources/public
, :asset-path
for cljs
task is set to "/application.out"
, :asset-path
for reload is set to "public"
. The issue is that when I'm on non-root route of my application (e.g. /users/1
), it tries to reload application.out/.../file.js
(without leading slash), effectively reloading /users/application.out/.../file.js
, which obviously does not exist on the server.
I heard it's deleted: http://stackoverflow.com/questions/12318667/closure-library-dom-node-from-html-text#comment63223933_12323597
I'm running latest ClojureScript, 1.9.76
, there was a Google Closure Compiler update https://github.com/clojure/clojurescript/blob/master/changes.md#changes .
Tried 1.9.36
and it is fine.
I have two cljs files being built at same time - one for client part of application, and another for server part. And application just doesn't start when boot-reload is used, failing on call to window
:
adzerk.boot_reload.reload.page_uri = (new goog.Uri(window.location.href));
^
ReferenceError: window is not defined
Some mechanism of skipping some builds is desirable. :)
The JS function specified by on-jsload
is called right after the code is reloaded. It would be useful to have a similar handle allowing to define a JS function called right before the code is reloaded, in the previous context.
A concrete use-case is to be able to close
AudioContext. AudioContext
leak system resources if not properly closed. After a couple of reload (6 with current chrome) you can't create new AudioContext
if they have not been closed.
The easy part is adding reload logic to Websocket client.
File reloading needs some changes so that it won't break when tries to reload all files (after reconnect).
I'm new to the clojure thing so boot is quite a challenge in understanding. does boot-reload try to recompile the cljs files to js when the file changes?
Though my first-load experience works fine, the reload mechanism attempts to load JS at relative URLs which fails. For instance:
localhost:3000/public/html/some-page.html
boot-reload
makes a request to localhost:3000/public/html/public/js/something.js
I tried all combinations of asset-host
and cljs-asset-path
in an attempt to resolve this, but mostly they caused more problems than they solved (for instance, cljs-asset-path
without asset-host
set makes requests to http://public/js/something.js
).
Ultimately, I ended up making the following changes in reload.cljs
:
(defn- absolute? [uri]
(or (not (string/blank? (.getDomain uri))) (.startsWith (.getPath uri) "/")))
(defn- maybe-make-absolute [uri]
(if-not (absolute? uri)
(.setPath uri (str "/" (.getPath uri)))
uri))
(defn- reload-js [changed {:keys [on-jsload]
:or {on-jsload identity}}]
(let [js-files (filter #(ends-with? % ".js") changed)]
(when (seq js-files)
(-> #(-> % guri/parse .makeUnique maybe-make-absolute)
;; ...
))))
Offhand I'm not sure why relative path reloads would ever be desirable but I'm no expert on all the use cases of boot-reload
so I don't know if this is a valid change for you to make. It worked well for me, though!
Maybe this topic is beyond boot-reload but I want to ask about the possibility of making it to do so. It's common pattern in JavaScript that people write in another syntax and compile it to JavaScript. And I'm doing this on Clojure, and perhaps the only one currently. I mean I will compile my code in .cirru
files into ClojureScript and then ClojureScript will be compiled to JavaScript.
Perviously I was using a lein plugin that compiling code from cirru-src/
to src/
and the file change event triggers another process called lein figwheel...
I was lucky. Now I'm trying to use boot with boot-reload.
As I read code of boot-reload, I think it's getting all ClojureScript files and check prev
fileset to find out changed files, and notify the browser. Now I want to add my boot task to compile .cirru
file into .cljs
before boot-reload is handling that. I want to ask if that's possible my boot talk to work correctly with boot-reload? Very tricky though. Thanks.
A declarative, efficient, and flexible JavaScript library for building user interfaces.
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
An Open Source Machine Learning Framework for Everyone
The Web framework for perfectionists with deadlines.
A PHP framework for web artisans
Bring data to life with SVG, Canvas and HTML. 📊📈🎉
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
Some thing interesting about web. New door for the world.
A server is a program made to process requests and deliver data to clients.
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
Some thing interesting about visualization, use data art
Some thing interesting about game, make everyone happy.
We are working to build community through open source technology. NB: members must have two-factor auth.
Open source projects and samples from Microsoft.
Google ❤️ Open Source for everyone.
Alibaba Open Source for everyone
Data-Driven Documents codes.
China tencent open source team.