Javascript: Provide alternate solution for no-underscore-dangle

Created on 8 May 2017  Â·  21Comments  Â·  Source: airbnb/javascript

I don't want to argue whether no-underscore-dangle is good or not (#1089 and #1024 have that covered), but as since I'm quite new to this whole ES6 thing, I'd appreciate it if the readme provided some guidance on how to handle private variables.

question

Most helpful comment

@ranneyd See the docs: you can specify allow: ['_id']

All 21 comments

The current guidance is to architect such that you don't need them.

When the language gets actual private fields (and airbnb’s supported browsers support them or their transpiled version), the guide will be amended to suggest using those instead.

@ljharb what are your thoughts on the following use case -

What is the recommended approach for doing DI with external modules? (https://codesandbox.io/s/D9r9GyxmB)

e.g. consider

// foo.js
export const Foo = 'i am foo';

// index.js
import { Foo } from "./foo";

const main = (_Foo = Foo) => {
  console.log(_Foo);
};

The alternatives I can think of are:

  • Rewrite the import statement:
import { Foo as SomethingElse } from "./foo";

const main = (Foo = SomethingElse) => {
  console.log(Foo);
};

Thoughts: I personally would rather not rewrite the import statement for every thing I want to inject and maintain that mapping

  • Rename the argument:
import { Foo } from "./foo";

const main = (SomethingElse = Foo) => {
  console.log(SomethingElse);
};

Thoughts: I would like to do the last altering of the variable name as possible, to make it as clear as possible in code as to what I'm calling


There's already a convention for the _ prefix to signify function scoped variables I think? Which is why I leaned towards using _ here.

I definitely agree with the reasoning given to disallow _ in general. Do you think this is any different? Or would making an exception for this just make things confusing? Or is this bad too? How do I javascript?!

@magicmark the convention for _ has nothing to do with scope; all variables prior to ES6 had function scope. _ is only a convention on object property names to indicate that the author would really really pretty please like you to consider this fully public property "private".

"Dependency Injection" in JS is just "function arguments"; if you want to have a dependency be an argument to a function, that's fine. That's utterly unrelated to how those arguments should be named.

_ is only a convention on object property names

Seems I misunderstood what the convention was. No further questions then. Thanks! :D

Our backend is giving us data from mongodb, which saves its primary keys as _id. Every time we get _id from these objects, eslint yells at us :'(

@ranneyd See the docs: you can specify allow: ['_id']

Is there an easy way to allow _id globally for all files rather than having to add /*eslint no-underscore-dangle: ["error", { "allow": ["_id"] }]*/ to all places it's used? :thinking:

[edit]
Figured it out, could add it like this in the rules section in eslint config:
"rules": { "no-underscore-dangle": [2, {"allow": ["_id"]}] }

This seems fully answered.

I know this issue was closed already, but how does Airbnb handle the no-shadow rule in the context of mapDispatchToProps? It seems like the obvious answer would be to indicate the inner scope using a dangling underscore. Do you have a better alternative?

The issue of how to "architect such that you don't need [privacy]" seems like enough of a conundrum to offer some guidance.

@jeremygottfried I’m not sure why mapDispatchToProps would be any different; you’re never forced to use any specific variable or argument names.

@ljharb This is a matter of semantics and assumptions about code. Libraries document which variables are part of their public API and which should be left alone. I think it's fair to assume that you're swimming at your own risk if you access undocumented parts of a library. I quickly learned this when I accessed one of google maps' "private" variables and they changed that variable a couple weeks later. I'm just wondering why this is such a big issue that you insist on enforcing it as a rule for tens of thousands of developers?

@jeremygottfried documentation is irrelevant; everything reachable is public. The experience you've described is google being user-hostile, not you making a mistake.

@ljharb Bugs arise and updates need to happen. Library versions are backwards compatible only to the extent of the public documentation. Every exported module/variable is reachable. Does airbnb expect every reachable variable/method in a library to be permanent and stable?

Yes, or else there’d need to be a semver major bump.

I don't think I've ever seen a library that follows the semver rules that broadly, though I commend your idealism. I think for most people, it's logistically a big expectation.

  1. Software using Semantic Versioning MUST declare a public API. This API could be declared in the code itself or exist strictly in documentation. However it is done, it SHOULD be precise and comprehensive.

The first rule in semantic versioning specification dictates that as a developer, you have the option to declare the API in the code itself OR strictly in documentation.

In practice, relying on docs to make public things “private” breaks users. As an opinionated guide, we intentionally force a stricter, non user hostile, approach.

@ljharb Semver is a great parallel example. Semver is a semantic convention-- v1.0.0. Users interpret the intent of a change-- Major.Minor.Patch based on where the number changes. Code doesn't inherently map to semver, but as developers we agree to follow the specifications to improve user experience. Similarly, an underscore is a semantic convention that communicates privacy. We have agreed on this as a community to make life easier for all of us, so that we don't mistake code as part of the public API. Both semver and underscore are semantic conventions. Why are you ok with one and not the other?

We have certainly not all agreed on it; npm broke node once by changing an underscored property in a non major. Treating reachable things as private breaks people.

At any rate, if you disagree with the linting config or the guide, you are free to fork the guide or override the config. Underscored properties aren’t likely to become permitted by this guide, especially since real private fields are shipping in browsers.

Was this page helpful?
0 / 5 - 0 ratings