I'm writing a Java to YAML transformer using my Pegex parsing library. The basic purpose is to aid in translation of clojure's java classes to other languages. Pegex in implemented fully in both Perl and JavaScript. My question here is would it be better for me to do this in JS and publish to NPM (rather than Perl and CPAN)?
fwiw I'm basically converting this Java grammar https://docs.oracle.com/javase/specs/jls/se7/html/jls-18.html to Pegex. I only care that it's good enough to parse all the clojure java sources for now.
Would having it on NPM make it more accessible to clojure people? I could have a clojurescript wrapper for it. Are clojurescript libaries just published to NPM? I guess there's no real point beyond me possibly learning some clojurescript.
Random thoughts welcome (to my rather random queries)
i usually find clojure and cljs packages uploaded to clojars
when cljs is uploded to npm its usually some nbb script
never heard of nbb
nbb = node babashka
its babashka but it runs on node.js, and it lets you do ad-hoc CLJS scripting… if you have npm installed, then trying it out is as easy as running npx nbb
what's npx ? :)
the new npm or something?
npx is a tool for executing npm packages, built in to npm
it works like "npm run ..." but for any package
can't believe I didn't know that
@hifumi123 have you published stuff on clojars?
and/or mavencentral?
yes to both
maven central is a lot more ceremony because you need pgp keys uploaded on a public keyserver, open a support ticket requesting access to a group id, and then finishing a challenge to get it
then deployments require you to sign the JARs with your pgp keys and what not
clojars is much more lax in that, although this is bad for security, it doesnt require pgp keys or signing anything
you just make an account and you have two group ids for free — you can get a custom group id if you own a domain name and complete an automated dns challenge IIRC
but otherwise deployment is as simple as running lein deploy, assuming you have used leiningen before
I see. So source code (both clojure and java?) go to clojars, and jar files to maven? Or is it that clojure parts go to clojars and java code to maven?
@hifumi123 btw I got a http://clojars.org account and a sonatype account (for maven, right?) about a year ago
But yeah the pgp stuff kept me from releasing anything
and I'm not sure what you mean by group ids
Looks like I'm ingy on both http://clojars.org and http://sonatype.org
oh huh, I guess I did upload to clojars https://clojars.org/org.clojars.ingy/ingy-prelude
re: group ids: maven by default namespaces packages. the "group id" is basically a namespace
e.g. org.clojars.ingy is one (of two) namespaces clojars gives you for free. and you can publish packages with whatever name youd like, since they will exist under this namespace that only you control
I assume lein handles clojurescript as well as clojure packaging and publishing?
What do Clojure people use maven for?
trying to grok the matrix of multiple clojure platforms (clj and cljs) and multiple package registries (clojars and maven) and multiple assets (source and jar)
I think there is an important distinction to make between maven repositories and maven the build tool
clojure users make use of maven repositories, but not necessarily maven itself
people mostly use either leiningen or tools.deps for clojure on the jvm, and on clojurescript almost everyone uses shadow-cljs
both clojure and clojurescript tend to publish to a maven repository
in the case of clojure, most java libraries are also pushed to a maven repository (usually maven central)
for this reason, most clojure setups will default to maven central and clojars as default repositories for fetching dependencies
the vast majority of clojure/clojurescript libraries get published to clojars
in the javascript world, people tend to deploy to npm, and for that reason, shadow-cljs etc. also supports fetching dependencies from npm — this is typically meant for fetching javascript libraries rather than clojurescript libraries
if I had to simplify how this all works, I would make a table like so:
| Platform | Repositories | Format |
|---------------+------------------------+--------|
| Clojure | Maven Central, Clojars | JAR |
| ClojureScript | Maven Central, Clojars | JAR |
| Java | Maven Central | JAR |
| JavaScript | NPM | TGZ |
so if I had a project with both clojure and java code, would I publish the clojure code to one place and the java to another?
if you had a project with clojure and java code, you would publish a single JAR to a maven repository
you will most likely publish to clojars since it is simpler to publish there than maven central
do jars contain source and bytecode?
clojure libraries tend to be deployed as JARs with source code inside rather than classes inside
ok
you can compile the java code to class files if youd like, but people typically do not compile clojure files to classes because the format may change between clojure versions
ah
so for best results / best compatibility, you will typically distribute clojure code rather than compiled clojure code
i.e. you leave compilation to the user
yep
making a bit more sense now
so clojars is a "maven" repository?
when I was saying maven I meant "maven central"
but that's just another maven repository it seems
I guess my last question would be, What's the easiest way you know to get something on maven central?
(easiest/best way to learn)
> so clojars is a “maven” repository? correct > What’s the easiest way you know to get something on maven central? personally speaking: i just avoid maven central if i can, and deploy to clojars or my own maven repos
oh ok
the easiest way to deploy something for public consumption in clojure is to deploy on clojars — its less of a headache for the library maintainer and the library consumer
I thought you were saying most authors publish to both
ah, no, i meant to say most clojure packages are published to clojars, with some exceptions
most of the clojure libraries you do see on maven central tend to be “first party” clojure libraries
i.e. things maintained by cognitect, such as clojure itself, core.async, core.logic, and what not
great. and same for clojurescript, right?
yup
practically all of the CLJS libraries I know of are published on clojars
great to know. nothing stopping me then
I publish some things to npm... If i write a cljs interface for them then I can publish that to clojars?
yup
hmm if that's right, then wondering if I would use a second git repo for the cljs wrapper
submodules or something
well, for the cljs package, you dont need to bundle the npm deps at all
it just grabs them from npm?
however, if you would like to do so anyway, you can create a deps.cljs file that contains something like this
{:npm-deps {"your-npm-library" "1.0.0"}}
well there are two ways to approach this:
• you instruct ppl to run npm install stuff themselves
• you add a deps.cljs file with {:npm-deps {"stuff" "1.0.0"}} inside, and CLJS will automatically fetch the npm deps for the user
but either way you don't ship js files to clojars, sounds like
you can, but typically not js files from npm packages
some very old CLJS libraries may have done this + ship google closure externs (so that they can survive advanced js compiler optimizations)
but this hasnt been done since nearly everyone moved to shadow, which offers near seamless npm integration
What's shadow-cljs in 10 words?
I could search for all this I know, but I like hearing it from you 🙂
Definitely going to be publishing stuff soon
shadow-cljs in less than 10 words: it’s a build tool for clojurescript
the longer edition: clojurescript is a language that transpiles to javascript — it leverages the google closure compiler, an optimizing compiler for javascript, to produce small and fast JS code
the pipeline from CLJS -> JS is roughly as follows: 1. code in a cljs file is parsed 2. this creates some AST 3. the cljs compiler emits specific JS code for each node of the AST 4. the JS code is organized 5. (optional) the organized JS code is sent to google closure for optimization
shadow-cljs covers steps 1, 4, and 5 here
it takes care of e.g. parsing npm requires, and then organizing npm code and CLJS code so that they can actually run together, and finally, it decides how to optimize npm code and cljs code