For example, today I tried to use this lib:
https://github.com/andreypopp/react-textarea-autosize
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.
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"}
}
}
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.
HTH,
/thomas
[1] https://github.com/google/closure-library/blob/master/closure/goog/ui/textarea.js
[2] https://google.github.io/closure-library/source/closure/goog/demos/textarea.html
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.
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.
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 https://github.com/clojure/clojurescript/wiki/Enhanced-JavaScript-Module-Support
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: https://github.com/christianalfoni/react-webpack-cookbook/wiki/Authoring-libraries
It says: "...to 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: https://github.com/umdjs/umd
As a basis I took the webpack config in this library https://github.com/STRML/react-grid-layout/blob/master/webpack.config.js because it contains an exported JS in its repo that I had imported flawlessly earlier.