This page is not created by, affiliated with, or supported by Slack Technologies, Inc.
2018-02-28
Channels
- # beginners (226)
- # boot (18)
- # bristol-clojurians (4)
- # cider (1)
- # clara (77)
- # cljs-dev (79)
- # cljsjs (27)
- # clojure (178)
- # clojure-austin (9)
- # clojure-dev (30)
- # clojure-gamedev (11)
- # clojure-italy (5)
- # clojure-losangeles (3)
- # clojure-poland (1)
- # clojure-spec (42)
- # clojure-uk (34)
- # clojurescript (182)
- # core-async (5)
- # core-logic (2)
- # cursive (17)
- # datascript (12)
- # datomic (33)
- # emacs (8)
- # figwheel (1)
- # fulcro (25)
- # jobs (6)
- # jobs-discuss (27)
- # lein-figwheel (1)
- # lumo (18)
- # off-topic (17)
- # onyx (5)
- # pedestal (7)
- # re-frame (30)
- # reagent (52)
- # remote-jobs (1)
- # ring (2)
- # ring-swagger (1)
- # shadow-cljs (40)
- # spacemacs (5)
- # sql (31)
- # unrepl (12)
- # vim (25)
Does anyone know a way to alias a namespace without requiring it in cljs? E.g. (alias 'a 'some.long.thing)
I want the alias, but I don’t want the require (the alias is for convenience, and a require will create a loop)
tony.kay you can do it by using an empty ns form - I've seen it done at least - there may be unexpected consequences there though
that is, create the ns with an empty ns form and then alias it
but :as uses alias (or it does in clj...)
adds this to his "reasons cljs is a bit odd" list
ns is a special form. On the JVM a Namespace is an instance of a class that is essentially a map-like thing. In cljs, I htink it is just an internal construct used during compile.
@tony.kay I don't think you can. We hit this problem before and had to ditch a use of alias
in this code so that it could be processed by ClojureScript, and at the time I recall there being no good way to do it https://github.com/clojure/clojurescript/commit/8477f19dcf67a8f305b46f2fd2e793586e027263
@dpsutton I use namespaced symbols on multimethod dispatch, but the multimethods sometimes need to access the code where they’re also used, creating a require loop…but the dispatch just uses the symbol as data, so being albe to alias would save some typing.
Having said that, it makes me wonder if alias
couldn't be made to work in ClojureScript (at least if constrained in a static way)
You can do it in self-hosted ClojureScript
cljs.user=> (defn alias
#_=> [alias namespace-sym]
#_=> (swap! cljs.env/*compiler* update-in
#_=> [:cljs.analyzer/namespaces (.-name *ns*) :requires]
#_=> assoc alias namespace-sym)
#_=> nil)
#'cljs.user/alias
cljs.user=> (alias 'cs 'clojure.string)
nil
cljs.user=> ::cs/foo
:clojure.string/foo
cljs.user=> (var cs/reverse)
#'clojure.string/reverse
Perhaps something similar could work in the JVM analyzer (it might even need to be a special form).seems like it could, but feels a bit hacky unless it were in the ns form, and that thing is already such a mess
Perhaps the reason alias
doesn’t exist is due to lack of runtime reification of namespaces, etc., but ultimately we ended up with a limited form of the var
special form in ClojureScript, albeit with some static restriction—perhaps the same could happen for alias
, but there probably just hasn’t been enough people asking for it, given that the times you could use it are extremely rare.
Two CLJS versions were pushed out yesterday, with no changes to the change log and no announcement. Anyone have info on what they contain?
I pinged @dnolen on IRC earlier, but didn't hear anything back. Versions 1.10.63
and 1.10.64
.
Hi, what's the most straightforward way to load my cljs namespaces in a repl? I've been trying to get cljs-bootstrap (https://github.com/swannodette/cljs-bootstrap) going but I hit some opaque errors. This doc (https://clojurescript.org/reference/repl) makes the browser version look easy I couldn't find a clear answer on how to get the cljsc compiler working. Any suggestions?
Hi! I’m trying to use npm modules directly in ClojureScript.
For this, I ran yarn add @cljs-oss/module-deps apollo-client
in a new directory.
I then created a file src/foo.cljs
with the following content: (ns foo (:require apollo-client))
.
I’m starting it with clj -Sdeps '{:deps {org.clojure/clojurescript {:mvn/version "1.10.64"}}}' -m cljs.main -r
, then in the repl, I evaluate (require 'foo :reload)
.
The result is a stacktrace that begins with java.lang.IllegalArgumentException: /Users/jannis/node_modules/graphql/language/printer.js is not a relative path
. I’m happy to dive deeper and find a solution. But I wanted to check first: is this a known issue?
I don’t know how npm modules are loaded yet but I suspect it comes from this:
./node_modules/apollo-client/index.js:export { print as printAST } from 'graphql/language/printer';
@jannis I'd also be interested in hearing about how to setup externs, it's my task for today 🙂
@benzap People might shout at my but yeah, they are pretty much the same tool in that they both manage npm dependencies in your project and can run your package.json
commands etc.
yeah, I assumed that yarn has the benefit of being a bit faster, but they still pull from npm dependencies, right?
@benzap yarn adds some extra functionality on top of npm, it was developed in order to resolve some of npm's shortcomings. Think of Yarn as an improved installer that still relies upon the same npm structure.
A major problem with npm is that it automatically runs code from dependencies and permits packages to be added on the fly. But since Yarn only installs from your yarn.lock or package.json files it’s more secure, it also makes use of checksums before installation to ensure the integrity of each package. And although I'm not a big fan of Facebook, they're one of the largest software companies in the world... so bugs usually get fixed very quickly.
Oh that's interesting, I never knew it was created by facebook, i'm a big fan of react
So one difference i'm noticing, it appears that the clojurescript compiler allows you to include dependencies right in the compiler options under the option :npm-deps
I just started setting up yarn, so i'm not familiar with how this affects external inference when compared to managing the node_modules yourself
@benzap I’m working on something similar. I’m struggling with 2 different react components, and it seems each will require a different import procedure. Does that make any sense?
Is there an easy way to have cljsbuild swap an atom variable when as i compile? I'd like to have two different builds of my app and the only difference is :admin in my state atom is true/false
@jlindeberg88 you can use goog-define
together with :closure-defines
. it seems a little insecure to do this though as a savvy user might just flip the setting and become an admin?
Thanks I'll look into that! That shouldn't matter since the non admin-version is for users with no privileges to access any of the backend structure
Interesting, I tried https://github.com/clojure/clojurescript/tree/master/samples/string-requires-npm-deps without :target :nodejs
(swapping out react-dom/server
for react-dom
). It didn’t work out of the box (`goog.require` failed to resolve react
and react_dom
) but once I added those two names to the right goog.addDependency
calls in out/cljs_deps.js
it worked! I wonder how we can make this work out of the box?
It seems different tweaks are needed for different packages.
1. react
and react_dom
needed to be added to the provides section of the dev bundle addDependencies
manually
2. graphql
didn’t show up in cljs_deps.js
in the first place; changing it to point to index.js
instead of index.mjs
in its package.json
"module"
field fixed that but there are still references to mjs
files in cljs_deps.js
that can’t be resolved.
@jeaye yeah no announce for now, cut some releases so users could do some testing of the new cljs.main
feature. We’re close, but some finesse things to do - there will be a changelog, proper announce soon
@jannis, i'm attempting to use lein-cljsbuild with similar arguments, i'll let you know how it plays out
I can't seem to find an article which was an example of using npm dependencies with lein, it also used the new require functionality to pull in dependencies as strings (to get around issues with naming)
This was a few months ago, so I wonder if maybe they removed that functionality, and they're going a different direction
@dnolen Hey David, sorry to ping you directly. I’m wondering how far the latest CLJS release (1.10.64) is from being able to include “arbitrary” npm packages in browser-targeting builds. I’ve spent the last couple of days trying to package Apollo for cljsjs, which required build changes to almost all JS libraries involved (…), so I’m eager to understand how far we are from not having to go through that anymore—and what I can do to help. 🙂
however I’m thinking about a couple of debug tools + some documentation to help people more easily contribute to ClojureScript / Closure Compiler
@dnolen It must be super complex to be able to pull packages in, given how different they are. Documentation what the current baseline of support is would be great (to set expectations for instance; I currently don’t understand what is possible and what isn’t).
I find it incredibly confusing starting out, i'm guessing it's one of those things that becomes simple once you get it working once
Almost all issues that aren’t Closure are issues with indexing, could be easier to debug
Using the new release and the cljs
build API, it seems a bunch of problems simply arise from dependencies not being inserted correctly into cljs_deps.js
. Is this what you mean?
typical bug https://github.com/clojure/clojurescript/commit/4003d238e2cf27c7e73be7e62f1a12d80b003a8a
@pesterhazy That did the trick! Accessing (.-default foo)
How can I determine which libraries need that approach? And is using webpack and :foreign-libs the best way to do that?
@dnolen Got it. If I wanted to debug how the packages I’m trying to depend on are indexed, where would I best start? Is module_deps.js
the right/earliest place?
I used it:
(defn ->js [var-name]
(-> var-name
(str/replace #"/" ".")
(str/replace #"-" "_")))
(defn invoke [function-name & args]
(let [fun (js/eval (->js function-name))]
(apply fun args)))
(ns go-report.pg.cadastro.grupo)
(defn ^:export ui [] [:div "Result"])
(eval/invoke "go-report.pg.cadastro.grupo/ui")
is getting Uncaught TypeError: Cannot read property 'ui' of undefined@fabrao try comparing the same eval with a hand-written eval in the javascript console
@benzap As I tested now, I have to reference the namespace to call it. In this case, is there any way to use require dynamicly?
I´m doing some menu references that I want to be dynamic. Now I have to use static references any time I include menu item referenced to view
if i'm understanding correctly, you want to pull in certain namespaces dynamically after some user action?
because I don´t want to use (require '[go-report.pg.cadastro.grupo :as grupo]) (grupo/ui)
anytime I create other view
I don't understand, can't you just list all of your required namespaces in the (ns)
form?
Today I use
(defmulti pagina (fn [x] x))
(defmethod pagina :cadastro/sistema []
[sistema/ui])
(defmethod pagina :cadastro/usuario []
[usuario/ui])
(defmethod pagina :cadastro/cliente []
[cliente/ui])
(defn ui []
[:div.centrar {:style {:width "100%" :height "100%" :background-color "#293E6A"}}
[menu/ui]
[pagina @(rf/subscribe [:controle/pagina])]])
Yeah, I see what you're getting at, but there are a ton of edge cases that would drive me crazy 🙂
I'm going nuts trying to find an article outlining a new way to require within clojurescript
Instead of defining :foreign-libs, you could just include a string within the namespace (ns)
form, no?
@benzap Here is the article https://clojurescript.org/news/2017-07-12-clojurescript-is-not-an-island-integrating-node-modules
Hi folks, I'm getting the following error when trying to take a value from a core.async channel returned by cljs-http, any ideas on how to go about debugging it?
Uncaught #error {:message "Invalid keyword: .", :data {:type :reader-exception, :ex-kind :reader-error}}
Maybe there's some javascript being interpreted by the cljs reader? My knowledge here is limited, any pointers would be 💯
Once I follow those instructions for :npm-deps
and run the build, @mfikes is there a way to discover the exact name of the namespace I need in the require
form?
Hmm… I don’t have a lot of experience using NPM or JavaScript. I would go digging through the source.
@jmckitrick i'm in the same boat
Yeah, I was going to say, it might be something you're sending. It probably has a try/catch, and produces the error as a return on the channel
Is it possible to pass namespace symbols as parameters in cljs? I’m trying to do this:
(map #(ns-publics %) ['ns.1 'ns2 ...])
I get this error though: Argument to ns-publics must be a quoted symbol (core/and (seq? quoted-ns) (= (first quoted-ns) (quote quote)) (core/symbol? (second quoted-ns)))
Isn't there a way to inspect namespaces at macro-expansion time?
Is this all documented somewhere? I think I learned that on the Google Group
In a similar thread
okay, so it seems like there is not a way to autogenerate information on functions in clojurescript. The only way to get this info is to have it done at compile time right? So I’d have to explicitly call ns-publics on each namespace manually. And moreover I’d have to call meta on every function within those namespaces manually.
Hey people! Is there any way to compile a CLJS to a node modules ready output? I wrote a small lib in CLJS and would like to be able to use it in a nodejs project
@jplaza I have only tried with the :node-library
profile of shadow-cljs
: it allows you to specify things to export. I cannot say anything about vanilla because back then when I tried I went directly to shadow-cljs
for this feature.
relevant user manual section -> https://shadow-cljs.github.io/docs/UsersGuide.html#target-node-library
Cool! Thanks a lot @richiardiandrea exactly what I was looking for
Let’s say I want to create an uberjar that launches an nrepl server with com.cemerick/piggieback
middleware. Why does the following throw an exception as it compiles?
(defproject smoketest "0.1.0-SNAPSHOT"
:dependencies [[org.clojure/clojure "1.9.0"]
[org.clojure/tools.nrepl "0.2.12"]
[com.cemerick/piggieback "0.2.2"]
[cider/cider-nrepl "0.17.0-SNAPSHOT"]]
:main smoketest.core
:profiles {:uberjar {:aot :all}})
Above is project.clj. And next is src/smoketest/core.clj
(ns smoketest.core
(:require [clojure.tools.nrepl :as nrepl]
[clojure.tools.nrepl.server :as server]
[cemerick.piggieback])
(:gen-class))
That’s literally it. The compiler throws an exception:
Compiling smoketest.core
clojure.lang.ExceptionInfo: Call to clojure.core/ns did not conform to spec:
In: [1] val: ((require [clojure.string :as string] [cljs.source-map.base64 :as base64])) fails spec: :clojure.core.specs.alpha/ns-form at: [:args] predicate: (cat :docstring (? string?) :attr-map (? map?) :clauses :clojure.core.specs.alpha/ns-clauses), Extra input
#:clojure.spec.alpha{:problems [{:path [:args], :reason "Extra input", :pred (clojure.spec.alpha/cat :docstring (clojure.spec.alpha/? clojure.core/string?) :attr-map (clojure.spec.alpha/? clojure.core/map?) :clauses :clojure.core.specs.alpha/ns-clauses), :val ((require [clojure.string :as string] [cljs.source-map.base64 :as base64])), :via [:clojure.core.specs.alpha/ns-form], :in [1]}], :spec #object[clojure.spec.alpha$regex_spec_impl$reify__2436 0x527a8665 "clojure.spec.alpha$regex_spec_impl$reify__2436@527a8665"], :value (cljs.source-map.base64-vlq (require [clojure.string :as string] [cljs.source-map.base64 :as base64])), :args (cljs.source-map.base64-vlq (require [clojure.string :as string] [cljs.source-map.base64 :as base64]))}, compiling:(cljs/source_map/base64_vlq.clj:1:1)
@gonewest818 Looks like some ns
header is wrong
It appears to be piggieback itself, although that doesn’t really make sense to me.
nice dig, thanks for that.
so I can use (keyword "foo")
and it creates :foo
, how can I make it ::foo
? i.e. I need fully qualified keyword bound to current namespace. I thought I could do something like (keyword (ns-name *ns*) "foo")
but that didn't do the trick
cljs.user> (ns-name *ns*)
#object[TypeError TypeError: Cannot read property 'name' of null]
cljs$core$ns_name (jar:file:/Users/ag.ibragimov/.m2/repository/org/clojure/clojurescript/1.9.946/clojurescript-1.9.946.jar!/cljs/core.cljs:11177:11)
nil
@ag isn’t Lumo self-hosted? In your standard cljs, the namespace (and var) info isn’t reified at runtime. It is only available at compile/macroexpansion time
I haven’t tried it, but it would seem to me that you could get it compiled into your js if you did something like
(def this-ns-name-str (namespace ::x))
I have seen things like that out there such as https://stackoverflow.com/questions/16656481/how-can-i-get-the-clojurescript-namespace-i-am-in-from-within-a-clojurescript-pr
nice link to SO, saved 😄 I also do this, seems to work fine:
(defmacro self-ns-name
"Return the namespace name as string (at compile time - macro)."
[]
(str *ns*))
maybe it does
> You can disable the Rebel readline by adding :readline false to your :figwheel config. i don't think readline works in emacs. Will CIDER users need to add this config for 0.15?
CIDER doesn't use an inferior process (i.e. communicate with a subprocesss via stdin/stdout) so it shouldn't be affected by rebel-readline, AFAICT
@pesterhazy if you use cider-jack-in it does create an inferior process, but the process buffer (and all process output) is hidden by default, most cider users aren't likely to interact with it
cider doesn't try to send input to that buffer though, as far as I know, so maybe the readline wouldn't matter
right, what I meant was that cider-jack-in doesn't talk to the repl via the process's stdin/out
well it does read the stdout
@jannis clj -e "(require '[cljs.closure :as cc] '[clojure.pprint :refer [pprint]]) (pprint (cc/index-node-modules-dir))" > npm.edn
one liner
this is awesome
@dnolen Sweet, yeah, I've done something similar in the meantime: wrap the function with redefs to capture it's I/O. My next question would be what kind of things or patterns I should be looking for in the output.