Fork me on GitHub
#shadow-cljs
<
2017-10-02
>
Jon05:10:42

The required namespace "cljsjs.highlight" is not available, it was required by "respo_markdown/main.cljs".

Jon05:10:10

any changes to cljsjs packages?

Jon05:10:46

meanwhile there are quite some errors when I switched to highlight.js from npm.

Jon05:10:49

Oct 02, 2017 1:47:40 PM com.google.javascript.jscomp.LoggerErrorManager println
SEVERE: node_modules/highlight.js/lib/languages/actionscript.js:1: ERROR - required "shadow.js" namespace never provided
goog.require("shadow.js");shadow.js.provide("module$node_modules$highlight_js$lib$languages$actionscript", function(require,module,exports) {module.exports = function(hljs) {
^^^^^^^^^^^^^^^^^^^^^^^^^

Oct 02, 2017 1:47:40 PM com.google.javascript.jscomp.LoggerErrorManager println
SEVERE: node_modules/highlight.js/lib/languages/ada.js:1: ERROR - required "shadow.js" namespace never provided
goog.require("shadow.js");shadow.js.provide("module$node_modules$highlight_js$lib$languages$ada", function(require,module,exports) {module.exports = // We try to support full Ada2012
^^^^^^^^^^^^^^^^^^^^^^^^^

Oct 02, 2017 1:47:40 PM com.google.javascript.jscomp.LoggerErrorManager println
SEVERE: node_modules/highlight.js/lib/languages/apache.js:1: ERROR - required "shadow.js" namespace never provided
goog.require("shadow.js");shadow.js.provide("module$node_modules$highlight_js$lib$languages$apache", function(require,module,exports) {module.exports = function(hljs) {
^^^^^^^^^^^^^^^^^^^^^^^^^

Jon06:10:26

for highlightjs issue, I end it up with https://cdnjs.com/libraries/highlight.js ...

thheller08:10:52

I’ll check why highlight.js doesn’t work

thheller08:10:12

I think their packaging is weird

thheller08:10:07

should be fixed in 2.0.5. it is not ideal to use their npm package since that will unconditionally include support for ALL languages

thheller08:10:32

probably best to build your own via https://highlightjs.org/download/

thheller08:10:39

and include that instead

thheller08:10:06

you can include any .js files via

thheller08:10:56

:js-options
   {:resolve
    {"highlight.js"
     {:target :file
      :file "lib/highlight.pack.js"}}}

thheller08:10:25

so whenever you ["highlight.js" :as hljs] in your code, it will include that file

thheller08:10:44

but does matter for now the npm package should work, its just bigger than it needs to be

Jon10:10:57

Now I think CDN is a better choice for highlight.js ...

Jon10:10:27

building highlight.js locally is much more hard to maintain

thheller10:10:23

well not much more work than using a CDN really

Jon10:10:23

so huge...

Jon10:10:04

I guess I have to open another repo if I want to maintain my own bundle

Jon10:10:36

how would you build highlight.js BTW?

thheller10:10:29

added the languages I want and done

Jon10:10:30

...and save it locally in the same project?

Jon10:10:59

well, sound cool... just I don't want to include it in my repo

thheller10:10:02

uses highlight.js 😉

thheller10:10:25

I don’t know what the webpack world does

thheller10:10:34

probably some kind of custom management as well

thheller10:10:48

its really the way the highlight.js package is built

thheller10:10:56

cljsjs is actually quite nice in this case

Jon10:10:12

well, on your blog, it's just highlight.js

thheller10:10:13

but I can’t add support for :foreign-libs without creating more issues than its worth

thheller10:10:37

yeah it is. but its probably the way I would use it in a CLJS project as well

thheller10:10:51

since its really just a library, it doesn’t interact with anything else

Jon10:10:52

you are right about highlight.js , no idea how we custom build that in Webpack

Jon10:10:13

I think putting it on my server would be slow

Jon10:10:17

CDN is way faster

thheller10:10:02

but CDN doesn’t have the customized package

thheller10:10:13

so you probably need more than one request

thheller10:10:24

which probably makes it slower

thheller10:10:34

depends on the number of languages you want to support

Jon10:10:51

fixing my example

thheller10:10:14

given that it will probably be updated very infrequently I think the manual build is fine for now

thheller10:10:48

I do like what cljsjs has done in this case

Jon10:10:12

well....

thheller10:10:15

but that is basically just a custom build 😉

Jon10:10:25

I was wrong

thheller10:10:35

add hljs.initHighlightingOnLoad; to an externs file

thheller10:10:46

assuming thats what you are calling

Jon10:10:34

actually I never managed to create an extern file before

Jon10:10:47

tried when using Boot, but failed

thheller10:10:00

you create a file with whatever name

Jon10:10:24

how does shadow-cljs discover that file?

thheller10:10:36

basically like that file

thheller10:10:00

for every name that is “foreign” you add a property

thheller10:10:19

X.prototype.initHighlightingOnLoad; in your case

thheller10:10:28

the X is not ideal but it works

thheller10:10:38

that file you include in your build via

Jon10:10:42

hot how is it recognized by the compiler?

thheller10:10:10

so :compiler-options {:externs ["path/to/file.js"]}

thheller10:10:58

shadow-cljs check your-build should tell you that initHighlightingOnLoad is an unknown property

thheller10:10:02

which means it needs externs

Jon10:10:23

sounds cool..

thheller10:10:26

externs basically just tell the closure compiler about names it is not allowed to remove or rename

thheller10:10:47

I’m still working out the details on how to generate that automatically

thheller10:10:09

the danger is in overly generic externs since they might prevent code from being removed that you weren’t actually using

thheller10:10:21

which is why shadow-cljs check exists

Jon10:10:45

is it really possible to generate externs automatically

Jon10:10:06

in theory...

thheller10:10:57

generating them yes, ensuring that they are accurate no

thheller10:10:49

the problem is that externs prevent any kind of optimization

thheller10:10:59

so if you generate too much thats bad for filesize

thheller10:10:05

if you generate too little you get errors

thheller10:10:25

both bad … but at this point I’d rather generate too much than deal with errors 😉

Jon10:10:51

first make it work, second make it performant~

thheller10:10:05

it does work … manually 😉

Jon10:10:00

externs it's like magic. - -

Jon10:10:21

it's so strange, I tried it before but it didn't work

Jon10:10:00

how about code like event.target? I notice Closure Compiler optimizes that too?

thheller10:10:17

default externs cover that

thheller10:10:31

it has built-in externs for all the web standards stuff

Jon10:10:26

I mean, when I access a DOM Element, define a local variable, and use (.-x el) to access it

Jon10:10:42

the code is optimized, and it was broken

thheller10:10:25

then it wasn’t target? or the Closure Compiler thought it was not of type Event and renamed it

Jon10:10:41

I guess so.

thheller10:10:06

ah no I misunderstood

Jon10:10:29

I never really understood how externs work though.

thheller10:10:30

you can’t just define .-x

thheller10:10:15

but anyways .. externs are really simple … it is just external names really. so if the closure compiler find a name it doesn’t recognize it know what to do with it

Jon11:10:53

like variables that can be accessed from global? (not local variables?)

thheller11:10:45

local variables do not need externs since they are always safe to rename

thheller11:10:55

I assume you mean property?

Jon11:10:00

but not properties..

thheller11:10:52

see you example. it didn’t recognize hljs.initHighlightingOnLoad so it renamed it to hljs.Qc

thheller11:10:19

it didn’t rename hljs since it is a bit less aggressive with global vars

Jon11:10:24

while hljs is actually window.hljs...

thheller11:10:44

but properties on global vars will be renamed

Jon11:10:41

except for ones with externs...

thheller11:10:56

yes, exactly

thheller11:10:23

externs are the big stop sign that says “do not rename this”, “do not delete this”.

Jon11:10:33

right...

Jon11:10:03

but still, for local variable of Event, if properties are renamed, it's bad

thheller11:10:28

I do not know what you mean by local variable

Jon11:10:48

event...

thheller11:10:49

(let [x 1] ...) x is a local variable

thheller11:10:02

you are talking about property which is different (I think)

thheller11:10:30

need code example

Jon11:10:51

"input" {:type :input, :value (aget (.-target event) "value")}
        "change" {:type :change, :value (aget (.-target event) "value")}

Jon11:10:03

that "value"

thheller11:10:51

depends on what event is

thheller11:10:09

those are the default externs. things in there should be covered

thheller11:10:38

> I noticed there was a formatter before. But it did not working recently.

thheller11:10:01

can you be more specific? what didn’t work? it should always work?

Jon11:10:06

if I use (.-value (.-target event)) the value part will be renamed, but it should be event.target.value

Jon11:10:19

so I switched to aget and string

thheller11:10:21

I have used that many times and never had issues with renaming

thheller11:10:03

but as I said .. the compiler might get confused about event and not use the correct type

Jon11:10:14

well... not sure now, it was old codebase. I was trying to solve that with externs, but didn't managed to do it.

thheller11:10:17

hard to tell without all the code

Jon11:10:43

anyway it's enough for my current problem.

thheller11:10:46

using the :externs example from above X.prototype.value would have been enough

thheller11:10:28

shadow-cljs check might have explained as well

Jon11:10:46

thanks anyway...

Jon11:10:23

at least I learnt externs today...

geraldodev13:10:43

can shadow-cljs co exist with figwheel ?

thheller15:10:29

@geraldodev sure but it can do almost anything that figwheel does, so why would you want to? 🙂

thheller15:10:38

only part thats missing is live reloading for css

thheller15:10:47

live reloading of code and REPL just works