Hacker Newsnew | past | comments | ask | show | jobs | submitlogin

What is the best and most modern way to write a module where you have public and private functions and data?


I'd say you might need to be more specific with your phrasing.

If you want replicate more class-like behavior (but without actual class/inheritance information):

- Some type of exported constructor function

- The function instantiates an instance of data internally that is possibly mutable (let vs const)

- That function returns an object/interface of functions that have access to that data by virtue of it being defined in a higher but accessible function scope

- All other private functions are simply not exported

Or you might mean singleton data:

- let or const data at the file/module scope level

- export functions to operate on the data

- Don't export functions you want to be private

The first is sort of reinventing a class instance, but if you are anti-inheritance for the most part (likely a good idea), then you can use a "kind" or "type" property on the returned constructed plain object if needed (TypeScript generics make this quite ergonomic to represent as well). So, you don't really need classes, but they have their uses and have familiar and comfortable syntax to programmers from other languages. You can use either and they are both accepted as idiomatic.

I usually still allow classes in codebases that I have some control over, but add a custom ESLint rule to ban extension unless with an ignore comment. This sort of encourages you to compose more like the functional/data approach, but allows you to still use instanceof since it's an actual class. It also means you're not creating a copy of all the method functions if you don't need to between instances.

There is a caveat that there is a class syntax:

method = () => {}

That auto-binds the method to this, creating that method copy for all. In this case you're encroaching on the plain object behaviour, again with a more familiar syntax.

So, I guess it's more messy than I thought reflecting on it. But you have some choices depending on what properties you'd like to encourage in your codebase.


Context is if I am writing a node app from scratch in JavaScript, I’d like to use all the best practices for laying out my code.

With so many options, it’s hard to know what you’re doing is “right” and to setup the appropriate lints and whatnot.


classes have the # prefix for private members and TS has the private keyword.

If you don’t want to go with classes, not exporting a value or a function from a module is almost the same. The rest can be done with closures.


Is there a “canonical” example of a module that is written well and uses what most would consider best practices?

When looking through npm modules, there still seems to be a variety of approaches.


Canonical? Best practices? Not that I’m aware of. Not in Node.

Deno has some ideas though:

> Don’t import any symbol with an underscore prefix: export function _baz() {}.

> Don’t link to / import any module whose path […] Has a name or parent with an underscore prefix: _foo.ts, _util/bar.ts.

https://deno.land/std@0.204.0




Guidelines | FAQ | Lists | API | Security | Legal | Apply to YC | Contact

Search: