figwheel-main

figwheel-main http://figwheel.org
2020-06-01T04:12:34.099600Z

Why do I not get a single bundled .js file even though I have optimization set to advanced ?

2020-06-01T04:13:29.100600Z

I get a target/public/cljs-out/prod folder

2020-06-01T04:15:39.101700Z

Is that folder just an artifact? And the prod-main.js file actually contains everything inside it?

dominicm 2020-06-01T09:18:24.102Z

@didibus artefact.

bhauman 2020-06-01T13:29:52.102200Z

@folcon can you send me your npm_deps.js file?

2020-06-01T13:31:03.102400Z

As in my original one? Ie what works in dev?

bhauman 2020-06-01T13:34:34.102600Z

yeah that one

2020-06-01T15:06:54.102800Z

Sorry, had to step away for a bit, building it now

2020-06-01T15:47:54.103Z

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')  }
};

bhauman 2020-06-01T15:49:39.103200Z

ok so react and react-dom should be in there

bhauman 2020-06-01T15:49:55.103400Z

and the cljsjs libraries need to be excluded

bhauman 2020-06-01T15:51:35.103600Z

I just confirmed that the :bundle target does not utilize cljsjs libs but does include them so that they are available globally

2020-06-01T15:52:35.103800Z

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?

bhauman 2020-06-01T15:53:13.104Z

you’ll want to do that for advanced for sure

bhauman 2020-06-01T15:55:40.104200Z

Actually hmmm

2020-06-01T15:56:22.104400Z

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…

bhauman 2020-06-01T15:56:57.104600Z

yeah there’s more to it

bhauman 2020-06-01T15:58:26.104800Z

Are you using Rum or Reagent?

2020-06-01T15:58:36.105Z

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?

2020-06-01T15:58:44.105200Z

Reagent.

bhauman 2020-06-01T15:58:56.105400Z

and old version of Reagent?

2020-06-01T15:59:27.105600Z

Well I can update, that’s not a blocker, I just wanted to keep the changes minimal while I was doing this =)…

bhauman 2020-06-01T16:01:10.105800Z

If you have no need to use webpack or a bunch of npm libraries then there is no need to use the bundle target.

bhauman 2020-06-01T16:01:42.106100Z

but I have found your experience really enlightening

2020-06-01T16:02:32.106300Z

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 =)…

2020-06-01T16:02:50.106500Z

Sorry if I’ve not been much help in all this…

2020-06-01T16:04:33.106700Z

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…

bhauman 2020-06-01T16:05:08.106900Z

you have been, I appreciate you taking the time to share your experience

2020-06-01T16:11:31.107100Z

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.

2020-06-01T16:11:59.107300Z

Thanks for the help, I’ll have to see if I can figure out some other way of managing this then…

bhauman 2020-06-01T16:12:07.107500Z

there is an :install-deps true flag

bhauman 2020-06-01T16:12:44.107700Z

which will install all the node deps if the cljs library specifies it

bhauman 2020-06-01T16:12:52.107900Z

you can even do it on the command line

bhauman 2020-06-01T16:13:28.108100Z

In figwheel-main 0.2.7 you can to clj -m figwheel.main --install-deps

bhauman 2020-06-01T16:13:45.108300Z

or even clj -m cljs.main --install-deps

bhauman 2020-06-01T16:14:29.108500Z

that will add the packages that cljs libraries like reagent need if they are specified

2020-06-01T16:14:48.108800Z

Hmm, so the intent is to use :install-deps as a flag? Perhaps I can put that into my figwheel dev.cljs.edn?

bhauman 2020-06-01T16:15:03.109Z

its better on the command line

bhauman 2020-06-01T16:15:29.109200Z

because it doesn’t slow your compile

bhauman 2020-06-01T16:16:21.109500Z

reagent has this file https://github.com/reagent-project/reagent/blob/master/src/deps.cljs

2020-06-01T16:16:39.109800Z

Ok, so perhaps do that before I call figwheel dev or advanced? I’ll give that a go now

bhauman 2020-06-01T16:16:44.110Z

which specifies its npm dependencies

bhauman 2020-06-01T16:17:50.110200Z

if your reagent version is old it may not have that file

bhauman 2020-06-01T16:18:04.110400Z

because this is another peice of the puzzle

bhauman 2020-06-01T16:19:05.110600Z

if a ClojureScript library uses a js lib by its global value like js/React then node modules wont work with it

bhauman 2020-06-01T16:19:49.110800Z

ClojureScript libraries have to use the required ns symbol to reference the js lib

bhauman 2020-06-01T16:19:59.111Z

(:require [react])

bhauman 2020-06-01T16:20:10.111200Z

then react/createElement

bhauman 2020-06-01T16:20:37.111400Z

not js/React.createElement

2020-06-01T16:20:53.111600Z

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!

bhauman 2020-06-01T16:21:37.111800Z

the (:require [react]) syntax works for cljsjs and npm deps

bhauman 2020-06-01T16:22:12.112Z

unfortunately this is all implicit knowledge and really needs to be recorded somewhere in the docs

2020-06-01T16:23:36.112200Z

That’s true

bhauman 2020-06-01T16:24:22.112400Z

But as libraries improve and the eco-system adjusts this should all be pretty seemless

bhauman 2020-06-01T16:24:32.112600Z

but until then …

2020-06-01T16:25:12.112800Z

Definitely, I appreciated all the help. I’ve got a string to pull on.

2020-06-01T16:25:46.113Z

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…

2020-06-01T16:26:10.113200Z

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 =)…

