
Human JavaScript - robin_reala
http://read.humanjavascript.com/
======
skrebbel
I really like opinionated books like these.

I've a question for HN on one of the opinions in this book: "use Browserify".
There is only 1 single reason I don't currently use Browserify for client-side
web apps: debugging. If Browserify turns all my files into one big file, all
the time, and that's the only way, then how am I going to debug without going
insane?

I know about source maps, but I use many compile-to-JS languages (TypeScript
and React's JSX, in my case), and they provide source maps already. Afaik,
Browserify doesn't re-map those source maps, or something like that.

Can I conclude that people who use Browserify simply never use compile-to-JS
languages? Am I really forced to choose one of:

    
    
        * Avoid Browserify (and similar tools)
        * Write only vanilla JS
        * Deal with having to in-browser-debug a single 20000 line JS file
        * Finally spend time to contribute source map remapping to Browserify
    

Any ideas? Am I missing something awesome?

~~~
HenrikJoreteg
Browserify has had source maps since v2: [http://thlorenz.com/blog/browserify-
sourcemaps](http://thlorenz.com/blog/browserify-sourcemaps)

Just pass {debug: true} to build function.

~~~
warfangle
This probably only works if you're using a transpiler transform in the
browserify pipeline. (instead of running browserify on an already-transpiled
codebase)

~~~
HenrikJoreteg
Oh, got it. I misread the original comment.

~~~
warfangle
No worries :)

I like that you're focusing so heavily on commonjs+browserify. We've made the
switch for new projects as well. I'm curious as to why you advocate
wildemitter over browserify's client side port of EventEmitter? Is it a lot
lighter?

------
warfangle
> "What about load times and performance?!?!"

If you're rendering everything on the client like that, how many HTTP requests
are you making, other than the initial 3 (stylesheet + javascript + html
document)?

I'm especially focusing on mobile performance, here. On 3G you have 200-2500ms
latency on the control plane, 200ms latency for dns lookup, 200ms latency on
establishishing a tcp connection, your TLS handshake will have a latency
anywhere from 200-400ms and the actual http request will have a latency of
200ms.

That's 1000-2900ms per http request, minus 100 if your client can cache DNS
responses (and everything is on the same domain). Sometimes these will be
multiplexed. You can't count on it though. 4G is only marginally better: you
have an overhead of 240-500ms on 4G.

And none of that takes into account the time it takes your server to process a
request, or the time it takes for the client to parse and execute your
rendering codebase.

If you're aiming for sub-1000ms request-to-glass, you can't follow the advice
of this book (don't render anything on the server ever) - unless you don't
mind the client showing a loading animation for the 2-15 seconds it'll take to
load your "app."

(good luck with that mobile bounce rate)

0\.
[https://www.youtube.com/watch?v=Il4swGfTOSM](https://www.youtube.com/watch?v=Il4swGfTOSM)

~~~
HenrikJoreteg
Yup, I don't disagree, this fact sucks. If you keep reading you'll notice I
suggest not doing this for apps that aren't behind a login.

You can use login pages to prime caches, pre-render, etc. That's certainly not
a panacea, but can help.

With the right cache headers on the main application assets and a primed cache
you can start executing code immediately and eliminate all but your data calls
on a good portion of app loads. From my experience, with a primed cache it's
not too difficult to get comparable load times to opening a native app.

I'm hoping ServiceWorkers, Improved local databases, and HTTP 2.0 can help us
out here.

There's also the option of trying to do the initial render server-side. I've
experimented a bit with this, and have some more thoughts and approaches I
want to try for this. But, I have yet to see someone do this is a way that
didn't add a significant amount of complexity to the codebase :-/

~~~
warfangle
Yup. For those of us working on highly dynamic non-app sites things are a bit
more difficult.

I only had time to skim the introductions earlier - I'll have to give it a
full read.

------
dmix
I skimmed a few chapters and as someone who writes Javascript all day, this
looks pretty good. I want to dig into it more.

But I'm going to be "that-guy" and say $39 is too much just to get the
kindle/PDF version. I buy a ton of programming books and I tend to only fork
that much over for authoritative paper textbooks on particular subjects.
Rarely digital versions. Otherwise I'm all with Patrick McKenzie on charging
more.

~~~
pablasso
Agreed, I don't have a problem buying digital books, but $39 is too much.

~~~
jmromer
I suspect that if Henrik is already giving away a digital version, with the
paid version he's targeting high-rollers motivated to buy one out of a sense
of gratitude/largesse. So a high price tag sort of makes sense.

------
l8no7cougyi
In the 'Writing code for humans.' section are the first three code examples
meant to do the same thing? The first and third check whether the array
contains 'hello' but the second does the opposite.

~~~
Yahivin
I guess it wasn't so clear after all. I think this makes the third example
even stronger: use a method that is named what it does.

~~~
HenrikJoreteg
Haha, this is an epic typo :) Sorry, will fix.

~~~
l8no7cougyi
No problem :) it looks really good - just thought I'd point that out!

------
stagas
I stopped reading at the tilde argument for readability. I find the tilde
token far more readable and easier to spot, and there's no confusion as to
what the indexOf is checking for, the existence of an element in an array,
where with the equality comparison tokens I need to stop and read what the
heck it is comparing to. These should be reserved for when it's checking for a
specific index or range.

Those extra seconds add up and in my opinion readability is more about
optimizing reading speed by using common shapes and patterns conventionally,
not making something dumb proof.

It even suggests using a dependency like underscore for something that is
already in the language. So if I don't use underscore, I need to stop my
reading completely because my mind doesn't recognize this
_(array).contains('foo') pattern and I need to actively read the entire line
and in cases lookup the documentation of some random method in a random
obscure _ library that I also need to lookup in the code to find the actual
dependency name. Because even if I were to check the implementation of that
underscore method using the IDE, it's even more obscure and magic. Good luck
following the advice in this book.

~~~
qwerty_asdf
I think the tilde operator and Underscore are both equally cryptic and
represent similar degrees of obfuscation. Tilde doesn't get much use, because
it's prone to quirky behavior, particularly with respect to negative one in
javascript. Gven that javascript has junk lying around like NaN, undefined,
null, ==, ===, I tend to mistrust anything that isn't dog-ugly bland
convention.

Aliases are also ugly in my opinion, given that they can be reassigned any old
time. Even the much-used dollar sign alias demands extra scrutiny, when
inspectng unfamiliar code. The advantage is that they're (aliases, that is)
are easy to write, not easy read. On the other hand, the "contains" function
_should_ adhere to the sanest contract most would expect from it, and if it
does, "contains" is easy enough to understand. But yeah, depending on
libraries is either laziness or bullshit, when it comes to core language
functionality. The only thing advanced libraries really offer is cross-browser
compatibility.

Meanwhile, (x.indexOf(y) == -1) is dead simple, as long as you know that
arrays start at zero, never have negative indices, and that indexOf() returns
a negative value when the argument isn't matched by an object in the array.
Returning a negative value, as parlance for "not found", when an absolute
integer value is expected, is a pretty sane convention.

~~~
stagas
That's what I mean by using patterns and shapes conventionally. By using the
tilde only on indexOfs (math aside), it immediately communicates its reason
and when you don't see it and instead see equality operators you know that
it's NOT a 'has' operation but it's something that needs more attention. Of
course this depends on a lot of people doing it besides you, but most of the
code I trust and use mostly uses this pattern.

------
odiroot
I'm really interested how people here react to the "Picking your tools" part
in the introduction.

Some pretty strong opinions that contradict current trends in front-end world.
I actually waited for someone to break the mould and start questioning the
status quo. Especially regarding the use of DSLs and logic in templates.

~~~
klibertp
Until recently I didn't even know that there was a status quo in the frontend
development. I worked with JavaScript in exactly the same way I'd work with
any other language where stdlib is minimal at best (like Scheme or C) and that
was to design the app, fill as many blanks as possible with libraries and
write the rest myself.

Now I'm forced to use Angular and frankly, I'm frightened. There is no room
for designing the architecture of my app - it's been taken care of - yet I'm
still going to be held responsible for this architecture shortcomings, if I
happen to stumble upon some of them.

Of course, codification of some conventions may be convenient and so I'm not
against frameworks in general. But I know that sooner or later I _will_ need
an escape hatch to do something less than conventional and I want my framework
to just get out of my way for a while. That's what Pyramid does and what
Django starts to support in recent versions. I'm not yet familiar enough with
them, but I suspect Angular, Ember and some others are not that great in this
respect.

In short, while I never was very interested in front-end development, I did
build some single-page apps, and I - after skimming a few chapters of this
book - always worked similarly to what the author proposes. I really do hope
that this approach will become dominant (once again, everything old becomes
new again and all that), if for no other reason then because I just enjoy
designing and writing in this style more.

[PS. It's nice to see you're still alive :)]

