How can I import this foreign lib.

Skip to first unread message

Leon Grapenthin

Oct 29, 2015, 2:51:33 PM10/29/15
to ClojureScript
I have now tried a variety of :foreign-libs options.

For example, today I tried to use this lib:

I have tried loading this directly with the :es6 option - to no luck because apparently the = member declaration is invalid JS.

I fixed that in the JS directly and put it on the constructor, but the JSX obviously was in the way. So I ran npm install and used the supplied make script to compile the code and tried to import the result with the :es6 option which simply resulted in the namespace not being available.

Then I tried it without any module-type option and that resulted in a runtime error (exports is not defined).

Then I tried it with the :commonjs module type, which resulted in ERROR: JSC_ES6_MODULE_LOAD_ERROR. Failed to load module "react" at resources/public/js/lib/react-textarea-autosize/lib/TextareaAutosize.js line 25 : 13

So I tried it with supplying ["cljsjs.react"] as a :requires, but that didn't help. Also runtime errors showed.

Is there even a clean way to do this? The last two libs I imported I changed the Javascript until it was working. But I'd prefer not to.

Kind regards,

Leon Grapenthin

Oct 29, 2015, 7:51:22 PM10/29/15
to ClojureScript
I solved this by compiling the library to UMD using webpack. Also, babel is required as a loader to compile ES6 and JS6.

It might be worthwhile to write a beginners guide about how to deal with the Javascript module world for people who never used JS as their first language. I'd do it myself but lack expertise.

In any case, here is the webpack configuration file I wrote to get the above package to compile so that it can be included via :module-type :commonjs - Your input is very welcome.

module.exports = {
entry: "./src/TextareaAutosize.js",
module: {
loaders: [
test: /\.js$/,
loader: "babel?stage=0"
output: {
path: __dirname + "/dist",
filename: "result.js",
libraryTarget: "umd",
library: "TextareaAutosize"
externals: {
"react": {root: "React"}

Leon Grapenthin

Oct 29, 2015, 9:07:12 PM10/29/15
to ClojureScript
Correction: Using :module-type :commonjs is incorrect because of the way the React dependency is specified. Instead, using no :module-type and :requires ["cljsjs.react"] is correct.

Thomas Heller

Oct 30, 2015, 4:54:01 AM10/30/15
to ClojureScript
This is very likely to break :advanced optimisations, did you test that yet?

Probably not what you are looking for but there is a "goog.ui.Textarea" [1,2] in the closure library which does the auto-sizing as well. Should be pretty straighforward to make a react-wrapper for it.



Leon Grapenthin

Oct 30, 2015, 6:19:25 AM10/30/15
to ClojureScript
Thanks Thomas for the link regarding the textarea, I might want to try that.

However I'd be very interested to learn why I should expect that this breaks advanced optimization (luckily it doesn't).

What is your recommended pipeline? I. e. what module-type should I comp/transpile foreign libs to before adding them to ClojureScript. It seems that webpack is very flexible in that regard so all I'd have to know is what is best for ClojureScript.

Thanks in advance, Leon.

Thomas Heller

Oct 30, 2015, 1:17:05 PM10/30/15
to ClojureScript
Interesting. I might need to try webpack to pre-process files before letting closure convert them. I made some attempts including common-js files into a build and most of it broke in some way.

I assume you are including react via the normal foreign cljsjs.react?

I don't have a recommended pipeline as the feature simply has not worked for me in :advanced.

Leon Grapenthin

Oct 31, 2015, 1:25:43 PM10/31/15
to ClojureScript
Yes, I am using CLJSJS react.

To configure dependencies among the libs, I used the externals: property with the dependencies exported class name under the root: property, where you specify the global classname of the dependencies export. Of course for that to work you need to use the :requires option of the CLJS compiler. There might be a more elegant way by specifying the dependencies directly in webpack and including as modules.

I don't require the webpack results as :commonjs but without a module-type. It surprises me as well that I didn't have to specify externs in two cases. Either these are automatically created (using CLJS 1.7.145) or since they are React comonents, they might be using the String based version of .createElement.

I found this document on the ClojureScript wiki

I don't really understand it but hope that it simplifies all that mess. It is shocking to realize that premium JS developers need expertise in all that chaos, at least when you are a CLJS "only" developer like me who is used to dependency vectors and usually spends his work time on programming ;)

NPM seems relatively sane though. If we could use NPM identifiers in our project.clj or if there were some plugin that allows to do so I guess it would be a step further.

It might be possible to require all foreign libs of a CLJS project that are on NPM into one NPM project and then use webpack to create one UMD export with webpack so that you don't have to specify deps within the project.clj.

The following might be useful if you intend to research this further:

I took inspiration by this guide:

It says: " output UMD, a format that's compatible with various module loaders (CommonJS, AMD) and globals." So I guess that CLJS foreign-libs import without module-type utilizes the "globals" variant, but that might be totally wrong. This is the UMD repo:

As a basis I took the webpack config in this library because it contains an exported JS in its repo that I had imported flawlessly earlier.

Reply all
Reply to author
0 new messages