bhauman 2020-06-01T16:26:25.113400Z

update clojurescript version

bhauman 2020-06-01T16:26:27.113600Z

to 773

2020-06-01T16:26:32.113800Z

But thanks for all the help and time you’ve taken! I really appreciated it =)…

2020-06-01T16:26:47.114Z

It is currently?

bhauman 2020-06-01T16:27:04.114200Z

I not with that error

2020-06-01T16:27:31.114400Z

At least the deps are, just trying the :install-deps you suggested =)…

2020-06-01T16:27:51.114600Z

Hmm, ok so I’ll pull the deps tree and see if something is overriding

bhauman 2020-06-01T16:28:07.114800Z

install-deps has that error in the previous version of clojurescript not the current one

bhauman 2020-06-01T16:29:10.115100Z

so that’s strange to me

bhauman 2020-06-01T16:36:45.115300Z

BTW the behavior around ignoring cljsjs files is apparently a bug

2020-06-01T16:47:46.115500Z

Oh? Cool, so we might get a fix =)…

2020-06-01T16:54:07.115700Z

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 >_<…

2020-06-01T17:19:24.116100Z

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')

bhauman 2020-06-01T17:25:02.116400Z

@folcon that one should be OK

2020-06-01T17:25:25.116600Z

Ok, will continue digging =)…

bhauman 2020-06-01T17:25:31.116800Z

you should see a require(‘xmlhttprequest’)

bhauman 2020-06-01T17:25:57.117Z

are you using :simple instead of :advanced?

bhauman 2020-06-01T17:26:04.117200Z

that should make it easier

bhauman 2020-06-01T17:26:58.117400Z

also you can use :pretty-print true in your compiler options

bhauman 2020-06-01T17:27:10.117600Z

along with :simple it should make it easy to find

bhauman 2020-06-01T17:27:27.117800Z

https://clojure.atlassian.net/browse/CLJS-3258

bhauman 2020-06-01T17:27:50.118Z

I created that JIRA and we’ve beentalking about this in #cljs-dev

2020-06-01T17:32:11.118200Z

Thanks for the heads up =)… Trying with simple assuming I’m passing the flag correctly ;)…

2020-06-01T17:44:18.118400Z

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;

2020-06-01T17:47:56.118600Z

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)))

2020-06-01T17:54:26.118800Z

Right getting somewhere =)…

2020-06-01T18:05:55.119Z

I don’t really understand why this is true?

(= cljs.core/*target* "nodejs")
Surely *target* should be "bundle"?

bhauman 2020-06-01T18:12:06.119200Z

yeah its complicated

bhauman 2020-06-01T18:12:53.119400Z

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)))

bhauman 2020-06-01T18:13:01.119600Z

in clojurescript?

bhauman 2020-06-01T18:17:08.119800Z

Thats in cljs-ajax

bhauman 2020-06-01T18:20:02.120300Z

yep

bhauman 2020-06-01T18:20:13.120500Z

I just posted a question about to david

2020-06-01T18:20:24.120700Z

Yea, sorry was hunting the line number for you =)…

bhauman 2020-06-01T18:20:52.120900Z

this is a good find, and obviously doesn’t work

bhauman 2020-06-01T18:21:02.121100Z

do you use cljs-ajax directly?

bhauman 2020-06-01T18:24:40.121300Z

oh you can probably set that in closure-defines [“cljs.core/target” nil]

bhauman 2020-06-01T18:24:53.121500Z

or “browser”

2020-06-01T18:27:17.121700Z

No, I use https://github.com/day8/re-frame-http-fx

2020-06-01T18:27:44.122Z

I’ll try browser (`cljs.core/target "browser"`) now...

2020-06-01T18:54:25.122400Z

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'

bhauman 2020-06-01T18:59:10.122600Z

oh yeah that won’t fix it because the require is actually in the code and the bundler is trying to replace it

2020-06-01T18:59:28.122800Z

Oh, fair enough =)…

bhauman 2020-06-01T19:04:51.123Z

if you do a clojure -Stree can you see which library is requiring cljs-ajax

2020-06-01T19:21:46.123200Z

Oh, I thought I mentioned it, it’s day8.re-frame/http-fx

bhauman 2020-06-01T19:50:09.123400Z

you need a webpack.config.js

bhauman 2020-06-01T19:50:11.123600Z

https://webpack.js.org/configuration/resolve/

bhauman 2020-06-01T19:51:10.124Z

and you need a resolve {alias {‘xmlhttprequest’ false}} in it

bhauman 2020-06-01T19:52:01.124200Z

along with the closure-define 🙂

2020-06-01T20:02:26.124400Z

Reading =)…

2020-06-01T20:20:56.124600Z

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.
   -&gt; New request
I’m going to reread these docs >_<…

bhauman 2020-06-01T20:28:32.124800Z

geez

2020-06-01T20:31:59.125Z

I think this is a webpack 5 only feature, so testing installing webpack@next

2020-06-01T21:06:53.125200Z

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…

2020-06-01T21:07:08.125400Z

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\" &amp;&amp; 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.

2020-06-01T21:09:02.125600Z

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 npm

2020-06-01T21:52:17.125900Z

ok so react works as stated, but react-transition-group does not…

cljs.user=&gt; (require '[cljsjs.react-transition-group])
nil
cljs.user=&gt; js/ReactTransitionGroup
#js {}
cljs.user=&gt; (require '[react-transition-group])
nil
cljs.user=&gt; react-transition-group
nil
cljs.user=&gt; (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.