Skip to content

Latest commit

 

History

History
214 lines (151 loc) · 4.7 KB

best-practices.md

File metadata and controls

214 lines (151 loc) · 4.7 KB

Javascript / Best practices

Avoid exporting an object for the purpose of exporting its properties

Axel Rauschmayer:

Note that default-exporting objects is usually an anti-pattern (if you want to export the properties). You lose some ES6 module benefits (tree-shaking and faster access to imports).

Instead, prefer breaking up the code into separate default exported modules or use named exports. See also:

BAD

export default { a, b, c };

GOOD

export a;
export b;
export c;

GOOD

// a.js
export default a;

// b.js
export default b;

// c.js
export default c;

Avoid exporting mutable objects and mutating imported objects

https://geedew.com/es6-module-gotchas/

ES6 modules were designed with a static module structure preferred. This allows the code to be able to discover the import/export values at compile time rather than runtime. Exporting an object from a module allows for unexpected situations and removes the static compilation benefits.

See also:

Avoid exporting an evaluation

In this case the module exports the result which is only evaluated once. This is rarely the desired outcome, but if it is, a Singleton pattern should be used instead. Some ES6 module benefits are lost, it makes imports slower and makes them possible to cause side-effects which should rather happen upon invocation.

Instead, export a function or class.

See also:

BAD

export default someModule();

GOOD

export default someModule;
export default () => { someModule() };

Pass objects to console.log as separate parameters

GOOD

user = { name: "Albert" };
console.log("User:", user);
// => User: Object { name: "Albert" }

BAD

user = { name: "Albert" };
console.log(`User: ${user}`);
// => User: [object Object]

Comment dependencies in the package.json

As described here and here. E.g.

{
  "//dependencies": {
    "crypto-exchange": "Unified exchange API"
  },
  "dependencies": {
    "crypto-exchange": "^2.3.3"
  },
  "//devDependencies": {
    "chai": "Assertions",
    "mocha": "Unit testing framwork",
    "sinon": "Spies, Stubs, Mocks",
    "supertest": "Test requests"
  },
  "devDependencies": {
    "chai": "^4.1.2",
    "mocha": "^4.0.1",
    "sinon": "^4.1.3",
    "supertest": "^3.0.0"
  }
}

Specify npm version requirements to avoid package-lock ping-pong

See: https://stackoverflow.com/a/55373854/2771889

package.json

{
  "engines": {
    "npm": ">=6.6"
  }
}

.npmrc

engine-strict=true

Serialize objects when concatenating to strings

GOOD

const obj = {
  // ...
};

console.log("Uh! " + JSON.stringify(obj);

// => Uh! { ... }

BAD

const obj = {
  // ...
};

console.log("Uh! " + obj);

// => Uh! [object Object]

Name functions when exporting

Otherwise debugging information is lost.

Enable import/no-anonymous-default-export to report if a default export is unnamed.

GOOD

const foo = () => {
  console.trace();

  // ...
};

export default foo;

// foo @ foo.js:2
// ...

GOOD

export default function foo() {
  console.trace();

  // ...
}


// foo @ foo.js:2
// ...

BAD

export default () => {
  console.trace();

  // ...
};

// (anonymous) @ foo.js:2
// ...