Fork me on GitHub
#clojurescript
<
2022-06-25
>
zane06:06:39

Has anyone successfully packaged a ClojureScript library as a UMD (or AMD for that matter) module? I’m really struggling with it. The basic approach I’ve been attempting is to compile the ClojureScript with :target :bundle and then feed the output through Webpack as per the https://clojurescript.org/guides/webpack.

zane19:06:31

Here’s my attempt at a https://github.com/zane/experiment/tree/library. This is just with output.library set. No UMD or AMD yet. :main contains:

(defn ^:export hello
  []
  (.log js/console "Hello, world!"))
webpack.config.js is:
module.exports = {
  entry: './out/main.js',
  output: {
    path: __dirname + '/dist',
    filename: 'bundle.js',
    library: 'tinylib',
  },
};
But the resulting tinylib that gets bound to window is empty. If there’s a different or better way I should be going about this I’m all ears.

zane20:06:20

I think the issue is essentially that Webpack expects the entrypoint to export all the variables to be included in the module, and the compiled JavaScript uses goog.exportSymbol instead.

zane20:06:36

I’m toying with wrapping the compiled JavaScript with some code that augments goog.exportSymbol before I feed it to Webpack, but I’m aware that that’s a huge hack. Suggestions welcome.

vlaaad07:06:14

https://www.scattered-thoughts.net/log/0025 has some notes about issues when developing a cljs app, maybe this might be of interest to cljs dev team?

p-himik07:06:13

I assume you mean specifically this section: https://www.scattered-thoughts.net/log/0025#clojurescript-blues At least the Rum compilation issue has been handled after a chat in #cljs-dev.

zane18:06:04

Is it expected that Webpack will fail to build the output of :target :bundle when :optimizations is set to :advanced?

dnolen19:06:20

@zane "fail" is pretty vague - can you be more specific about the behavior?

zane19:06:45

Absolutely! Didn’t want to get into it if the answer was “yes”.

zane19:06:47

@U050B88UR When I use :optimizations :whitespace I get the error goog.dom is undefined in the browser console when I include the bundle in a script tag.

zane19:06:54

This is with mode=none.

zane19:06:37

With mode=development I get SyntaxError: invalid assignment left-hand side.

zane19:06:01

With mode=production Webpack compilation actually fails:

> webpack --config webpack.config.js --mode=production
assets by status 1.85 MiB [cached] 1 asset
runtime modules 221 bytes 1 module
./out/main.js 1.84 MiB [built] [code generated]

ERROR in bundle.js
bundle.js from Terser plugin
Invalid assignment [bundle.js:4443,541]
…stacktrace…

zane19:06:54

Throwing the files in a repository. There’s not a lot to it, but perhaps I’ve misconfigured it somehow.

dnolen20:06:37

Probably won't have time to look at this. But these all sound like webpack specific problems especially if the CLJS works without it. For the assignment issue did you look at the generated JS to see what is wrong?

dnolen20:06:18

pretty printing the output will probably make it more obvious

dnolen19:06:47

@vlaaad the problem is that post is not very coherent and doesn't leave much of trail

dnolen19:06:38

one of the "compilation" issues was a runtime regression around fns w/ metadata etc.

dnolen19:06:21

also a lot random things were tried - without any explanation of why

dnolen19:06:38

"a lot of conditional compilation to support REPL driven development" - never needed such a thing ever - what does this mean?

dnolen19:06:43

I'm sure behind each "issue" there is something real to look at - but without proper bug reporting of any kind there's nothing to do about such posts

dnolen19:06:55

the one thing that looked somewhat suspicious the def meta fn thing - I cannot reproduce

zane19:06:31

Here’s my attempt at a https://github.com/zane/experiment/tree/library. This is just with output.library set. No UMD or AMD yet. :main contains:

(defn ^:export hello
  []
  (.log js/console "Hello, world!"))
webpack.config.js is:
module.exports = {
  entry: './out/main.js',
  output: {
    path: __dirname + '/dist',
    filename: 'bundle.js',
    library: 'tinylib',
  },
};
But the resulting tinylib that gets bound to window is empty. If there’s a different or better way I should be going about this I’m all ears.