Fork me on GitHub
#shadow-cljs
<
2018-03-01
>
hlolli01:03:44

For emacs users to try: https://gist.github.com/hlolli/d8a28c88ee90c5a57d15299f21528030 the magic is in the function shadow-cljs-jack-in I can start on my computer browser-repl node-repl and start watch and have cider connect to it without doing anything (like pressing enter twice). Only problem being the possibility of creating these ghost java processes. Deleteing .shadow-cljs directory most often fixes it. Assumes shadow-cljs v2.2.20+, the emacs package edn (melpa/elpa) and cider/cider-nrepl as declared dependency within shadow-cljs.edn.

donmullen12:03:03

Thanks @hlolli - do you have sample shadow-cljs / project.clj / .dir-local.el files to share? I’m just ramping up on all these - would be helpful. Some people have been using .dir-local.el to kick off shadow-cljs - I’m assuming using this gist would replace that. Also - I’ve run into CIDER not loading cider/cider-nrepl — and think I’m not putting it in the right place. Where specifically should that reference live?

hlolli12:03:26

no but I can set up one, just need to be in a buffer where a shadow-cljs.edn file is in the root. This does script does not take leiningen into account, and no need to .dir-local.el/projectile like I saw here recently. If you have cider-nrepl in :dependencies within shadow-cljs.el, it should fire the nrepl connection automatically.

