Message from discussion
peeves & current best practices?
Received: by 10.205.123.145 with SMTP id gk17mr1683150bkc.2.1349896166247;
Wed, 10 Oct 2012 12:09:26 -0700 (PDT)
X-BeenThere: nodejs@googlegroups.com
Received: by 10.204.7.203 with SMTP id e11ls1127418bke.8.gmail; Wed, 10 Oct
2012 12:09:08 -0700 (PDT)
Received: by 10.205.123.145 with SMTP id gk17mr1683057bkc.2.1349896147956;
Wed, 10 Oct 2012 12:09:07 -0700 (PDT)
Received: by 10.205.123.145 with SMTP id gk17mr1683056bkc.2.1349896147912;
Wed, 10 Oct 2012 12:09:07 -0700 (PDT)
Return-Path: <m...@hahnca.com>
Received: from mail-la0-f42.google.com (mail-la0-f42.google.com [209.85.215.42])
by gmr-mx.google.com with ESMTPS id k7si275680bks.2.2012.10.10.12.09.07
(version=TLSv1/SSLv3 cipher=OTHER);
Wed, 10 Oct 2012 12:09:07 -0700 (PDT)
Received-SPF: neutral (google.com: 209.85.215.42 is neither permitted nor denied by best guess record for domain of m...@hahnca.com) client-ip=209.85.215.42;
Authentication-Results: gmr-mx.google.com; spf=neutral (google.com: 209.85.215.42 is neither permitted nor denied by best guess record for domain of m...@hahnca.com) smtp.mail=m...@hahnca.com
Received: by mail-la0-f42.google.com with SMTP id e6so1317537lah.1
for <nodejs@googlegroups.com>; Wed, 10 Oct 2012 12:09:07 -0700 (PDT)
d=google.com; s=20120113;
h=mime-version:x-originating-ip:in-reply-to:references:from:date
:message-id:subject:to:content-type:x-gm-message-state;
bh=pF+rkuk/UNjGXOsIqaKlSCbFrPk5UfODQeTRv5nWcx4=;
b=omikxQ14NN6RIxW/YBLc6VO7MMQ6LdjSWMrPRO39hhEqXyuKNBb/YeB3AkuQFF0rWd
mClbqbMud4Ba3ntXGhENuNbFC9FsbcVXpFFjrg+B6X2/FuLnyx/T6mNewc85p/5WIVuI
pC5+X+UzIkiJZquXeDZwGPeHYuMsIRLVpBZf35QJhhwvI0P1Nkby6qCD9IhUAdge6lrf
6Z2mu29kWTuwVFUKQzGHko7Bhfg9QBQl+QLxTq7GGpgmAJgvMeSzUqJj5rOxJn1jUdzn
vTmdOeePhvYYtls6N+hSmYeHrQP/DJPMhRGGLz2w8MIjpC6PZrKn6dulNsTpp3my+8Iw
SO9A==
Received: by 10.112.84.135 with SMTP id z7mr9673679lby.119.1349896147232; Wed,
10 Oct 2012 12:09:07 -0700 (PDT)
MIME-Version: 1.0
Received: by 10.114.74.196 with HTTP; Wed, 10 Oct 2012 12:08:47 -0700 (PDT)
X-Originating-IP: [68.5.117.177]
In-Reply-To: <dc8c3771-5e2e-4cf0-b3ed-3815579692cb@googlegroups.com>
References: <dc8c3771-5e2e-4cf0-b3ed-3815579692cb@googlegroups.com>
From: Mark Hahn <m...@hahnca.com>
Date: Wed, 10 Oct 2012 12:08:47 -0700
Message-ID: <CACrj35Ef4hJk6VzUoMV-mx6gFa21AkTAdGG69S6MsvGQKcY...@mail.gmail.com>
Subject: Re: [nodejs] peeves & current best practices?
To: nodejs@googlegroups.com
Content-Type: multipart/alternative; boundary=f46d0401687b56e76b04cbb93060
X-Gm-Message-State: ALoCoQkC0tAn/44D51Za0pUr1xSZqI2xjxx1yo7Fa0ZmL1tetKE6Jus178B/SEn5OcpwfzfEmXvY
--f46d0401687b56e76b04cbb93060
Content-Type: text/plain; charset=windows-1252
Content-Transfer-Encoding: quoted-printable
That's pretty awesome. There's a couple of items I'd like to discuss, the
first one being ...
> Always wrap callbacks in process.nextTick if they're not behind an async
operation. Simple.
This doesn't seem necessary to me and it seems inefficient and dangerous.
I make sure to write in a style that will work whether the callee is sync
or async. Your scheme will break if the callee ever adds some async.
Writing in a style that isn't affected by sync/async has these advantages
...
1) I don't have to know whether the callee is sync or async. I'm lazy.
2) As I said above, I don't have to worry if it changes.
3) It makes it easier to add my own async to stuff. I can just split the
code with the editor.
4) Also as I said above it is efficient.
On Wed, Oct 10, 2012 at 11:51 AM, Tim Oxley <sec...@gmail.com> wrote:
> So, here's part of a totally subjective, non-comprehensive list of
> frustrations and "best practices" I've been collecting. Some are based on
> personal experience and others are ideals from the node community that I'=
m
> trying to incorporate.
>
> I'm looking for more tips like this. Please share your knowledge or vent
> your frustrations here.
>
> *Stream-like apis*
> If your code is emitting data/error events but not inheriting from Stream=
,
> your module becomes inoperable with other streams, e.g. can't pipe(). Thi=
s
> severely reduces your module's flexibility.
>
> *Inconsistent sync/async*
> When functions are sometimes sync and sometimes async lead to hard to use
> apis, subtle bugs and more error handling wrapper code. Always wrap
> callbacks in process.nextTick if they're not behind an async operation.
> Simple.
>
> *Prematurely optimising*
> e.g. choosing to avoid readable, semantic iteration with
> Array#map/forEach/reduce/filter=85 instead using for loops 'because they'=
re
> faster'.
> Unless you're writing a database driver or something similar, focus on
> writing maintainable, clean code. Optimising your io and designing to sca=
le
> horizontally rather than tuning individual code paths will reap far
> more benefit and is more inline with node's focus (io bound tasks over cp=
u
> bound tasks).
>
> *OO is an implementation detail*
> Rather than exporting constructors as the primary API of a module, just
> give me a factory method please.
>
> *Fear of dependencies*
> Some developers exhibit a reluctance to use modules due to the 'overheads=
'
> of managing dependencies, which is probably a stigma carried from other
> non-nodejs environments. It's not nearly as big of an issue in node, so
> don't hesitate to `npm install` with reckless abandon.
>
> *Duplication of effort*
> Creating new modules instead of improving existing modules dilutes the
> quality of the module ecosystem. Diversity is great, but only when there=
=92s
> a meaningful reason for that diversity to exist. "All the other modules f=
or
> X were broken or buggy", sounds like a good reason to start a new module,
> but perhaps you're throwing baby out with bathwater=85 the fix may have b=
een
> a simple task but instead of 5 functionally similar, sparingly maintained
> modules, we=92ve now got 6, and more surface area for bugs. Nice work.
>
> Another reason new modules are created is because the consumer didn't
> appreciate the module's api; this is a trickier issue as people love
> bikeshedding over this kind of stuff. I've found it's often easiest to ju=
st
> wrap modules with an api you prefer rather than starting from scratch or
> arguing with the author.
>
> *Learn to npm*
> npm contains a great amount of functionality and information that many
> people don't seem to know about. For example you should rarely have need =
to
> edit your package.json (especially when installing/updating modules) as n=
pm
> has commands to create <https://npmjs.org/doc/init.html> and update<https=
://npmjs.org/doc/install.html> your
> package.json for you. 'npm help' is an excellent source of answers to man=
y
> questions. There's plenty to learn about npm<http://www.devthought.com/20=
12/02/17/npm-tricks/>,
> please share any tricks.
>
> *npm scripts vs readme
> *If you encapsulate all the knowledge about how to build/boot/test your
> app into your package.json scripts <https://npmjs.org/doc/scripts.html>,
> that's less information you need to put into the readme and keeps things
> consistent. For example, if you setup a test script, I only need to know =
to
> run `npm test`, rather than hope you've included information about how to
> run your tests. If you change your test tool, or change the arguments, I
> don't even need to know since that information is embedded in the
> package.json.
>
> *Tagging releases*
> If you don't tag releases, it's a pain to find the commit that correspond=
s
> to a release. Use npm version <https://npmjs.org/doc/version.html> to
> generate tags.
>
> *Deep abstractions*
> Having many layers and long breadcrumb trails makes understanding and
> debugging your module difficult, raising the barrier to participation (an=
d
> maintainability). Complexity is often presented as 'architecture'. Simpli=
city
> is key. <http://www.infoq.com/presentations/Simple-Made-Easy>If your
> system is becoming complicated, it's probably doing too much or you're
> going about it in the wrong way.
>
> *Refrain from building/using all-in-one frameworks**
> *This is not in keeping with the nodejs aesthetic<http://substack.net/pos=
ts/b96642/the-node-js-aesthetic>.
> Node isn't Rails. Having code coupled to a framework creates duplication =
of
> work, fragmentation and interoperability. This is bad. The trend towards
> modularisation is one of the best things node has got going for it over
> other environments, don't ruin it by creating silos.
>
> *MVC*
> Usually overkill. If your app is modular enough, you likely won't need
> much/any of it. MVC everywhere makes it more difficult to isolate feature=
s
> and break them into decoupled components, as well as encouraging some
> utterly ridiculous solutions (when all you have is a hammer=85). Framewor=
ks
> that dictate application architecture should be avoided as architecture
> should be determined by the problem at hand<http://blog.8thlight.com/uncl=
e-bob/2011/09/30/Screaming-Architecture.html> not
> a framework. Moving away from MVC everywhere also gives you the ability t=
o
> experiment with different patterns and evolve your architecture toolset.
> You'll be surprised at how simple some problems are if you don't contort
> everything to fit into the MVC mould.
>
> *Supply usage examples in modules*
> Most of TJ's and Substack's modules include working examples demonstratin=
g
> various use cases. Showing how to use the module is far, far more importa=
nt
> than narratives and lengthy api documentation in a readme. Code is a
> concrete explanation and usually uses less words (if not perhaps your cod=
e
> needs refactoring).
>
> *Supply usage examples upfront in readmes*
> Please put a usage example at the top of your readme.
>
> *Write tests*
> Tests help other developers have confidence they haven't accidentally
> broken anything when contributing to your project. Tests can also serve a=
s
> usage examples in lieu of comprehensive examples/documentation.
>
> What else? Teach me of your ways.
>
> This part of some research for a presentation <http://jscamp.asia/> I'm
> putting together on a similar topic.
>
> --
> Job Board: http://jobs.nodejs.org/
> Posting guidelines:
> https://github.com/joyent/node/wiki/Mailing-List-Posting-Guidelines
> You received this message because you are subscribed to the Google
> Groups "nodejs" group.
> To post to this group, send email to nodejs@googlegroups.com
> To unsubscribe from this group, send email to
> nodejs+unsubscribe@googlegroups.com
> For more options, visit this group at
> http://groups.google.com/group/nodejs?hl=3Den?hl=3Den
>
--f46d0401687b56e76b04cbb93060
Content-Type: text/html; charset=windows-1252
Content-Transfer-Encoding: quoted-printable
That's pretty awesome. =A0There's a couple of items I'd like to=
discuss, the first one being ...<div><br></div><div><span style=3D"font-fa=
mily:arial,sans-serif;font-size:12.727272033691406px;background-color:rgb(2=
55,255,255)">> Always=A0wrap callbacks in process.nextTick if they'r=
e not behind an async operation. Simple.</span></div>
<div><font face=3D"arial, sans-serif"><br></font></div><div><font face=3D"a=
rial, sans-serif">This doesn't seem necessary to me and it seems ineffi=
cient and dangerous. =A0I make sure to write in a style that will work whet=
her the callee is sync or async. =A0Your scheme will break if the callee ev=
er adds some async. =A0Writing in a style that isn't affected by sync/a=
sync has these advantages ...</font></div>
<div><font face=3D"arial, sans-serif"><br></font></div><div><font face=3D"a=
rial, sans-serif">1) I don't have to know whether the callee is sync or=
async. =A0I'm lazy.</font></div><div><font face=3D"arial, sans-serif">=
<br>
</font></div><div><font face=3D"arial, sans-serif">2) As I said above, I do=
n't have to worry if it changes.</font></div><div><font face=3D"arial, =
sans-serif"><br></font></div><div><font face=3D"arial, sans-serif">3) It ma=
kes it easier to add my own async to stuff. =A0I can just split the code wi=
th the editor.</font></div>
<div><font face=3D"arial, sans-serif"><br></font></div><div><font face=3D"a=
rial, sans-serif">4) Also as I said above it is efficient.</font></div><div=
><font face=3D"arial, sans-serif"><br></font></div><div><div><br><div class=
=3D"gmail_quote">
On Wed, Oct 10, 2012 at 11:51 AM, Tim Oxley <span dir=3D"ltr"><<a href=
=3D"mailto:sec...@gmail.com" target=3D"_blank">sec...@gmail.com</a>></sp=
an> wrote:<br><blockquote class=3D"gmail_quote" style=3D"margin:0 0 0 .8ex;=
border-left:1px #ccc solid;padding-left:1ex">
So, here's part of a totally subjective, non-comprehensive list of frus=
trations and "best practices" I've been collecting. Some are =
based on personal experience and others are ideals=A0from the node communit=
y that=A0I'm trying to incorporate.<br>
<br><div>I'm looking for more tips like this. Please share your knowled=
ge or vent your frustrations here.</div><div><div><div><br><div><b>Stream-l=
ike apis</b><br>If your code is emitting data/error events but not inheriti=
ng from Stream, your module becomes inoperable with other streams, e.g. can=
't pipe(). This severely reduces your module's flexibility.</div>
<div><br></div><div><b>Inconsistent sync/async</b><br>When functions are so=
metimes sync and sometimes async lead to hard to use apis, subtle bugs and =
more error handling wrapper code. Always=A0wrap callbacks in process.nextTi=
ck if they're not behind an async operation. Simple.</div>
<br><b>Prematurely optimising</b><br>e.g. choosing to avoid readable, seman=
tic iteration with Array#map/forEach/reduce/filter=85 instead using for loo=
ps 'because they're faster'.=A0</div><div>Unless you're wri=
ting a database driver or something similar, focus on writing maintainable,=
clean code. Optimising your io and designing to scale horizontally rather =
than tuning individual code paths will reap far more=A0benefit and is more =
inline with node's focus (io bound tasks over cpu bound tasks).</div>
<div><br><b>OO is an implementation detail</b><br>Rather than=A0exporting c=
onstructors as the primary API of a module, just give me a factory method p=
lease.<br><br><b>Fear of dependencies</b><br>Some developers exhibit a relu=
ctance to use modules due to the 'overheads' of managing dependenci=
es, which is probably a stigma carried from other non-nodejs environments. =
It's not nearly as big of an issue in node, so don't hesitate to `n=
pm install` with reckless abandon.<br>
<br><b>Duplication of effort</b><br>Creating new modules instead of improvi=
ng existing modules dilutes the quality of the module ecosystem.=A0Diversit=
y is great, but only when there=92s a meaningful reason for that diversity =
to exist. "All the other modules for X were broken or buggy", sou=
nds like a good reason to start a new module, but perhaps you're throwi=
ng baby out with bathwater=85 the fix may have been a simple task but inste=
ad of 5 functionally similar,=A0sparingly maintained modules, we=92ve now g=
ot 6, and more surface area for bugs. Nice work.=A0</div>
<div><br></div><div>Another reason new modules are created is because the c=
onsumer didn't appreciate the module's api; this is a trickier issu=
e as people love bikeshedding over this kind of stuff. I've found it=
9;s often easiest to just wrap modules with an api you prefer rather than s=
tarting from scratch or arguing with the author.<br>
<br></div><div><b>Learn to npm</b></div><div>npm contains a great amount of=
functionality and information that many people don't seem to know abou=
t. For example you should rarely have need to edit your package.json (espec=
ially when installing/updating modules) as npm has commands to=A0<a href=3D=
"https://npmjs.org/doc/init.html" target=3D"_blank">create</a> and <a href=
=3D"https://npmjs.org/doc/install.html" target=3D"_blank">update</a>=A0your=
package.json for you. 'npm help' is an excellent source of answers=
to many questions. There's plenty to <a href=3D"http://www.devthought.=
com/2012/02/17/npm-tricks/" target=3D"_blank">learn about npm</a>, please s=
hare any tricks.</div>
<div><br><b>npm scripts vs readme<br></b>If you encapsulate all the knowled=
ge about how to build/boot/test your app into your=A0<a href=3D"https://npm=
js.org/doc/scripts.html" target=3D"_blank">package.json scripts</a>, that&#=
39;s less information you need to put into the readme and keeps things cons=
istent. For example, if you setup a test script, I only need to know to run=
`npm test`, rather than hope you've included information about how to =
run your tests. If you change your test tool, or change the arguments, I do=
n't even need to know since that information is embedded in the package=
.json.</div>
<div><br></div><div><b>Tagging releases</b><br>If you don't tag release=
s, it's a pain to find the commit that corresponds to a release. Use=A0=
<a href=3D"https://npmjs.org/doc/version.html" target=3D"_blank">npm versio=
n</a>=A0to generate tags.<br>
<br><b>Deep abstractions</b></div><div>Having many layers and long breadcru=
mb trails makes understanding and debugging your module difficult, raising =
the barrier to participation (and maintainability). Complexity=A0is often p=
resented as 'architecture'. <a href=3D"http://www.infoq.com/present=
ations/Simple-Made-Easy" target=3D"_blank">Simplicity is key.=A0</a>If your=
system is becoming complicated, it's probably doing too much or you=
9;re going about it in the wrong way.</div>
<div><br></div><div><b>Refrain from building/using all-in-one frameworks</b=
><b><br></b>This is not in keeping with the nodejs <a href=3D"http://substa=
ck.net/posts/b96642/the-node-js-aesthetic" target=3D"_blank">aesthetic</a>.=
Node isn't Rails.=A0Having code coupled to a framework creates duplica=
tion of work, fragmentation and interoperability. This is bad. The trend to=
wards modularisation is one of the best things node has got going for it ov=
er other environments, don't ruin it by creating silos.</div>
<div><br><b>MVC</b><br>Usually overkill. If your app is modular enough, you=
likely won't need much/any of it. MVC everywhere makes it more difficu=
lt to isolate features and break them into decoupled components, as well as=
encouraging some utterly ridiculous solutions (when all you have is a hamm=
er=85).=A0Frameworks that dictate application architecture should be avoide=
d as<a href=3D"http://blog.8thlight.com/uncle-bob/2011/09/30/Screaming-Arch=
itecture.html" target=3D"_blank">=A0architecture should be determined by th=
e problem at hand</a>=A0not a framework. Moving away from MVC everywhere al=
so gives you the ability to experiment with different patterns and evolve y=
our architecture toolset. You'll be surprised at how simple some proble=
ms are if you don't contort everything to fit into the MVC mould.<br>
<br><b>Supply usage examples in modules</b><br>Most of TJ's and Substac=
k's modules include=A0working=A0examples demonstrating various use case=
s. Showing how to use the module is far, far more important than narratives=
and lengthy api documentation in a readme. Code is a concrete explanation =
and usually uses less words (if not perhaps your code needs refactoring). <=
br>
<br><b>Supply usage examples upfront in readmes</b><br>Please put a usage e=
xample at the top of your readme.<br><br></div><div><b>Write tests</b><br><=
/div><div>Tests help other developers have confidence they haven't acci=
dentally broken anything when contributing to your project. Tests can also =
serve as usage examples in=A0lieu of comprehensive examples/documentation.<=
/div>
<div><br></div><div>What else? Teach me of your ways.<br><br>This part of s=
ome research for a=A0<a href=3D"http://jscamp.asia/" target=3D"_blank">pres=
entation</a>=A0I'm putting together=A0on a similar topic.<span class=3D=
"HOEnZb"><font color=3D"#888888"><br>
</font></span></div></div></div><span class=3D"HOEnZb"><font color=3D"#8888=
88">
<p></p>
-- <br>
Job Board: <a href=3D"http://jobs.nodejs.org/" target=3D"_blank">http://job=
s.nodejs.org/</a><br>
Posting guidelines: <a href=3D"https://github.com/joyent/node/wiki/Mailing-=
List-Posting-Guidelines" target=3D"_blank">https://github.com/joyent/node/w=
iki/Mailing-List-Posting-Guidelines</a><br>
You received this message because you are subscribed to the Google<br>
Groups "nodejs" group.<br>
To post to this group, send email to <a href=3D"mailto:nodejs@googlegroups.=
com" target=3D"_blank">nodejs@googlegroups.com</a><br>
To unsubscribe from this group, send email to<br>
<a href=3D"mailto:nodejs%2Bunsubscribe@googlegroups.com" target=3D"_blank">=
nodejs+unsubscribe@googlegroups.com</a><br>
For more options, visit this group at<br>
<a href=3D"http://groups.google.com/group/nodejs?hl=3Den?hl=3Den" target=3D=
"_blank">http://groups.google.com/group/nodejs?hl=3Den?hl=3Den</a><br>
</font></span></blockquote></div><br></div></div>
--f46d0401687b56e76b04cbb93060--