This page is not created by, affiliated with, or supported by Slack Technologies, Inc.
2017-07-10
Channels
- # beginners (15)
- # boot (15)
- # cider (6)
- # cljs-dev (231)
- # cljsjs (1)
- # cljsrn (26)
- # clojure (147)
- # clojure-argentina (1)
- # clojure-dev (8)
- # clojure-germany (1)
- # clojure-italy (26)
- # clojure-russia (2)
- # clojure-spec (83)
- # clojure-uk (154)
- # clojurescript (123)
- # conf-proposals (3)
- # core-async (5)
- # cursive (26)
- # datascript (21)
- # datomic (120)
- # emacs (2)
- # graphql (9)
- # hoplon (195)
- # instaparse (16)
- # jobs-discuss (1)
- # leiningen (8)
- # luminus (8)
- # lumo (7)
- # off-topic (17)
- # om (7)
- # om-next (3)
- # parinfer (121)
- # pedestal (5)
- # planck (13)
- # re-frame (11)
- # reagent (21)
- # ring-swagger (2)
- # spacemacs (28)
- # uncomplicate (3)
- # unrepl (7)
- # untangled (34)
- # vim (5)
I have Reagent working with string requires, which use Cljsjs code through generated wrapper Closure modules:
❯ cat outsite/public/js/out/globalmodules/cljsjs/create-react-class/development/create-react-class.inc.js
goog.provide("globalmodule$create$react$class");
goog.require("globalmodule$react");
globalmodule$create$react$class = window.createReactClass;
{:file "cljsjs/create-react-class/development/create-react-class.inc.js"
:provides ["create-react-class"]
:requires ["react"]
:js-global "createReactClass"
:file-min "cljsjs/create-react-class/production/create-react-class.min.inc.js"}
^ if foreign lib has :js-global
option, it is used to generate that Closure module@juhoteperi is the purpose of that maintaining backwards compat?
or just reusing what CLJSJS has?
I guess it can be thought as backwards compat
Adapting to use npm-deps will take time (and there will be some that won't use it, I think), and it will be slow if libraries have to choose between using npm-deps and old way (cljsjs)
This way the libraries can use the new requires and it will work with both npm-deps and (updated) cljsjs packages
It should be also possible to write similar wrappers for Node target
Then libraries could just use the same requires everywhere
:npm-deps
is not going to be supported under Node
this commit removes compatibility for it: https://github.com/clojure/clojurescript/commit/fc0989f1b44b97547410a2d2c807f16430b47486
String requires can be used without npm-deps
(with my changes)
We could just add code which turns (:require ["react-dom/server"])
into wrapper with globalmodules$react_dom$server = require("react-dom/server");
when using Node target
https://github.com/clojure/clojurescript/compare/master...Deraen:string-require-js-global?expand=1
I'll write notes tomorrow about why I want this feature and about the implementation
@juhoteperi looks like what I described here? https://dev.clojure.org/jira/browse/CLJS-2061?focusedCommentId=45798&page=com.atlassian.jira.plugin.system.issuetabpanels:comment-tabpanel#comment-45798
@juhoteperi the Node.js parts just don’t seem high priority to me - if there’s something about this that will ease CLJSJS transition then that’s far higher priority.
re: :js-global
is this actually practical? will a JS lib necessarily only export one global?
As far as I can see, using npm-deps and string requires like they are implemented now, would break Reagent in Node
So while CLJSJS is first priority for me, I think Node support is also important
I'll write notes about this and we can see what other solutions we can come up
and we’re only doing it to get around the fact that we don’t have #|| literal in Clojure
People won't use :npm-deps
if there is no library support, and libraries won't support if it means breaking all previous configurations and no support for Node etc.
I disagree that a large population of people care about their build working under Node if they are going :npm-deps
I don’t really see any danger here in making choices that will make Node.js case difficult
Reagent has support for prerendering using Node, and I wouldn't want to break it even if it is not widely used
the other thing I’m not even particularly convinced that string based require for signaling Node.js stuff is a good idea
if we had #||
reader literal so we could do #|react/dom-server|
and there just no way we would think to use that as Node.js target special case
I would suggest that whatever we want to do actually address Node.js usage need more hammock time than quickly piggiebacking on string based require
Draft of the Code Splitting post https://github.com/clojure/clojurescript-site/pull/111
@juhoteperi another thought since @anmonteiro has already done a ton of work to index node_modules
I don’t see why string based requires even needs to be involved here
I haven't really followed the module splitting but quick Q: Does :verbose
give some debug information about how the splits were done? Like when there were parent namespaces that were picked. (etc?)
@juhoteperi instead we can use the JS index to figure out how we should go about requiring something
Yes indexing seems fine solution for that
it does means how we currently do it needs to be reworked - instead of the missing-js pass thing we need to know the whole index same as we do for Closure compatible libs on the classpath
Hmm, right currently node module index only includes those files that are used, and that is based on :npm-deps
and missing modules.
Alternative would be to index everything, and then only process those modules that are really required by Cljs sources.
the static resolve
, how does it work? is that like a static map injected into the build?
Yes, I agree. I find the missing-js- modules.. quite backwards, would be simpler to check if something is js lib than presume it is because it doesn't already exist.
@martinklepsch it just checks if some value exists, if it does return a var
@juhoteperi yes I didn’t love it - but it’s now clear why it’s a suboptimal approach
Anyway, my main priority is Cljsjs-style foreign libs, and Npm is an afterthought. Though changing the indexing will help with Cljsjs-style foreign libs also.
One other thing I was thinking about: How hard/what would it require to get Closure-lib understand Foreign-libs? E.g. goog.require("cljsjs.react");
from Closure lib.
@martinklepsch we have a Var
type
@juhoteperi the problem is that the thing being required needs to look like a Closure lib
Changing the indexing will probably remove also any need for special handling of string require symbols. Strings only need to be used when the name has "/" but the logic to resolve the module is same for symbols and strings.
Well, I guess the logic is the same even now but string requires are used to select what Node modules to index.
@juhoteperi yes, getting rid of the connection w/ :npm-deps
would be desirable.
the number of files is way less useful information than - “it took 500ms to index 12697 files”
Hm deps for them also need to be indexes for closure
But I think it should be posibble
@juhoteperi so are you thinking about prepending the provides/requires ? Google Closure needs to see those - this didn’t seem that attractive to me
to the foreign-libs? No I doubt that would be a good idea.
But when testing :js-global
it would have been usefulm, as it generates Closure modules that need to depend on the foreing-libs
My current code for :js-global
is just a proof-of-concept, there are some parts (like using module names in js-dependencies
to modify :requires
) that are bad ideas
Unfortunately changing the modules_deps.js
to index all files is not super easy, as module-deps
works by indexing the modules used in given JS input file
@juhoteperi yeah we should get @anmonteiro’s input here when he’s around
Yeah. In the meanwhile I'm checking what Closure compiler does. I think they might index the node modules lazily.
@juhoteperi I don’t see any issues with indexing the top level as a first step
what António has done should be easy to modify to accomplish just that - it’s just about computing what the top level :provides
re: :js-global
it would be useful to understand at a higher level what you are trying to accomplish - i.e. state the problem so that your current line of thinking is simple to grasp and open up ideas about alternatives.
I mean at high level I see you want to permit fluidity in :npm-deps
cljsjs
choice - but need to understand what the obstacles (problems) are
Just accidentally wrote (true x)
instead of (true? x)
, got a runtime error. Should this be caught by CLJS analyzer?
@dnolen @juhoteperi
1. should be easy to index the entire Node modules folder with some exceptions (see 2.), but I don't exactly understand what it would provide?
2. The caveat is things of the form react-dom/server
that are not reachable from the top level and why I went for the missing-js-modules
approach
"index the entire Node modules" -> all JS files, including server.js
@anmonteiro if we have a master index of all js deps we can know if they are :goog
or :node
Ah, and make Node support work with npm-deps?
We wouldn't process the modules in that case
Yeah this sounds like a good path forward. I can see what it takes to index all the Node stuff
@anmonteiro it would be worth considering how to avoid indexing everything
Will we still have :npm-deps
?
Then I can just index everything inside those folders only
If you wanna require a transitive dep of React, you have to add it to npm-deps
Or does that not work?
Oh ok that won't work then
3) whether npm modules get compiled and whether we emit goog.require or js/require or not has to do with :target
I might divide this experiment into milestones to prove it's possible. e.g.: 1. Index only stuff reachable from the top level 2. Naively index everything 3. Perhaps experiment with a depth option 4. Clean up & dedupe
hrm didn’t know String.prototype.endsWith
was ES6 only
submitted https://dev.clojure.org/jira/browse/CLJS-2208 fixing an occurrence in module_deps.js
I’m thinking since the dev work around the other posts are still very much in flight, maybe my code splitting post should go out first?
the only thing missing is an additional PR for the guide, but that’s mostly going to be a copy and paste affair
Do You think what we've been discussing with cljs-oss
is “snapshot testing” mentioned by James here? https://twitter.com/jlongster/status/884479533692399618 (Wondering if that is a common name for the pattern.)
Pertinent aspect: “cargotest is a small tool that runs the test suite of several significant out-of-tree Rust projects. The projects are chosen to have a wide variety of dependencies to maximize the chances of detecting type system regressions through build failures.”
heh no, I just thought the Clojure build matrix approach makes sense with outside projects, especially the more popular ones
heh, that's similar to how @andy.fingerhut made sure I didn't introduce subtle edge cases in tools.analyzer every new release years ago, https://github.com/jonase/eastwood/tree/master/crucible
empirically it's a better test suite than any number of unit tests you could ever come up with, IME
I've always wanted to run the bajillions of successful 4clojure solutions through ClojureScript tô see what works, barring Java interop issues.
Also have been wondering the same with Spec to generate code. Both ideas are that ClojureScript uses Clojure as a reference for correctness
I made quite nice progress on https://github.com/cljs-oss/canary, would be great if someone could look and stop me if this not the best idea 🙂
people will be writing clj functions or shell script (if preferred): https://github.com/cljs-oss/canary/tree/master/runner/src/cljs_oss/projects
the tool will run them in parallel and report results back: https://asciinema.org/a/6GbGI9swdQez8lKGSahun4Msm
@bronsa I agree it’s useful, but like the post alludes it’s not the answer by itself by any means
it would be nice if they talked about how long this takes, how many machines etc. it seems like the most costly and slowest form of testing
@dnolen the code splitting article looks great! I just left one note about a claim that I don’t believe is entirely accurate
@anmonteiro yeah was just looking at that I don’t see how the loader is important wrt. to how vendorization requires you to write useless code?
definitely true for the plugins part, but we’re kinda still managing splits via the source code with cljs-loader
and resolve
Webpack also allows you to add several entrypoints
just like our :modules
declaration
I’m simply pointing out what goes into a split isn’t expressed in the source and doesn’t require a plugin
I see. Now I get it but it isn’t clear
Webpack kind of complects splitting and loading - and I should be clear what I’m talking about here
@anmonteiro https://medium.com/@adamrackis/vendor-and-code-splitting-in-webpack-2-6376358f1923 stuff like this is what I’m referring to
looking for some final feedback https://github.com/clojure/clojurescript-site/pull/111
@anmonteiro I tweaked the language about Webpack comparison to clarify it’s only about split definition (not loading)
looking!
much clearer
Here is my draft of preprocess post: https://github.com/clojure/clojurescript-site/pull/112
@juhoteperi left some feedback, the technical parts are pretty good, but I think the post needs more setup / marketing mojo 🙂
Yeah definitely
@dnolen there’s a weird issue on the code snippets in the module loading blog post
on hover, the word clojure
appears
can you repro?
@anmonteiro yes it’s very strange, haven’t been able to figure that
https://clojurescript.org/css/asciidoctor-mod.css .listingblock:hover code.clojure:before { content: "clojure"; }
And there is another rule above that, which should position this text absolute: .listingblock:hover code[class*=" language-"]:before { text-transform: uppercase; font-size: 0.9em; color: #999; position: absolute; top: 0.375em; right: 0.375em; }
But I think that is not matched because the classes are not named language-
@juhoteperi hrm so what change should I make? I have access to the styles
Why do the code blocks on e.g. guides get language-clojure
class instead of clojure
@dnolen maybe use [source,clojure]
instead of [code,clojure]
but the same is happening on the quick start with XML and you’re using source there I think
@juhoteperi I just removed all those rules
@mfikes yes though I think the wow factor will go up significantly when we point out that we can apply the same trick to ES6 sources w/ static import/exports in our builds 🙂
I took a look at https://rollupjs.org today
yeah, I use Rollup to bundle Lumo’s JS
besides doing static import/export analysis it also does scope hoisting, i.e. doesn’t create a function scope for every module
I think we should refer back to JS tools like this consistently in our coming posts to give people the necessary reference points / context
I’m going to try and edit the JS modules blog post today
I’ll keep that in mind
looks like Google Closure Compiler started taking advantage of multiple threads recently https://github.com/google/closure-compiler/blob/master/src/com/google/javascript/jscomp/PrebuildAst.java#L58
oh nice
I just hope that translates well to JS with GWT
@dnolen btw do you know if Closure has public JavaDoc somewhere?
@dnolen https://github.com/google/closure-compiler/blob/863678d24e5012c9affb97cd41b7b3737bffe4e4/.travis.yml#L18
probably possible to generate
let me try
mvn javadoc:javadoc
works
not sure why they don’t publish it
(had to reset to a working version, it’s currently broken on master)