{:dependencies
 [[cider/cider-nrepl "0.17.0-SNAPSHOT"]
:nrepl {:port 9000
         :middleware []}
...}
This I have on top level.

donmullen12:03:12

Got it - thanks @hlolli. For cljs/clj dev (with clj repl for server side) - do you just use regular cider-jack-in or cider-connect for that?

hlolli12:03:21

yup, I just start a ring handler to serve the cljs-output directory and do my server side stuff with cider-jack-in, which picks up the project.cljs. (and in terminal I have shadow-cljs watch .. running) But I guess this could be simplified as well, there is to say get the autocompletions from both clj and cljs, thinking about it I didn’t test two nrepl connections, so things may get strange. I’ll try adding lein function tonight and let you know!

hlolli12:03:23

Ring handler as in, this typical commented section at the bottom of the main ring handler file (comment (defonce server (run-jetty … etc…)))

hlolli15:03:36

The node-repl had stupid bug there, which I fixed https://gist.github.com/hlolli/d8a28c88ee90c5a57d15299f21528030 plan to move this to a git...

cmal03:03:21

Hi, I defined a SomeGlobalObj in a.js and use SomeGlobalObj in b.js , I generated a a-externs.js file for *a.js* and add to shadow-cljs.edn :compiler-options, but when do advanced compilation, there is a warning says variable SomeGlobalObj is undeclared for b.js. How to fix this?

shaunlebron03:03:01

👋 I’m using the :target :node-library to get a UMD api that works in both node and the browser

shaunlebron03:03:11

for example, var Foo = require("foo") in node, or just window.Foo in the browser if you’re just including the JS file in a script tag without a build system

shaunlebron03:03:01

but currently, I have to use window.returnExports instead of window.<my-lib-name> because this is hard-coded into the UMD template that shadow uses here: https://github.com/thheller/shadow-cljs/blob/master/src/main/shadow/build/targets/umd_exports.txt#L7

shaunlebron03:03:21

@thheller this should probably be a build option, maybe under :umd-root-name "Foo"?

shaunlebron03:03:05

sorry, this should a github issue, i’ll file and link here

tianshu09:03:28

@thheller When use emacs cider, people usually quit with cider-quit command, this is not normal quit behavior for shadow-cljs.

thheller09:03:15

@doglooksgood can you please dig up the source of cider-quit so I can look at what it actually does and see if I can do something about it?

tianshu09:03:06

It use emacs built-in function delete-process, which send signal SIGHUP.

tianshu09:03:21

it is mentioned: Function: delete-process name This function deletes the process associated with name, killing it with a SIGHUP signal. The argument name may be a process, the name of a process, a buffer, or the name of a buffer. is it possible to handle this signal?

thheller09:03:29

the quesion is which process gets this signal

thheller09:03:39

probably the node process

thheller09:03:51

I'll look into what happens exactly

tianshu09:03:50

I think nrepl will receive

hlolli10:03:40

I think one solution would be to add all of the processes https://github.com/thheller/shadow-cljs/blob/b107bafc2c20b07af580e3f7deaa1434f54b0022/src/main/shadow/cljs/npm/cli.cljs#L56 into a atom, and catch the SIGHUP signals, kill these processes, and then exit.

hlolli10:03:21

@doglooksgood did you do your own shadow-cljs startup script in emacs? I could have maybe saved one evening by useing yours instead of makeing my own 😛

tianshu10:03:40

😂sry, I still don't know how to solve this. @hlolli

hlolli10:03:02

did you try https://gist.github.com/hlolli/d8a28c88ee90c5a57d15299f21528030 ? I believe we are haveing the same problem.

tianshu11:03:21

Let me take a look

thheller11:03:27

@hlolli I agree but spawnSync doesn't return until the process it spawned dies so I need to switch to spawn first

thheller11:03:02

turning sync code into async unfortunately requires a little more thought

thheller11:03:22

I'll look into it later

thheller11:03:41

btw given the state of lein dependence in most tools such as cider I would probably recommend just running through lein

thheller11:03:20

bbiab, grabbing food

tianshu11:03:23

@thheller I think the source map patch in re-natal is this: https://github.com/drapanjanas/re-natal/pull/102/files no need to patch in shadow-cljs

tianshu11:03:12

@hlolli this script works with lein + shadow-cljs?

tianshu11:03:11

have you tried stop the build before quit?

hlolli12:03:13

@doglooksgood no it just handles the shadow-cljs boot, cider boot and nrepl-select automatically. I guess with leiningen/shadow-cljs setup you don't need to boot shadow-cljs yourself. But I've never integrated shadow-cljs and leiningen, since they work perfectly seperately (within the same project).

mhuebert12:03:19

i am walking down a troubled road trying to get monaco-editor-core loading in cljs

mhuebert12:03:52

their loader has this OS detection which assumes it is not in a browser so long as there is a global process object

// OS detection
if (typeof process === 'object') {
	_isWindows = (process.platform === 'win32');
	_isMacintosh = (process.platform === 'darwin');
	_isLinux = (process.platform === 'linux');
	_isRootUser = !_isWindows && (process.getuid() === 0);
	let rawNlsConfig = process.env['VSCODE_NLS_CONFIG'];
	if (rawNlsConfig) {
		try {
			let nlsConfig: NLSConfig = JSON.parse(rawNlsConfig);
			let resolved = nlsConfig.availableLanguages['*'];
			_locale = nlsConfig.locale;
			// VSCode's default language is 'en'
			_language = resolved ? resolved : LANGUAGE_DEFAULT;
		} catch (e) {
		}
	}
	_isNative = true;
} else if (typeof navigator === 'object') {
	let userAgent = navigator.userAgent;
	_isWindows = userAgent.indexOf('Windows') >= 0;
	_isMacintosh = userAgent.indexOf('Macintosh') >= 0;
	_isLinux = userAgent.indexOf('Linux') >= 0;
	_isWeb = true;
	_locale = navigator.language;
	_language = _locale;
}

mhuebert12:03:37

I can get it to work if I include monaco’s loader.js in its own script tag, and (js-delete js/self "process") before I instantiate it

mhuebert12:03:50

i was wondering if shadow depends on this process object at runtime

mhuebert12:03:04

it looks like it is just a set of empty stubs

mhuebert12:03:29

I wonder what things will break if it’s not there

thheller13:03:02

@mhuebert the last time I tried monaco-editor it wasn't packaged in a way that was usable with any bundler (without heavy config)

thheller13:03:27

did they change that?

mhuebert13:03:29

yes it looks like a __

mhuebert13:03:01

i think its still awkward, there appear to be people who have found workarounds

thheller13:03:17

ah monaco-editor-core is some kind of custom package

mhuebert13:03:19

i am thinking i can just use it with their loader and not bundle it

thheller13:03:32

yeah that was my conclusion the last time

mhuebert13:03:55

i just want to make sure that deleting js/process won’t screw up anything else

thheller13:03:51

oh it definitely will screw up everything that uses it

thheller13:03:36

many packages either check process.browser or process.env.NODE_ENV

thheller13:03:50

while NODE_ENV will be inlined and optimized away

thheller13:03:27

there might be other process.env accesses that won't be

thheller13:03:20

there are several issues in their github issues complaining about this

thheller13:03:28

but they don't seem to be interested in fixing it

thheller13:03:37

(the package that is)

mhuebert13:03:24

I can do something horrible like this:

(defn require [paths cb]
  (let [process (.-process js/self)]
    (js-delete js/self "process")
    (js/require (clj->js paths)
                (fn [result]
                  (set! (.-process js/self) process)
                  (cb result)))
    nil))
if it so happens that no other code attempts to read js/process during the span of time before require calls its callback

thheller13:03:51

require? are you in node?

thheller13:03:12

dynamic require means it won't be provided by shadow-cljs

mhuebert13:03:55

no that is using monaco’s loader

mhuebert13:03:00

which supplies a global require

mhuebert13:03:28

i include it via a separate script tag, eg <script src="/js/monaco/vs/loader.js"></script>

thheller13:03:03

ah. it fails because I create the process as a global

thheller13:03:12

thats totally unnecessary. I can remove that

thheller13:03:22

I thought you were inside something shadow-cljs bundled

thheller13:03:31

where process must exist

mhuebert13:03:34

so there aren’t other things that use process at runtime

thheller13:03:36

it must not exist as a global though

thheller13:03:07

there are but I can isolate the scope of process so it doens't become global

cmal13:03:55

Hi, I define a SomeGlobalObj in a.js , use SomeGlobalObj in b.js , generate a a-externs.js file for *a.js* and add to shadow-cljs.edn :compiler-options, but when do advanced compilation, there is a warning says variable SomeGlobalObj is undeclared for b.js. How to fix this?

thheller13:03:01

what do the externs look like?

thheller13:03:13

are you sure they are used?

cmal13:03:55

var SomeGlobalObj = {
  "invoke": function () {},
  "on": function () {}
}

cmal13:03:32

They are used because the invoke and on are not changed anymore.

thheller13:03:34

and the :compiler-options {:externs ["path/to/externs.js"]}?

cmal13:03:56

:compiler-options {:externs ["./weixin-externs.js"]}

thheller13:03:19

the externs file is in the project root?

cmal13:03:07

yes. At first I got some error because compiler renamed on and invoke, then I add the externs and the error not come out again.

thheller13:03:28

is it a ES6 .js file?

cmal13:03:19

Not sure I will check it.

cmal13:03:12

No, neither file is ES6.

thheller13:03:47

the files are not part of the shadow-cljs build?

cmal13:03:03

a.js is not, b.js is imported into cljs

thheller13:03:31

how do you access SomeGlobalObj in the js?

cmal13:03:25

bare use, just SomeGlobalObj.

cmal13:03:57

function handleFontSize() {

    WeixinJSBridge.invoke('setFontSizeCallback', { 'fontSize' : 0 });

    WeixinJSBridge.on('menu:setfont', function() {
      WeixinJSBridge.invoke('setFontSizeCallback', { 'fontSize' : 0 });
    });
  }
here WeixinJSBridge is SomeGlobalObj.

thheller13:03:12

ah. when do you get the warning?

cmal13:03:30

when I run shadow-cljs release app

cmal13:03:12

shadow-cljs - config: /Users/yuzhao/gits/mobile/cljs/shadow-cljs.edn version: 2.1.4
shadow-cljs - connected to server
[:doumi] Compiling ...
------ WARNING #1 --------------------------------------------------------------
 File: com/cognitect/transit.js:649:8

 variable module is undeclared
--------------------------------------------------------------------------------

------ WARNING #2 --------------------------------------------------------------
 File: com/cognitect/transit/impl/writer.js:256:8

 variable isObject is undeclared
--------------------------------------------------------------------------------

------ WARNING #3 --------------------------------------------------------------
 File: com/cognitect/transit/types.js:384:70

 variable Buffer is undeclared
--------------------------------------------------------------------------------

------ WARNING #4 --------------------------------------------------------------
 File: doumi/autorem.js:13:4
 variable WeixinJSBridge is undeclared
--------------------------------------------------------------------------------

nil
[:doumi] Build completed. (713 files, 3 compiled, 0 warnings, 28.53s)

thheller13:03:01

the code does work though right?

cmal13:03:20

yes, it works.

thheller13:03:44

my guess is that is complains about the variable because the .js file is not in the global scope

thheller13:03:58

its wrapped in a function

thheller13:03:14

unlike the CLJS/goog code which is in the global scope

thheller13:03:53

does the file have any require or exports?

cmal13:03:33

var autorem = function (...) {...}
module.exports = autorem;

thheller13:03:54

what you can try is turn the file into ES6

thheller13:03:15

export default autorem;

thheller13:03:44

and then in the cljs (:require ["./autorem" :default autorem])

thheller13:03:01

when the file is processesd as ES6 it is lifted into the global scope

thheller13:03:09

which might make the warning go away

thheller13:03:14

otherwise just ignore the warning

cmal13:03:31

OK. Thanks!

thheller13:03:13

although you might just get the warning in a different place then

thheller13:03:28

I'm not sure why it complain if there are externs

thheller13:03:50

but its a closure warning so I can't do much about it

thheller13:03:01

except always disabling the warning but that sounds like a bad idea

cmal13:03:18

OK. :thumbsup:

mikerod14:03:54

I was a bit curious on some background info on shadow-cljs. Is the goal to just be a divergent “fork” of cljs as it is right now? Are there thoughts or plans around merging compiler fixes/changes into the main cljs etc. I haven’t found a “rationale” sort of discussion on this from waht I’ve seen.

mikerod14:03:28

I was just reading a bit through the codebase yesterday and was wondering where it is supposed to be headed. Looks like a cool project though by the way!

thheller15:03:14

I have no intent of merging any of the build specific stuff into CLJS and neither does have CLJS any interest in doing so.

thheller15:03:30

I see it as a build tool which should not be part of the language itself

thheller15:03:35

just like lein is not part of clojure

thheller15:03:18

I can move much faster and try many more things which would otherwise be impossible or reaallly slow when done in official CLJS

thheller15:03:37

when I find things that actually affect the compiler itself I usually submit patches and they usually get accepted

thheller15:03:04

it is good that CLJS moves so slow and is very careful when adopting new things

thheller15:03:45

just sometimes frustrating when you want to build new things 😉

thheller15:03:31

the goal is simple and hasn't changed. it should be a good build tool for CLJS.

mikerod15:03:23

Thanks @thheller that is some helpful insight indeed.

thheller15:03:08

https://dev.clojure.org/jira/browse/CLJS-948 started in shadow-cljs before it came part of standard cljs

thheller15:03:13

as did :modules

thheller15:03:32

so maybe its some kind of idea testing facility as well 😉

thheller15:03:57

the good stuff should all eventually make it into core

hlolli15:03:57

@thheller :include-macros true is in the core?

thheller15:03:43

that didn't come from shadow-cljs. that was there from the beginning

hlolli15:03:27

hmm ok, maybe I saw this in the wild way back. Never mind, struck me as something new 🙂

thheller15:03:29

that you no longer need it in most cases was the new thing 😉

thheller16:03:55

@mhuebert [email protected] doesn't leak the process global anymore

Jon16:03:27

I'm still in hope that shadow-cljs may get a release page like Webpack's, given that we have so many releases https://github.com/webpack/webpack/releases ╮(╯▽╰)╭

thheller16:03:47

I tried that before ... you know how it ended ...

thheller16:03:41

the changelog?

Jon16:03:59

too early. I didn't know how it ended at last.

thheller16:03:41

just look at the commit history thats pretty much the release log 😉

Jon16:03:02

releases is different, when you release a new version, if I'm watching the repo, I would get notified of new releases.

Jon16:03:33

I don't think so.. 2 reasons,

Jon16:03:54

1) I can't see versions in your commits,

