Why do I not get a single bundled .js file even though I have optimization set to advanced ?
I get a target/public/cljs-out/prod
folder
Is that folder just an artifact? And the prod-main.js
file actually contains everything inside it?
@didibus artefact.
@folcon can you send me your npm_deps.js file?
As in my original one? Ie what works in dev?
yeah that one
Sorry, had to step away for a bit, building it now
webpack.config.js
module.exports = {
target: 'web',
entry: './resources/public/js/compiled/out/main.js',
output: {
path: __dirname + "/out",
filename: 'app.js'
},
resolve: {
modules: ['./resources/public/js/compiled/out/', './node_modules']
}
}
One isn’t being created in min
, trying with dev
.
npm_deps.js
module.exports = {
npmDeps: {
"pako": require('pako') }
};
ok so react and react-dom should be in there
and the cljsjs libraries need to be excluded
I just confirmed that the :bundle target does not utilize cljsjs libs but does include them so that they are available globally
Right, but does that mean that I should audit my cljs libs to work out what npm stuff they’re doing and import them myself and exclude them in deps.edn
?
you’ll want to do that for advanced for sure
Actually hmmm
That seems like it’s not really handling that? I mean from my reading of the clojurescript announcement we could mix and match this, unless there’s some new command that just tells us what’s being used? I mean library deps can get pretty complicated…
yeah there’s more to it
Are you using Rum or Reagent?
Right, but in which case I don’t see the upside of using npm deps? It seems like the cost is taking on the burden of auditing all my libs to work out what they import and then explicitly excluding those and adding the imports myself… I mean at that point why not just write a cljsjs wrapper and skip all the hassle?
Reagent.
and old version of Reagent?
Well I can update, that’s not a blocker, I just wanted to keep the changes minimal while I was doing this =)…
If you have no need to use webpack or a bunch of npm libraries then there is no need to use the bundle target.
but I have found your experience really enlightening
Right, but I want to just use 1 npm lib, maybe a few more at some point in the future, that’s the target at least =)…
Sorry if I’ve not been much help in all this…
I’m also not quite clear about why the xmlhttprequest error came up as that implies it was building a node target as opposed to a browser one…
you have been, I appreciate you taking the time to share your experience
One thing I’m wondering is if the expectation is to perform in-depth auditing as you describe, a command to walk the deps and pull out the excludes / npm installs would be invaluable.
Thanks for the help, I’ll have to see if I can figure out some other way of managing this then…
there is an :install-deps
true flag
which will install all the node deps if the cljs library specifies it
you can even do it on the command line
In figwheel-main 0.2.7 you can to clj -m figwheel.main --install-deps
or even clj -m cljs.main --install-deps
that will add the packages that cljs libraries like reagent need if they are specified
Hmm, so the intent is to use :install-deps
as a flag? Perhaps I can put that into my figwheel dev.cljs.edn?
its better on the command line
because it doesn’t slow your compile
reagent has this file https://github.com/reagent-project/reagent/blob/master/src/deps.cljs
Ok, so perhaps do that before I call figwheel dev or advanced? I’ll give that a go now
which specifies its npm dependencies
if your reagent version is old it may not have that file
because this is another peice of the puzzle
if a ClojureScript library uses a js lib by its global value like js/React
then node modules wont work with it
ClojureScript libraries have to use the required ns symbol to reference the js lib
(:require [react])
then react/createElement
not js/React.createElement
It’s 0.8.1, which isn’t too bad, but fine this is a way I can move forward =)… And that’s good to know, I’ll be needing to write interop libs at some point, so knowing this is really helpful!
the (:require [react])
syntax works for cljsjs and npm deps
unfortunately this is all implicit knowledge and really needs to be recorded somewhere in the docs
That’s true
But as libraries improve and the eco-system adjusts this should all be pretty seemless
but until then …
Definitely, I appreciated all the help. I’ve got a string to pull on.
I’ll keep this updated if I figure out a fix, as in some sense this is probably a really useful thread for anyone looking at the logs in the future…
Btw, not sure if anything can be done about this?
[Figwheel] Failed to compile build dev in 1.074 seconds.
[Figwheel:WARNING] Compile Exception: contains? not supported on type: java.lang.Boolean
[Figwheel:SEVERE] contains? not supported on type: java.lang.Boolean
IE: a filename / line number would be helpful =)…update clojurescript version
to 773
But thanks for all the help and time you’ve taken! I really appreciated it =)…
It is currently?
I not with that error
At least the deps are, just trying the :install-deps
you suggested =)…
Hmm, ok so I’ll pull the deps tree and see if something is overriding
install-deps has that error in the previous version of clojurescript not the current one
so that’s strange to me
BTW the behavior around ignoring cljsjs files is apparently a bug
Oh? Cool, so we might get a fix =)…
Ok, I just did the :install-deps
and the react errors went away…
There’s just this node module thing:
Module not found: Error: Can't resolve 'xmlhttprequest'
Time to figure out where that’s coming from >_<…I think I found it? It looks like clojurescript itself is making it in xml_http_request.js
?
// Compiled by ClojureScript 1.10.773 {:target :nodejs}
goog.provide('ajax.xml_http_request')
@folcon that one should be OK
Ok, will continue digging =)…
you should see a require(‘xmlhttprequest’)
are you using :simple instead of :advanced?
that should make it easier
also you can use :pretty-print true
in your compiler options
along with :simple it should make it easy to find
I created that JIRA and we’ve beentalking about this in #cljs-dev
Thanks for the heads up =)… Trying with simple
assuming I’m passing the flag correctly ;)…
Well this is the offending line:
ajax.xml_http_request.xmlhttprequest=cljs.core._EQ_.call(null,cljs.core._STAR_target_STAR_,"nodejs")?function(){var a=require("xmlhttprequest").XMLHttpRequest;goog.object.set(global,"XMLHttpRequest",a);return a}():window.XMLHttpRequest;ajax.xml_http_request.xmlhttprequest.prototype.ajax$protocols$AjaxImpl$=cljs.core.PROTOCOL_SENTINEL;
So this I think?
ajax.xml-http-request
:
(def xmlhttprequest
(if (= cljs.core/*target* "nodejs")
(let [xmlhttprequest (.-XMLHttpRequest (js/require "xmlhttprequest"))]
(goog.object/set js/global "XMLHttpRequest" xmlhttprequest)
xmlhttprequest)
(.-XMLHttpRequest js/window)))
Right getting somewhere =)…
I don’t really understand why this is true?
(= cljs.core/*target* "nodejs")
Surely *target*
should be "bundle"
?yeah its complicated
hey where is that code?
(def xmlhttprequest
(if (= cljs.core/*target* "nodejs")
(let [xmlhttprequest (.-XMLHttpRequest (js/require "xmlhttprequest"))]
(goog.object/set js/global "XMLHttpRequest" xmlhttprequest)
xmlhttprequest)
(.-XMLHttpRequest js/window)))
in clojurescript?
Thats in cljs-ajax
https://github.com/JulianBirch/cljs-ajax/blob/master/src/ajax/xml_http_request.cljs#L29
yep
I just posted a question about to david
Yea, sorry was hunting the line number for you =)…
this is a good find, and obviously doesn’t work
do you use cljs-ajax directly?
oh you can probably set that in closure-defines [“cljs.core/target” nil]
or “browser”
No, I use https://github.com/day8/re-frame-http-fx
I’ll try browser (`cljs.core/target "browser"`) now...
Hmm, looks like it’s being set:
cljs.core._STAR_target_STAR_="bundle"
yet:
ajax.xml_http_request.xmlhttprequest=cljs.core._EQ_.call(null,cljs.core._STAR_target_STAR_,"nodejs")?function(){var a=require("xmlhttprequest").XMLHttpRequest;goog.object.set(global,"XMLHttpRequest",a);return a}():XMLHttpRequest;ajax.xml_http_request.xmlhttprequest.prototype.ajax$protocols$AjaxImpl$=cljs.core.PROTOCOL_SENTINEL;
Still gives the error…
Module not found: Error: Can't resolve 'xmlhttprequest'
oh yeah that won’t fix it because the require is actually in the code and the bundler is trying to replace it
Oh, fair enough =)…
if you do a clojure -Stree can you see which library is requiring cljs-ajax
Oh, I thought I mentioned it, it’s day8.re-frame/http-fx
you need a webpack.config.js
and you need a resolve {alias {‘xmlhttprequest’ false}} in it
along with the closure-define 🙂
Reading =)…
This is getting silly:
resolve: {
alias: {'xmlhttprequest': false},
...
}
error:
Bundling command failed
Invalid configuration object. Webpack has been initialised using a configuration object that does not match the API schema.
- configuration.resolve.alias['xmlhttprequest'] should be a string.
-> New request
I’m going to reread these docs >_<…geez
I think this is a webpack 5 only feature, so testing installing webpack@next
Ok so the upside is that it compiles, the downside is that it’s broken… I’m going to try and work out if updating the deps helps…
Here’s what I have so far on what is required is:
webpack.config.js
:
module.exports = {
target: 'web',
entry: './resources/public/js/compiled/out/main.js',
output: {
path: __dirname + "/out",
filename: 'app.js'
},
resolve: {
alias: {'xmlhttprequest': false},
modules: ['./resources/public/js/compiled/out/', './node_modules']
}
}
dev.cljs.edn
:
^{:final-output-to "resources/public/js/compiled/app.js"
:open-url false
:watch-dirs ["test" "src"]
:css-dirs ["resources/public/css"]
#_#_
:auto-testing true}
{:main example.core
:target :bundle
:bundle-cmd {:none ["npx" "webpack" "--mode=development" :output-to "-o" :final-output-to]}
:output-dir "resources/public/js/compiled/out"
:install-deps true
:npm-deps {"react" "16.8.6"
"react-dom" "16.8.6"}
:source-map-timestamp true}
min.cljs.edn
:
^{:final-output-to "resources/public/js/compiled/app.js"
:open-url false
:watch-dirs ["test" "src"]
:css-dirs ["resources/public/css"]}
{:main example.core
:target :bundle
:bundle-cmd {:default ["npx" "webpack" "--mode=production" :output-to "-o" :final-output-to]}
:output-dir "resources/public/js/compiled/out"
:source-map-timestamp true
:devcards true
:install-deps true
:npm-deps {"react" "16.8.6"
"react-dom" "16.8.6"}
:closure-defines {cljs.core/*global* "window"
cljs.core/*target* "browser"
goog.DEBUG false}}
:
{
"name": "example",
"version": "1.0.0",
"description": "",
"main": "index.js",
"directories": {
"doc": "docs",
"test": "test"
},
"scripts": {
"test": "echo \"Error: no test specified\" && exit 1"
},
"keywords": [],
"author": "",
"homepage": "",
"devDependencies": {
"webpack": "^5.0.0-beta.16",
"webpack-cli": "^3.3.11"
},
"dependencies": {
"pako": "^1.0.11"
}
}
Profile :dev deps:
[com.bhauman/figwheel-main "0.2.7-SNAPSHOT"]
[com.bhauman/rebel-readline-cljs "0.1.4"]
To build dev:
lein run -m figwheel.main -b dev -r --install-deps
To build min:
lein run -m figwheel.main -O advanced -bo min
Notes:
Use resolve.alias
module-name false in webpack.config.js
, ie:
resolve: {alias: {'xmlhttprequest': false}}
To elide a module from webpack that’s being mistakenly added.
If it should be added, but it’s not in being added because it’s a dep in a cljsjs lib for example use either :install-deps true
or add --install-deps
to the figwheel.main command as shown to add it.
Can’t seem to add --install-deps
to the min lein run command, but this can be worked around by adding it into min.cljs.edn
.One of the problems is coming from:
cljsjs/react-transition-group
Which is interesting, going to try what you mentioned earlier to pull it straight from npmok so react works as stated, but react-transition-group
does not…
cljs.user=> (require '[cljsjs.react-transition-group])
nil
cljs.user=> js/ReactTransitionGroup
#js {}
cljs.user=> (require '[react-transition-group])
nil
cljs.user=> react-transition-group
nil
cljs.user=> (js-keys react-transition-group)
#js []
this is with :npm-deps
:
"react-transition-group" "4.4.1"
and:
[cljsjs/react-transition-group "4.3.0-0"]
Also npm_deps.js
does not contain an entry for react-transition-group
.