~~~
odiroot
Hi, likewise :)

On topic: agree on Pyramid / Django comparison. It was a nice, eye-opening
experience to work on Pyramid project after only Django-based ones.

Though I doubt the same applies to Angular / Ember.

------
krmmalik
Possibly slightly tangential. I am someone that has a basic understanding of
JS. I don't code on a regular basis, just here and there. I'm fine with html
and css, but I want to up my JS skills in a couple of specific areas.
Specifically, I want to learn how to build apps that can leverage other APIs.
say for example if I want to build a service that interacts with the gmail
api. I can't seem to find any information anywhere that can help me do this.
Every time I do a search for JS API, API, rest API or similar, all I get is
results for how to build an API in your own app, which is not what I need.

Does your book have the content I need to learn how to use an API? If not --
does anyone have any suggestions as to where I can go to learn this?

~~~
delluminatus
There is a beta Javascript client library for the Gmail API [0]. If you are
looking to interface with an API that doesn't provide a JS client, your best
bet might be to just build yourself a simple client using jQuery to handle the
HTTP communication (see, for example, jQuery.ajax [1] for making HTTP calls).

ETA: To elaborate a bit, "interfacing with an external API" is usually just a
fancy way of saying, "making HTTP requests." In Javascript, this means using
the XmlHttpRequest browser API, which people call AJAX because it sounds hip.
You can use it directly, but jQuery gives some extremely convenient helper
methods for easily composing requests. One thing to keep in mind is that if
the API uses JSON, you will have to consider that the browser does not permit
you to return JSON from a cross-domain request (which an external API call
almost certainly is). There is a way to enable this using something called
JSONP [2].

[0]: [https://developers.google.com/api-client-
library/javascript/...](https://developers.google.com/api-client-
library/javascript/start/start-js)

[1]:
[https://api.jquery.com/jQuery.ajax/](https://api.jquery.com/jQuery.ajax/)

[2]: [http://json-p.org/](http://json-p.org/)

------
rhengles
I agree with almost everything, except Browserify. I guess he prefers CommonJS
to integrate with Node and npm, but in the browser I'd rather wrap the modules
in AMD and use an AMD module loader (not necessarily RequireJS).

~~~
HenrikJoreteg
It's merely an opinion, to each their own. If AMD works well for you, that's
great.

------
gprasanth
The books seems really interesting. I hope it's ok to print it and read
offline

[https://gist.github.com/g-P/0e663535d69a06f4dcca](https://gist.github.com/g-P/0e663535d69a06f4dcca)

JavaScript rocks!