Jon16:03:37

2) in a commit you can't add a link to some docs in User Guide.

thheller16:03:48

I know a release log would be nice but I just can't currently. got too much other stuff on my list already. I might be up for an automated solution but I don't know any so for now there isn't anything

thheller16:03:48

upgrading is also optional if you don't have any issues

thheller16:03:00

so no need to always be on the latest version

Jon16:03:30

made me curious.. I think adding a release note only takes tens of seconds.

thheller16:03:09

maybe if you have a workflow for it .. I don't.

Jon16:03:16

Click "New Release" button, write version number, a title, add a line or two of descriptions... won't take long.

Jon16:03:41

no workflow, just use GitHub.

Jon16:03:54

we don't need release notes as long as Webpack anyway, I guess most of updates, since they are mostly bug fixes, should be less than 5 lines.

Jon17:03:16

some of mine are really short. and GitHub generates a page for commits since last release https://github.com/Respo/respo/compare/0.8.13...master

thheller17:03:26

@jiyinyiyong I understand. Still no.

thheller17:03:04

if you want short messages read the commit log. last commit will almost always reflect what you get with npm install

Jon17:03:12

okay, ╮(╯▽╰)╭

thheller17:03:34

I don't have infinite amount of time to do this stuff

Jon17:03:46

how about just adding version after this "bump"?

Jon17:03:27

Concerns on my side might be different from yours. New commits are adding to shadow-cljs. Following the release notes would be the simplest way for me to keep updated with changes in shadow-cljs. In theory by reading messages in this channel I would keep myself updated. But I don't have enough time to read so many messages either.

Jon17:03:00

1a.m. already. bye..

hlolli20:03:12

Thomas, you mentioned few weeks ago that you implemented an experimental feature of require-ing bundled in js jar file. Does it mean that I can do an override like this

:resolve {"mylib" {:target :file
                  :file "jar:file:/lib/some.jar!/mylib.js}}
bit sorry I didn't try to do this immediately, was stuck with other project and the @logbot hasn't published logs for this channel since last year.

thheller20:03:46

@hlolli just (:require ["/path/to/mylib.js" :as x]) abs path being on the classpath

thheller20:03:30

(:require ["/mylib.js" :as x]) in your case. but be careful with files like that. everything on the classpath should be properly namespaced.

hlolli20:03:08

BINGO, the slash without dot did it!

thheller20:03:27

./ is relative to the current file

hlolli20:03:35

makes sense

thheller20:03:36

/ is from any classpath root

hlolli20:03:59

added lot of goog symbol and all kinds of jars, now cleanup... but yeh, very nice!