Skip to content

Instantly share code, notes, and snippets.

David Nolen swannodette

Block or report user

Report or block swannodette

Hide content and notifications from this user.

Learn more about blocking users

Contact Support about this user’s behavior.

Learn more about reporting abuse

Report abuse
View GitHub Profile
swannodette /
Last active Jul 5, 2019
Transitive Foreign Dependencies

ClojureScript Support for Foreign Libraries via NPM

Problem Description

The current Webpack solution works reasonable well for application oriented development, but does not address the wider issue of developing ClojureScript libraries that depend on the wider JavaScript ecosystem where the artifacts do not reside in Java-centric distrubtion like Maven (i.e. NPM). Currently a ClojureScript library cannot express these kinds of foreign library dependencies at all. Thus users must constantly redefine basic dependencies from NPM such as React, boilerplate Webpack configuration, boilerplate import/export files, and thus cannot create and share reusable ClojureScript components that depend on this vast ecosystem.

ClojureScript actually has nearly all of the pieces to solve this problem today due to prior work around :npm-deps, as well as :foreign-libs changes to support community distribution efforts like CLJSJS.


swannodette /
Created Apr 2, 2019 — forked from kisielk/
Linnstrument + Supercollider
var notes, synths, on, off, mod, bend, touch;
~num_channels = 8;
~bend_range = 24;
notes = Array.newClear(~num_channels);
synths = Array.newClear(~num_channels);
View twister-example.scd
// Twister devices are expected to be named in this form:
// classvar <endpointDevice="Midi Fighter Twister %", <endpointName="Midi Fighter Twister";
// Where "Midi Fighter Twister 1" is TwisterDevice(\default) and "Midi Fighter Twister 2" is TwisterDevice(\secondary)
// A twister device. These are singletons - there is only ever one registered per device. It works ala Ndef, Pdef, etc, see Singleton help file.
~device = TwisterDevice(\default);
// If your MIDI Fighter is named something other than the above, you can register it via:
this.registerDevice(\myDevice, "endpoint device", "endpoint name");
// And then access it via TwisterDevice(\myDevice)
DummyMIDI {
var dummy = 0;
*new {
noteOn {}
noteOff {}
control {}
swannodette / core.cljs
Last active Jul 13, 2018
Figwheel :paths bug
View core.cljs
;; src/cljs/hello_world/core.cljs
(ns hello-world.core)
(println "Hello, world!")
View deps.edn

Code Splitting

NOTE: This gist uses the master branch of ClojureScript. Clone ClojureScript and from the checkout run ./script/bootstrap and ./script/uberjar. This will produce target/cljs.jar which you can use to follow this guide.

As client applications become larger it becomes desirable to load only the code actually required to run a particular logical screen. Previously ClojureScript :modules compiler option permitted such code splitting, but this feature only worked under :advanced compilation and users would still have to manage loading these splits. :modules also required manual

View test.cljs
(ns async-test.core
(:require-macros [cljs.core.async.macros :as async])
(:require [cljs.core.async :as async]))
(defn looper [ch handler-fn]
(async/go-loop []
(handler-fn (async/<! ch))
swannodette /
Last active Nov 28, 2019
Externs Inference

Externs Inference

Integrating third party JavaScript libraries not written with Google Closure Compiler in mind continues to both be a source of error for users when going to production, and significant vigilance and effort for the the broader community (CLJSJS libraries must provide up-to-date and accurate externs).

In truth writing externs is far simpler than most users imagine. You only need externs for the parts of the library you actually intend to use from ClojureScript. However this isn't so easy to determine from Closure's own documentation. Still in the process of writing your code it's easy to miss a case. In production you will see the much dreaded error that some mangled name does not exist. Fortunately it's possible to enable some compiler flags :pretty-print true :pseudo-names true to generate an advanced build with human readable names. However debugging missing externs means compiling your production build for each missed case. So much time wasted for such simple mistakes damages our sen

View figwheel_client_socket_repl.clj
(require 'tubular.core)
(tubular.core/connect "" REPL_PORT)
You can’t perform that action at this time.