OK, I realize now that all your points were about writing good modules.  I
took your point from the view of the module user, not the author.  I really
should read more carefully.

On Wed, Oct 10, 2012 at 12:14 PM, Tim Oxley <[email protected]> wrote:

> > Always wrap callbacks in process.nextTick if they're not behind an async
> operation. Simple.
>
> Oh, of course… to clarify:
>
> If a module is possibly going to execute an async operation, ensure any
> otherwise synchronous callbacks are inside in process.nextTick. i.e. If
> it's sync it should always be sync. if it's async, it should always be
> async.
>
>
> On Thursday, 11 October 2012 05:09:26 UTC+10, Mark Hahn wrote:
>>
>> 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 <[email protected]> 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(). This 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… 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 scale
>>> horizontally rather than tuning individual code paths will reap far
>>> more benefit and is more inline with node's focus (io bound tasks over cpu
>>> 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’s
>>> a meaningful reason for that diversity to exist. "All the other modules for
>>> X were broken or buggy", sounds like a good reason to start a new module,
>>> but perhaps you're throwing baby out with bathwater… the fix may have been
>>> a simple task but instead of 5 functionally similar, sparingly maintained
>>> modules, we’ve 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 just
>>> 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 npm
>>> 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 many
>>> questions. There's plenty to learn about 
>>> npm<http://www.devthought.com/2012/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
>>> corresponds 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 (and
>>> maintainability). Complexity is often presented as 'architecture'. 
>>> Simplicity
>>> 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/posts/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 features
>>> and break them into decoupled components, as well as encouraging some
>>> utterly ridiculous solutions (when all you have is a hammer…). Frameworks
>>> that dictate application architecture should be avoided as architecture
>>> should be determined by the problem at 
>>> hand<http://blog.8thlight.com/uncle-bob/2011/09/30/Screaming-Architecture.html>
>>>  not
>>> a framework. Moving away from MVC everywhere also gives you the ability to
>>> 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
>>> demonstrating various use cases. 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).
>>>
>>> *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 as
>>> 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<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 [email protected]
>>> To unsubscribe from this group, send email to
>>> nodejs+un...@**googlegroups.com
>>> For more options, visit this group at
>>> http://groups.google.com/**group/nodejs?hl=en?hl=en<http://groups.google.com/group/nodejs?hl=en?hl=en>
>>>
>>
>>  --
> 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 [email protected]
> To unsubscribe from this group, send email to
> [email protected]
> For more options, visit this group at
> http://groups.google.com/group/nodejs?hl=en?hl=en
>

-- 
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 [email protected]
To unsubscribe from this group, send email to
[email protected]
For more options, visit this group at
http://groups.google.com/group/nodejs?hl=en?hl=en

Reply via email to