Giter VIP home page Giter VIP logo

boot-reload's Introduction

boot-reload Downloads Build Status Dependencies Status

Clojars Project

Boot task to automatically reload resources in the browser when files in the project change. Communication with the client is via websockets.

  • Provides the reload task
  • Reload client can show warnings and exceptions heads-up display

Usage

Add dependency to build.boot and require the task:

(set-env! :dependencies '[[adzerk/boot-reload "X.Y.Z" :scope "test"]])

(require '[adzerk.boot-reload :refer [reload]])

Add the task to your development pipeline before (cljs ...):

(deftask dev []
  (comp
   (reload)
   (cljs)))

Additional Info

You can see the options available on the command line:

boot reload --help

or in the REPL:

boot.user=> (doc reload)

Examples

For in-depth, up-to-date examples of how to use reload in development, see Boot templates and example projects in the ClojureScript wiki.

License

Copyright © 2014 Adzerk
Copyright © 2015-2017 Juho Teperi

Distributed under the Eclipse Public License either version 1.0 or (at your option) any later version.

boot-reload's People

Contributors

alandipert avatar alesya-h avatar anmonteiro avatar arichiardi avatar bhagany avatar deraen avatar empperi avatar garrett-hopper avatar jobez avatar manicolosi avatar martinklepsch avatar matthewlal avatar micha avatar mitchelkuijpers avatar myguidingstar avatar pandeiro avatar pesterhazy avatar piranha avatar regularfellow avatar samroberton avatar schmir avatar skammer avatar svdm avatar tirkarthi avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

boot-reload's Issues

Boot-reload will try reloading non-reloadable files

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.

Generic way to pass messages to HUD

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.

Reloading of CSS fails with asset-path options

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.

Check for existence of DOM before using it

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.

Reconnect

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).

Reload from correct host

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:
screenshot 2015-12-17 14 40 11

I'll probably give this a go some time if someone already sees how this could be fixed, any pointers appreciated :)

Deprecations

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!

Evaluate using figwheel.client code

Pros:

  • community effort bundled in one project
  • dependency ordering + filtering of reloadable files would not need to be re-implemented

Cons:

  • potentially more complex to maintain (effort shared by more people though)
  • special cases for boot tooling might not be possible (e.g. displaying SASS compilation errors)
  • speed with which we could implement features/fixes might be reduced

Please discuss 😄

Changes of EDN files break compilation?

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

Reloading ClojureScript doesn't work for non-root browser path if asset-path is set

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

cljs build on cljs file change

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?

reload fails when changing css file

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"]

CSS not reloading

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))))

in use with tests

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)?

Empty hostname makes the url invalid

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.

Reloading mechanism uses relative paths

Though my first-load experience works fine, the reload mechanism attempts to load JS at relative URLs which fails. For instance:

  1. I go to localhost:3000/public/html/some-page.html
  2. I make a change to a CLJS file
  3. 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!

boot-reload requires Internet connection

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?

Feature request: wss support

People may debug code in HTTP/2 since ClojureScript is always lots of small files, which is naturally fixed in HTTP/2. And since HTTP/2 is based on HTTPS, so ws is no longer working and we need wss.

image

Make clearer the relationship with serve

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

adding new html includes without removing old ones

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>

goog.dom.constHtmlToNode is not a function

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.

shared webworkers incompatible with boot reload

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.

Unable to reload when using shared worker

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

Specify reload path for browser

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?

Asset-host with no / fails

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!

on reloading a transpile-to-Clojure language

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.

Warn when using with advanced optimisations

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?

non-shared web-worker return references window

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

Reload-css (and -img) does not consider asset-host?

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:

selection_008

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.

Different websocket addresses for different simultaneous platforms

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.

Tighten up file reloading

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.

Reloading ClojureScript doesn't work for non-root browser path if asset-path is set

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.

Only send messages when socket is open

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.

On-jsload is required because recompiled files are not being reloaded

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.

reload fails (on both safari and chrome with different errors)

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.

reloading main.js in unified mode

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.

Prepend :asset-path

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?

getting started?

I can't find any information about how to get this started. Please add a short how-to to the README.

TypeError: Cannot read property 'addCallbacks' of undefined

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.

  1. run boot dev
  2. open up index.html in a browser.
  3. change title.cljs

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.

Closure Compiler error under simple optimizations

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.

Allow to have a JS function called before reload

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.

reload and multiple builds

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. :)

Reload only a build's dependencies

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

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo 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.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.