My thoughts on writing tiny reusable modules that each do just one | |
thing. These notes were adapted from an email I recently sent. | |
*** | |
If some component is reusable enough to be a module then the | |
maintenance gains are really worth the overhead of making a new | |
project with separate tests and docs. Splitting out a reusable | |
component might take 5 or 10 minutes to set up all the package | |
overhead but it's much easier to test and document a piece that is | |
completely separate from a larger project. When something is easy, you | |
do it more often. | |
I've observed the biggest gains for splitting something out into a | |
separate module when I'm completely stuck mucking around in a larger | |
application. When I isolate the problem down to the scope of a small | |
module, it's much easier to see how that small piece fits in with the | |
greater application objective. | |
Another technique is to pick tools and approaches that don't involve a | |
lot of boilerplate in the first place. My usual flow for writing a new | |
module is: | |
1. hack up some tiny (<10 line) example file that does just enough to | |
start experimenting with the api | |
2. start fleshing out an index.js file required by the example file | |
3. make incremental changes to the index file to get the example | |
further along, updating the example as necessary to reflect changes | |
4. once the example pretty much works, copy it into test/ | |
5. `npm install tap` or `npm install tape` for modules I want to test | |
in the browser. I like simple, imperative tests that I can adapt from | |
simple examples. | |
6. add some assertions around the example code | |
7. `pkginit` (https://github.com/substack/pkginit) to generate a | |
package.json (or you could just use `npm init`) | |
8. copy the example file into a readme.markdown since I really like | |
when packages have code in their readmes when I'm looking for modules | |
to use | |
9. add a blurb at the top of the readme.markdown, document the methods | |
(there are only a few to document usually), add a license and install | |
instructions | |
10. create a github repo | |
11. add travis and/or testling-ci github hooks as appropriate | |
12. `git push` and `npm publish` | |
With practice, I run through all these steps very quickly now. Not all | |
of these are strictly necessary and sometimes I'll skip a step but | |
this is mostly the procedure I use for new modules. | |
As much as possible, I try to build large-scale projects using lots of | |
tiny modules so I just repeat this process whenever I need some | |
reusable component that doesn't yet exist in quite the form I need it | |
to exist. As more modules are published to npm I expect I won't need | |
to write so many modules but there will always be room for new stuff. | |
When applications are done well, they are just the really | |
application-specific, brackish residue that can't be so easily | |
abstracted away. All the nice, reusable components sublimate away onto | |
github and npm where everybody can collaborate to advance the commons. |
This comment has been minimized.
This comment has been minimized.
Here are some naming tricks:
|
This comment has been minimized.
This comment has been minimized.
Cool, thanks a lot! |
This comment has been minimized.
This comment has been minimized.
Awesome, I'm going to start doing this. |
This comment has been minimized.
This comment has been minimized.
I wrote kind of a counter argument to this gist while explaining the design decisions behind moutjs: http://blog.millermedeiros.com/mout-and-modularity/ |
This comment has been minimized.
This comment has been minimized.
Not only do I completely agree with this advice, but it is also worth noting that besides the At this stage in the game, it is my opinion that any language/environment that is not amenable to this (or a similar) workflow is likely broken. I don't think a better workflow exists at this time. If there is, please fill me in. Always looking to improve. |
This comment has been minimized.
This comment has been minimized.
Nice read - love the last paragraph on "advancing the commons" :-) |
This comment has been minimized.
This comment has been minimized.
thank you for the step-by-step. straightforward how-to's are difficult to find while i'm learning to program :) i'm looking thru some of your github repos (particularly their early commits), and i recognize some of this list in practice. do you have a single repo that you would recommend as a "shining example" that i can refer to while learning? |
This comment has been minimized.
This comment has been minimized.
I love this! Does searching for existing modules that accomplish what you want to do fit into your workflow (or your vision of a generalized application or module development workflow)? In other words, do you wind up using primarily your own modules? If so is it because their purposes are specific to your style of building things, or because they're specific to the things you're building and are fulfilling new purposes? And if not, do you have any tricks for balancing the tradeoffs of getting to know other peoples' modules vs building/remembering your own? Thanks! |
This comment has been minimized.
This comment has been minimized.
I absolutely look for existing modules first using a bunch of |
This comment has been minimized.
This comment has been minimized.
re-posted to my new blog: http://substack.net/how_I_write_modules |
This comment has been minimized.
This comment has been minimized.
Hey James, nice post |
This comment has been minimized.
This comment has been minimized.
Finally, illustrate the readme! |
This comment has been minimized.
This comment has been minimized.
@substack what irc channels do you ask around on? |
This comment has been minimized.
This comment has been minimized.
Writing such modules is a difficult task. We had such an assignment in the college, but not all students were able to do this. Many of them had to pay for writing an essay on the site www.papersowl.com. The main advantage of this service is the high quality of work, as well as convenient online payment of any order. I recommend this service to every student. |
This comment has been minimized.
This comment has been minimized.
exactly! |
This comment has been minimized.
That's nearly the same way, I do it. The hardest/longest step in this approach is to find a good name for the new module.