Fork me on GitHub
#clojurescript
<
2016-09-10
>
jiangts06:09:04

i'm trying to compile a project that has macros under src/clj and clojurescript under src/cljs

jiangts06:09:26

it works in lein-cljsbuild as I can specify multiple :source-paths, but I can't figure out how to run it with the normal build api

jiangts06:09:38

when I (require '[cljs.build.api :as b]), and (b/watch "src" ...), I get an error saying java.io.FileNotFoundException: Could not locate utils/helpers__init.class or utils/helpers.clj on classpath

jiangts06:09:55

any insight on how lein-cljsbuild combines sources from multiple paths for compilation? not using lein-cljsbuild since I have a lot of foreign deps that I can't require across a bunch of different builds I have without repeating myself a bazillion times due to limitations in lein

jiangts06:09:55

wait a second, even putting the .clj files into the cljs directory doesn't solve the problem

Jeremie Pelletier10:09:01

@jiangts are you missing a :source-paths for clojure (not clojurescript) as well in your project.clj?

yury.solovyov18:09:19

can I somehow stop lein from polluting target/ dir with it's stuff? or it is totally ok to just output to different dir?

yury.solovyov18:09:36

i only need main and renderer

yury.solovyov18:09:03

project.clj is

(defproject eion "0.1.0-SNAPSHOT"
  :description "FIXME: write description"
  :url ""
  :license {:name "MIT"
            :url ""}
  :dependencies [[org.clojure/clojure "1.8.0"]
                 [org.clojure/clojurescript "1.9.229"]]

  :plugins [[lein-cljsbuild "1.1.4"]]

  :cljsbuild {
    :builds [{
      :source-paths ["src/eion/main"]
      :compiler {
        :output-to "target/main/core.js"
      }
    } {
      :source-paths ["src/eion/renderer"]
      :compiler {
        :output-to "target/renderer/core.js"
      }
    }]
  })

darwin18:09:50

@yury.solovyov you can specify :output-dir and :output-to to point to an independent directory, I tend to point them into resources/public/_compiled so they are visible by my dev web server

yury.solovyov18:09:46

now I have a different problem

yury.solovyov18:09:19

files that are coming out are not actually complete bundles

yury.solovyov18:09:34

they refer to goog ns

yury.solovyov18:09:57

I need to somehow embed this info

darwin18:09:45

I don’t understand, can you gist your produced :output-to file?

darwin18:09:56

also I would recommend you to not use vector in :cljsbuild > :builds but a map instead, using vector prevents further composing via lein profiles feature

yury.solovyov18:09:54

I think this is somewhat typical error

darwin18:09:40

(advice) I tend to explicitly declare empty :cljsbuild :builds at the root level, and then use profiles to “merge” ad-hoc configurations, and usually prepare common configurations via aliases. see the example here: https://github.com/binaryage/cljs-oops/blob/master/project.clj#L37

yury.solovyov18:09:45

yup, but let me just get started first 🙂

yury.solovyov18:09:08

replaced array with map

darwin18:09:10

from the gist it looks like you are not using :main, this is a quirk in the cljs compiler in my opinion, :advanced and :none modes behave completely differently depending if :main was provided or not

yury.solovyov18:09:04

you mean main in build maps?

darwin18:09:25

you have to specify :main if you want to get “bootable” script out: https://github.com/clojure/clojurescript/wiki/Compiler-Options#optimizations

darwin18:09:02

in other case you have to include goog/base.js prior your script and then manually goog.require your main namespace(s) after

yury.solovyov18:09:15

actually, output chanesg as soon as I changes output

yury.solovyov18:09:25

I'll make a gist

darwin18:09:00

ok, optimizations :simple behave like :advanced, :output-to will be a “bootable” script

darwin18:09:55

in case of :none optimizations (which is the default AFAIK), you will get just a script with dependencies and you have to some manual work as I described above

darwin18:09:09

given :main wasn’t provided

yury.solovyov18:09:45

:main key maps to ns right?

darwin18:09:53

yes, now it should work for you

darwin18:09:16

core.js will be a self-contained “bootable” script, which won’t depend on some prior setup

darwin18:09:51

and changing it to :none, will work as well, without changing your html file

yury.solovyov19:09:37

it works, but throws an error now cljs.core/*main-cli-fn* not set, I guess I need to use some repl?

darwin19:09:51

(enable-console-print!)

darwin19:09:26

or is it under node?

stbgz19:09:45

hey guys so I am running into some problems when using transducers and NodeJS calls. if I understand correctly transducers expect their functions to return synchronosly, but a lot of the NodeJS calls are themselves an async call that return a channel. Does any one have any experience unsing transducers with NodeJS API?

darwin19:09:49

your question should be transducers + core.async, and answer is “they should play well"

darwin19:09:07

or is your nodejs api using plain callbacks?

darwin19:09:17

@yury.solovyov you have set main-cli-fn to some function, it will be called as your command-line app entrypoint

stbgz19:09:02

nodejs is using plain callbacks, which I am pushing the results through a channel

darwin19:09:00

and you want to apply a transducer on that channel?

stbgz19:09:33

yes to the returning channel

darwin19:09:04

if you already have a transducer, you can create your returning channel with transducer applied, xform param here: https://clojuredocs.org/clojure.core.async/chan

darwin19:09:56

if you don’t have transducer and want to apply a simple transformation function, you can just wrap your resulting channel in a core.async/map: https://clojuredocs.org/clojure.core.async/map

yury.solovyov19:09:32

@darwin thank you, I've managed to get everything working

stvnmllr220:09:53

new to clojurescript. I have data in a clojurescript datastructure on the client. And now want to save it somewhere on the server. What's a simple way? serialize to json on client? or use some other format/transport. Not sure if EDN would be easier if i want to use the same structure on the server. To avoid the double serialization. Any tips appreciated. otherwise i'll power through. thanks

darwin20:09:38

if you have clojure on the backend, I would recommend: https://github.com/cognitect/transit-clj

stvnmllr220:09:42

ok. thanks. Started looking at those.

stvnmllr220:09:36

And should i even try to get figwheel and my compojure handlers running on the same port?

darwin20:09:10

don’t have experience with compojure, but figwheel definitely needs its own port

stvnmllr220:09:38

it's own nrepl port right? But diff http port? haven't read all the figwheel docs yet to see

darwin20:09:10

nrepl port, figwheel port and your dev http server ports must differ

darwin20:09:36

figwheel port is the port where figwheel file-system watcher notifies client in the browser that it should reload something

stvnmllr220:09:46

ok. thanks. so i'll start up two processes, and work on that whole CORS prevention.

darwin20:09:41

ah, you want to reuse fighweel http server to serve your app?

darwin20:09:50

I would not recommend it

darwin20:09:23

btw. and the CORS problem of figwheel http server is already resolved if I remember correctly

darwin20:09:37

never bumped into the issue myself

stvnmllr220:09:21

ok. thanks for the advice. Ok. not sure if it's a problem with figwheel. might be the ajax lib i used. didnt' like requesting something on 3000 with figwheel ui on 3449

yury.solovyov21:09:46

@darwin is there any special plugin I need to install to support sourcemaps? I can't see the mapping file to be generated at all https://gist.github.com/YurySolovyov/16fdcec3fe39765e439b8dd8d55b6ca1

yury.solovyov21:09:13

I tried setting :source-map-path and :asset-path

yury.solovyov21:09:39

d'oh, it seems like lein cached compiled files all this time and didn't reported any errors, but whn I changed file, I now see them

yury.solovyov21:09:51

can I just somehow have core.js.map and not all the other dirs there?

darwin21:09:32

my understanding is that source maps are generated by default and their location is determined by :output-dir in :none mode, and :output-to in all other modes

darwin21:09:15

so in your case of :simple optimizations, just point :output-dir into some temp folder and you get only core.js and core.js.map as your resources

darwin21:09:42

(I speculate here)

yury.solovyov21:09:54

yeah, it seems to be a hard requirement here:

Compiling "out/main/core.js" failed.
java.lang.AssertionError: Assert failed: :output-dir "/media/yury/MYMEDIA/Projects/eion-clojurescript/target/cljsbuild-compiler-0" must specify a directory in :output-to's parent "/media/yury/MYMEDIA/Projects/eion-clojurescript/out/main" if optimization setting applied
(or (nil? (:output-to opts)) (:modules opts) (same-or-subdirectory-of? (absolute-parent output-to) output-dir))

yury.solovyov21:09:56

maybe just copy it as build step?

yury.solovyov21:09:07

but this would be brittle

darwin21:09:23

ah, ok, yes post-build step is always a solution, but I think there must be a better way

darwin21:09:58

but if you want working source maps you will need those output-dir files

darwin21:09:04

there are cljs versions of your sources

yury.solovyov21:09:44

I'm ok with having them, but I need some way to extract relevant files afterwards to distribute the app

darwin21:09:22

yes, that is another story, I would recommend a plain shell script if you are under an unix system

yury.solovyov21:09:00

if I'm into shell scripts, I'd better just copy the source map

darwin21:09:47

a tip: I tend to use lein-shell plugin to allow executing arbitrary shell files from lein aliases, it is pretty flexible

yury.solovyov21:09:11

why not just allow users to provide their own paths?

darwin21:09:58

in general case your cljs compiler could produce multiple js files, see :modules feature

darwin21:09:48

that is why you configure it via directory locations and not by specifying a single path

darwin22:09:14

now when I’m reading the docs, you can specify a path to source map: https://github.com/clojure/clojurescript/wiki/Compiler-Options#source-map

darwin22:09:48

under :simple optimizations you actually must specify a path

yury.solovyov22:09:55

yes, it does not work

yury.solovyov22:09:05

will try modules

darwin22:09:05

in case you don’t want to rely on default location

darwin22:09:16

no don’t do modules if you don’t need them

yury.solovyov22:09:10

I tried setting the path like :source-map "out/main/core.js.map" and it does not work without setting the dir

darwin22:09:17

I’m sorry, cannot help without actually going and trying it myself

darwin22:09:48

can you share the project? I could run it here and maybe fix your config

darwin22:09:11

after some tinkering with yury’s config I’ve found the culprit: yury decided to point output files produced by cljs compiler into custom “out” folder, but he didn’t instruct leiningen to clean it when issuing lein clean. this probably coupled with aggressive caching in cljs compiler, so when he was tinkering with the project.clj and re-running lein cljsbuild once <build-id>, the changes didn’t take effect (because misconfigured out dir was still present from previous builds) - this puzzled me at first too, but I have the basic survival experience from clojurescript world: "if it does not work, kill it with fire and start from scratch"

yury.solovyov22:09:52

yup, I guess I'll just make another release task to make it packaging-ready bundle

darwin22:09:24

np, good luck!

yury.solovyov22:09:40

also changed out to output

darwin22:09:06

don’t forget to update :clean-targets as well