npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2024 – Pkg Stats / Ryan Hefner

eslint-config-jessy

v0.1.0

Published

Jessy JavaScript Style - ESLint Shareable Config

Downloads

6

Readme

Jessy, A Javascript Coding Style

travis npm downloads

Just another Javascript coding style with an eslint shareable config.

Install

  npm install --save-dev eslint-config-jessy

Then inside your .eslintrc.js file, you can write

{ extends: 'jessy' // https://github.com/lucidogen/jessy
, 'rules':         // add your custom rules here
  {
  }
}

Motivation

With the release of Javascript ES2015 (ES6), we can take the chance to change some habits regarding the code we write in Javascript, especially regarding punctuation. For this 'exercise', let's try to view Javascript as a totally new language and not let ourselves driven away by styling rules that seem weird at first sight.

Javascript is not english. We do not write phrases ending with dots or use parenthesis, commas and semicolon in the same way as in english (or french or any spoken language). We can stick to the old conventions for any good or bad reason, but with this document, we felt it could be fun to read the Javascript specs and get the most out of it in terms of:

  • Readability

Adding spaces between expressions adds visual identification of the elements and helps readability. This means adding a space before and after parenthesis, around symbols and other punctuation marks.

  • Scope readability

Some eyes are not perfect balls (astigmatism) so it is hard for some people to align things with identation. We should try to help by having some kind of consistency between opening and closing scope character positioning. Basically, it should look obvious if we missed out a comma or some punctuation or if we replaced a brace with a parenthesis or vice versa. This is particularly true for the actual trend in 'declarative Javascript' where we find ourselves often defining objects and less often writing procedural code.

  • Refactoring ease

If we need to move code around, we should not need to change too much punctuation or indentation in order to 'sit' this code in the new context.

  • Single line commit changes

It is nice if we can keep changes from spilling on lines not really concerned by the change. For example, adding an element in a list should not make it as if we changed neighboring elements in the same operation.

  • Orthogonality

This goal is to try to find a styling guide that is as consistent as possible across conditionals, object definitions, callbacks, etc.

Proposal

So here is the proposal. If you feel there is something that can be enhanced regarding the goals above, please send a pull request.

Object definition

Very short objects can be defined on a single line as so:

let foo = { title: 'hello' }

Longer objects should be defined on multiple lines, with commas at the start of each element. In this manner, all punctuation for the object definition align (opening curly bracket, commas and closing curly bracket). Note that we are not indenting the first curly bracket.

let person = 
{ firstName: 'John'
, lastName:  'Difool'
, age:       45
}

Nested object definitions should follow the same rule, with increasing indentation corresponding to nesting depth.

let effect =
{ fx: 'mix'
, mix: 0.5
, source1:
  { fx: 'video'
  , src: '/my/crazy/cat.mp4'
  , rate: 0.6
  }
, source2:
  { fx: 'quasicrystals'
  , saturation: 0.8
  }
}

Object definition with functions should follow the same rules.

let handler =
{ url: '/foo/bar/baz'
, callback ( msg ) {
    console.log ( 'Receiving', msg.url, msg.value )
  }
}

Conditional

We use 'stroustrup' brace style for functions and conditionals. Regarding parenthesis, we use spaces just as with object definitions (more on parenthesis further down).

if ( hero.isHome ) {
  hero.rest ()
  hero.giveSomeLove ()
}
else {
  hero.explore ( World )
}

Single line blocks in conditionals can be simplified by removing curly braces. But execution block never goes on the same line as the condition.

if ( hero.isHome )
  hero.rest ()
else
  hero.explore ( World )

Function definition

Function definitions look similar to conditionals. The function keyword and parameters should be on the same line as the equal sign if there is one.

const setup = function ( params ) {
  console.log ( 'Starting setup...' )
  callMum ()
  sayHelloToDad ( params.wordOfTheDay )
  makeCoffee ()
}

When using return with a new object, we need to bend the rules a little since we cannot simply describe the object on the next line. In this case, we put the opening brace with the return statement.

export function mockUser ( firstName, lastName ) {
  return {
    firstName
  , lastName
  , login: firstName
  , password: 'testing'
  }
}

When returning a complex expression, we should split it into multiple lines, aligning elements after the return keyword.

let test = function ( a, b, c, d ) {
  return a
      && b
      && ! c
      && d
}

Arrow function

Without a block, these are treated like any expression. With a block, we consider them like function definitions:

let foo = bar.map ( e => e.replace ( /foo/, 'bar' ) )
const setup = ( params ) => {
  console.log ( 'Starting setup...' )
  callMum ()
  sayHelloToDad ( params.wordOfTheDay )
  makeCoffee ()
}

let foo = baz.map
( ( e, i ) => {
    let name = ID_TO_NAME [ e ]
    return `param ${ i }: ${ name }`
  }
)

Try / catch

These are treated like conditionals, with the block starting on the next line.

try {
  doThis ()
  doThat ()
}
catch ( e ) {
  rescueThat ( e )
}

An empty 'catch' will have both curly braces on the next line. Having an empty catch can usually be avoided and makes the code easier to read.

Function call

Long function calls should go on multiple lines. Create a newline after the function name in case of assignment. This makes code slightly more readable and avoids too many lines with a single variable or function name:

let compiledWrapper = runInThisContext ( wrapper, { filename: filename } )

// or

let compiledWrapper = runInThisContext
( wrapper
, { filename: filename
  , more: options
  , blah: blih
  }
)

Chained calls are either contained on a single line (rare case) or split on different lines, new calls should start on the same line as the first call.

this.get ( 'model' )
.set ( 'title', title )
.set ( 'description', description )

Accessing object properties

We treat square brackets in the same manner as parenthesis or curly braces:

let c = components [ name ]

String interpolation

Use a space around interpolated elements.

throw new Error
( `Cannot watch path '${ path }' (not a relative or absolute path).` )

Real-world example

Here are some examples in order to evaluate if the desired goals are or seem to be reached by comparing some real-world examples.

Defining an animation in Ember's Liquid-fire.

// Jessy style
import { animate, stop, Promise } from 'liquid-fire'

export default function crossFade ( opts = {} ) {
  stop ( this.oldElement )
  return Promise.all
  ( [ animate
      ( this.oldElement
      , { opacity: 0 }
      , opts
      )
    , animate
      ( this.newElement
      , { opacity: [ opts.maxOpacity || 1, 0 ] }
      , opts
      )
    ]
  )
}

Compared to:

// Classic style
import { animate, stop, Promise } from 'liquid-fire';

export default function crossFade(opts = {}) {
  stop(this.oldElement);
  return Promise.all([
    animate(this.oldElement, {opacity: 0}, opts),
    animate(this.newElement, {opacity: [opts.maxOpacity || 1, 0]}, opts)
  ]);
}