Fork me on GitHub
#cljs-dev
<
2016-10-20
>
chris-andrews20:10:22

I've run into a snag with commonjs modules in the latest clojurescript, but I would like to check about what the intended behavior is

chris-andrews20:10:29

Basically I can (:require [prefix.namespace :as myns :refer [myfn]]), and then I can use myns/myfn or myfn in my code without any issues.

chris-andrews20:10:49

However, if I try using prefix.namespace/myfn in my code, I get a compiler warning about the namespace prefix.namespace not existing and a console error that prefix is not defined.

chris-andrews20:10:04

In the javascript output, references to myns/myfn or myfn expand to module$prefix$namespace.render, wheras prefix.namespace/myfn expands to prefix.namespace.myfn

chris-andrews20:10:11

Is it feasible (and/or desirable) for the clojurescript compiler to resolve all of these correctly?

chris-andrews20:10:48

@anmonteiro oh wow, yes, that’s it exactly

anmonteiro20:10:02

it’s in the works 🙂

chris-andrews20:10:45

That’s awesome

chris-andrews20:10:51

so I’ve been playing with commonjs bundles a lot lately, and the current state is really pretty fantastic

chris-andrews20:10:38

I suspect that advanced optimizations will break everything, but it’s making it very easy to use npm/bower code

chris-andrews20:10:46

I think I’ve also figured out how handle dependencies that are shared between bundled commonjs and clojurescript (namely react)

dnolen20:10:47

@chris-andrews that’s interesting news

chris-andrews20:10:17

@dnolen I’m happy to try to document some of how this works if anyone is interested in it

dnolen20:10:28

@chris-andrews a blog post on what you’re doing would be interesting

dnolen20:10:05

knowing whether libraries are or aren’t advanced compilation safe is useful - that’s the big limitation here

dnolen20:10:45

we could do a lot for extern inference for CLJS -> JS interop

dnolen20:10:55

but JS -> JS seems like a lost cause

juhoteperi20:10:06

@chris-andrews Does it really work with npm modules? As far as I know, Closure can't yet handle npm require

dnolen20:10:42

@juhoteperi there’s support for CommonJS and AMD I thought

chris-andrews20:10:25

@juhoteperi The latest clojurescript is working with npm modules for me with the caveat that you have to bundle your javascript first

juhoteperi20:10:40

Right, so I want to be able to use them without bundling

chris-andrews20:10:38

Yeah the problem is that require(‘package’) in node has that weird method of searching for what you required

dnolen20:10:48

ah right k

juhoteperi20:10:26

Currently Closure has hardcoded search logic for require

juhoteperi20:10:46

We can either wait for them to fix that, or propose a fix for them

juhoteperi20:10:30

Or, if we preprocess the packages anyway to generate deps.cljs, we could rewrite requires so that Closure can deal with them

chris-andrews20:10:49

Yeah I’ve been pretty ok with the current constraints, basically I require whatever I want and break that out into modules and just webpack them in my build process

dnolen20:10:38

@chris-andrews yeah some kind of write up about what works well and a description of the limitations you’ve run into would be definitely be useful

chris-andrews20:10:11

@dnolen I’ll definitely put something together and ping you when it’s available

chris-andrews20:10:08

I do think that using webpack means there won’t be any dead code elimination from anything you run through it (although I think that could change in some cases with webpack 2)

dnolen21:10:49

@chris-andrews right thought I don’t see how Webpack can do any better than Google Closure here at all

dnolen21:10:09

at best you might get module level elimination - but that’s just implicit in how Google Closure works anyway

dnolen21:10:03

I’ve listening to people talk about getting DCE in these JS tools for years

dnolen21:10:09

“We’ll beat Closure"

dnolen21:10:11

time passes ...

juhoteperi21:10:12

Here is my work on automatically packaging npm modules as jars: https://github.com/cljsjs/cljsjs.npm

chris-andrews21:10:19

@dnolen yeah I don’t think commonjs in general can be optimized as well as google closure compatible code

chris-andrews21:10:59

I’m mainly doing this for the cases where you just want to use something that isn’t available through cljsjs with very little friction

dnolen21:10:51

@chris-andrews I’m assuming the main benefit here is normal looking :require for you then?

chris-andrews21:10:14

I bundled a file that just contained module.exports = require("d3");

chris-andrews21:10:24

and then could do:

chris-andrews21:10:25

(:require [js.d3 :as d3]) (-> (d3/select "body") (.append "span") (.text "hello world"))

chris-andrews21:10:04

@dnolen so I just tried my d3 hello world and it does compile with :optimizations :advanced

dnolen21:10:53

@chris-andrews is that because you have externs? (also d3 may be Closure compatible by avoiding JS string property metaprogramming)

chris-andrews21:10:16

no, I have no externs

chris-andrews21:10:43

some sample code:

chris-andrews21:10:48

}([function(a, c, d) {
  a.h = d(1);
}, function(a) {
  a.h = {s:1, u:2};
}]), G = F.s, H = F.u;
function I() {
  console.log("hello commonjs");
}
;I.v ? I.v() : I.call(null);
d3.select("body").append("span").text("Hello, npm!");
console.log(function(a) {
  return a * a * a;
});
console.log(G);
console.log(H);
console.log(G);

chris-andrews21:10:11

so it looks like it may have inferred externs for d3?

chris-andrews21:10:09

however, it did not optimize any of the d3 source code

chris-andrews21:10:56

actually, I think it did optimize some of the d3 source

dnolen21:10:32

if it didn’t that would be very surprising

dnolen21:10:50

in the ClojureScript JS module processing support

chris-andrews21:10:24

well a lot of it appears verbatim, including comments

chris-andrews21:10:18

I thought it might not optimize umd bundled code because it’s wrapped in a big function call that gets evaluated

dnolen21:10:13

big function call shouldn’t matter

dnolen21:10:21

Closure optimizes inside of closures

dnolen21:10:54

if white space isn’t collapsed and comments aren’t present then advanced optimization might not have been applied

chris-andrews21:10:51

then looks like maybe a bug

chris-andrews21:10:53

I’ll see if I can put together a collection of testing out different things with this