This page is not created by, affiliated with, or supported by Slack Technologies, Inc.
2020-05-18
Channels
- # announcements (9)
- # atom-editor (29)
- # aws (17)
- # babashka (72)
- # beginners (83)
- # braveandtrue (3)
- # calva (7)
- # cider (16)
- # clj-kondo (15)
- # cljs-dev (146)
- # cljsjs (1)
- # cljsrn (8)
- # clojars (1)
- # clojure (96)
- # clojure-dev (19)
- # clojure-europe (53)
- # clojure-losangeles (1)
- # clojure-nl (3)
- # clojure-spec (7)
- # clojure-uk (235)
- # clojuredesign-podcast (5)
- # clojurescript (81)
- # conjure (73)
- # cursive (7)
- # data-science (1)
- # datomic (5)
- # defnpodcast (8)
- # emacs (3)
- # figwheel-main (34)
- # fulcro (83)
- # graalvm (10)
- # graphql (6)
- # helix (49)
- # jackdaw (3)
- # jobs (1)
- # joker (1)
- # kaocha (1)
- # mid-cities-meetup (10)
- # off-topic (17)
- # pathom (16)
- # re-frame (11)
- # reagent (18)
- # reitit (18)
- # remote-jobs (4)
- # shadow-cljs (63)
- # spacemacs (18)
- # specter (20)
- # sql (17)
- # uncomplicate (1)
- # vim (28)
- # xtdb (32)
Using the new :bundle
with figwheel latest (following the CLJS official guide) I have added firebase
as a dependency in my package.json
{
"devDependencies": {
"webpack": "^4.43.0",
"webpack-cli": "^3.3.11"
},
"dependencies": {
"firebase": "^7.14.4",
}
}
Then I can require the above like this and everything works.
(:require
[firebase])
However, the above will import the entire firebase JS package. I can save some kb by specifying exactly what I need. In JS, it would be this:
import * as firebase from 'firebase/app';
import 'firebase/auth';
What would the equivalent require be like in CLJS? Do we need to specify any additional configuration for the CLJS compiler?Not sure if that’s correct. The closure compiler doesn’t know anything about the internal structure of firebase
, and won’t necessarily be able to do DCE inside that.
That said, it might not even help to express with a limited import either, as problem stays the same
Indeed. My understanding is that what you do in webpack is outside the scope of the GCC.
Normally this is not a problem because all the modules we import through webpack, once set to “production”, will be minified to the same level as everyone else in the JS ecosystem.
The challenge here comes with the fact that commonJS, unless the authors of the library did prep work, will include everything by default without webpack having the ability to eliminate the unused stuffs. There are workarounds in JS land though.
> That said, it might not even help to express with a limited import either, as problem stays the same I believe with the limited import (ES6 modules), you’re able to eliminate all the unused stuffs. But this might only be true for libraries like Firebase which have done the work to make this possible.
Interesting. Are we talking about the same thing? e.g. I have a package like React that is handled by webpack. We’re saying that React
will be run through GCC’s advanced compilation step?
I will have to dig into this a little more, but my understanding is that something like React may already be compiled (to a certain degree) by GCC. This means it would be as small as it can be, yes? I’m not sure why I would try to run any package from the NPM ecosystem + webpack through GCC because it’s my understanding that those packages, in their production builds, are already as small as they can be.
But maybe your point is that is that whether you would run them through GCC is irrelevant and rather that the webpack packages are run through unless you tell the compiler otherwise?
Gotcha! For sure. What you mentioned is what I do during my builds (externs), but I never distinguished the externs and webpack code running through gcc. That’s my bad.
@tkjone ah I was mistaken. It seems that in order to have to have it included within your code's compilation, you need to specify it as a foreign lib to tell the CC about it. I know you can refer to parts of JS libraries like so ["@react-navigation/native" :refer [NavigationContainer]]
, but I don't know if that affects the output size.
So by default packages setup through webpack are not run through GCC, yes?
Is there a way to write this in CLJS for use with the new :bundle
target.
...
export default {
title: 'Foo',
component: FooComponent,
decorators: [ ... ],
parameters: { ... }
}
@olivergeorge should be possible if you write an ES6 file, but not sure if there are issues
@tkjone we only support CommonJS style import - so there's no way to express that - and no plans at least in the near future - would need a lot of thought
@dnolen hmm. I have {:language-out :es6} set now. Adding (js* "export default " SimpleComponent)
but a :simple compile throws ERROR - [JSC_MIXED_MODULE_TYPE] A file cannot be both a goog.provide'd file and an ES6 module.
Yeah, was reaching. Not familiar with how this could/should work.
I'm happy for wait and work with the ^:export
approach for now.
if you just want a prod build that exports some stuff then that's easy, write that stuff in your index.js
Yep, figured that might be how it works.
I was experimenting with getting reagent views to display in Storybook. The webpack guide works.
My approach required referencing a global export which is fine but left me wondering if I was missing a more common approach to importing the component.
import React from 'react';
import '../out/index.js';
export default {
title: 'SimpleComponent',
component: SimpleComponent,
};
export const SimpleComponent = () => <hello_bundler.core.SimpleComponent />;
Repo is here for anyone curious: https://github.com/olivergeorge/webpack-repros/tree/storybook-vs-reagent
I could provide an alternative index.js which imports my component does the "export default ..." to make a cleaner interface
That hides the quirk.
@dnolen gotcha. Curious though: In the https://www.npmjs.com/package/firebase#include-only-the-features-you-need. One example they use seems to be commonjs
var firebase = require('firebase/app');
require('firebase/auth');
require('firebase/database');
but maybe I am misunderstanding their docs.In a scenario like the above (aside from using shadow-cljs), to achieve the smaller packages in production, would the recommended approach be to go back to the previous way of using webpack and ClojureScript?
the important thing isn’t the es6 import stuff, it’s the way they’re referencing the package by path
No such namespace: firebase/auth, could not locate firebase_SLASH_auth.cljs, firebase_SLASH_auth.cljc, or JavaScript source providing "firebase/auth" (Please check that namespaces with dashes use underscores in the ClojureScript file name) in file src/pillar/app.cljs
> the important thing isn’t the es6 import stuff, it’s the way they’re referencing the package by path Totally. This was my thought as well.
Everything else is working with the commonjs style, it’s just that “style” of require.
@dnolen does that seem like something that should be supported? are we doing something wrong?
I likely know answer to this but.. for cljs macros you can’t pre-compile javascript only code, right? (for react native, I was hoping to inline static style props, e.g. `{:style (sh {:flex 1})`, but doesn’t look like that’s possible since the `StyleSheet` is a js object)
@alidcastano not sure what you mean. can you explain what the desired CLJS or JS output is?
@lilactown using Helix, imagine this declaration
(def styles (.create rn/StyleSheet #js {:container #js {:flex 1})
(defnc Foo [] ($ rn/View {:styles (.-container styles))
i’d like to do this
(defnc Foo [] ($ rn/View {:styles (sh {:flex 1}))
where sh
is a macro creating the static styles, so that I can inline them without re-creating them on every component render
but in order to that I need some way to call (.create rn/StyleSheet)
which I imagine isn’t possible. I know I can expand to the appropriate js code but that code wouldn’t be called until component is rendered (?), defeating the purpose.
not sure if there’s some workaround that’d make this possibleokay, so what you want is to “lift” the style creation outside of the form you’ve written the macro in
it’s possible to lift the style creation outside the form with macros, but it seems like just memoizing the call should do what you want:
(def sh (memoize #(.create rn/StyleSheet (clj->js %)))
depending on how many different styles you expect, you may or may not want to limit the maximum size of your cache using something like https://github.com/burbma/cljs-cache
@alidcastano I recommend offloading the code into a helper fn. so you emit (def styles (your-macro-ns/make-stylesheet #js {:container #js {:flex 1}))
and have the make-stylesheet
fn for whatever it needs to call rn/StyleSheet
with this suggestion the styles wouldn’t be inlined, right? it’d just make it easier to create the static styles in cljs outside the component
Hi, I'm 100% sure that this question have been asked before, but after reading documentation, and few answers from google, I'm starting thinking that I don't understand something I have very simple clojurescript project with shadow-cljs.edn config
{:source-paths ["src"]
:dependencies []
:builds {:app {:target :browser
:output-dir "public/js"
:asset-path "/js"
:modules {:main {
:entries [app.core]}}}}}
after shadow-cljs watch app
and shadow-cljs cljs-repl app
I'm getting No application has connected to the REPL server. Make sure your JS environment has loaded your compiled ClojureScript code.
I've opened
in the browser@rafal.wysocki the server running on 9630
is for the internal shadow-cljs UI and websockets. it does not load any of your code. if you want a webserver for your code use :dev-http
https://shadow-cljs.github.io/docs/UsersGuide.html#dev-http
if you just want a browser repl use shadow-cljs browser-repl
but that also won't load any of your code unless you (require 'app.core)
it and use it that way
@thheller thanks, it's working now, I think it should be more explicitly mentioned in the docs
it is mentioned here https://github.com/thheller/shadow-cljs#quick-start if you want something shorter 😛
Hey! Is it possible to use SCSS
with shadow-cljs
live reloading?
@marodriguez if you start a scss watcher, shadow-cljs will hot reload changes to your CSS files
@lilactown thanks, in that case I would need to start a scss watcher and a shadow watcher right? I was thinking of a plugin/config to add the scss watcher into the shadow one.
Any suggestions?
there might be a JVM scss watch that you could start in your shadow-cljs process, I’m not sure
there are many options to run multiple things for you. shadow-cljs does not need to do that.
Will check it out thanks. I come from React/Angular/Vue and all of them have like scss out of the box. Maybe there was like a recommended way of doing it.
I’m trying to build a clj+cljs library (using deps.edn
and cljx) and I’m looking for guides on how to set up and organize everything, and/or other libraries that I can look at for inspiration. Does anybody have any recommendations? (Sorry in advance if this is the wrong place to ask!)
cljx is deprecated, cljc offers the functionality and is built into clojure itself
You can read the guide on Clojure Cli on the official website or shadow cljs readme