Saving time with Prettier

Agenda

  • What Prettier is
  • Why you should use it
  • Examples
  • How to use

Prettier

  • Code formatter
  • Used by iPlayer web since Jan 2019

Prettier

export const fullScreenSelector = createSelector([getFullscreen], (fullscreen) => fullscreen);

Prettier

export const fullScreenSelector = createSelector(
  [getFullscreen],
  fullscreen => fullscreen
);

Why?

  • Formatting makes code easier to read
  • Manual formatting is time consuming
  • Other solutions didn't cut it

Manually

function restoreScript( elem ) {
	if ( ( elem.type || "" ).slice( 0, 5 ) === "true/" ) {
		elem.type = elem.type.slice( 5 );
	} else {
		elem.removeAttribute( "type" );
	}

	return elem;
}

JSLint/ JSHint

  • Web apps
  • CLI tool (JSHint)

eslint

  • Analyzes code
  • Configurable
  • Has rules for formatting
  • Can autofix

But ...

  • Limited formatting rules
  • Can't handle multiline formatting
  • Requires so much config!

Result

  • Nitpick PR comments
  • Wasted time checking formatting
  • Wasted time choosing rules
  • Red squigglies

Red squiggilies

Prettier is not a replacement for eslint

  • eslint for static analysis
  • Prettier to format

Prettier

  • Formats code across multiple lines
  • Opinionated
  • Supports loads of languages!
  • Little configuration

Our config

module.exports = {
  singleQuote: true,
  arrowParens: 'always'
};

Examples

The 😁

export default function dialsReducer(state: DialsState = initialState ): DialsState {
  if (action.type === DIALS_SET_DIALS) {
  return {
    ...action.payload
  }
  }
  return state
}
export default function dialsReducer(
  state: DialsState = initialState
): DialsState {
  if (action.type === DIALS_SET_DIALS) {
    return {
      ...action.payload
    };
  }
  return state;
}

The 😁

export interface ConfigState {
  readonly staticAssetsPath: string;
  readonly host: string
  readonly iblBaseUrl: string,
}
export interface ConfigState {
  readonly staticAssetsPath: string;
  readonly host: string;
  readonly iblBaseUrl: string;
}

The 😁

|          |    |
| -------- | ---|
| Service| Node|
| Platform| Cosmos|
| Language| Node|
|          |        |
| -------- | ------ |
| Service  | Node   |
| Platform | Cosmos |
| Language | Node   |

The 😐

function mapDispatchToProps(dispatch) {
  return {
    showDownloadModal: () => dispatch(setModalVisiblity(ModalType.Download, true)),
    toggleAdded: () => dispatch(toggleAdded())
  };
}
function mapDispatchToProps(dispatch) {
  return {
    showDownloadModal: () =>
      dispatch(setModalVisiblity(ModalType.Download, true)),
    toggleAdded: () => dispatch(toggleAdded())
  };
}

The 😐

export const LONG_LIFE_PID_WITH_SUBTITLE = '/iplayer/episode/p00y1h7j/adventure-quest-under-capricorn-5-bush-walkabout';
export const LONG_LIFE_PID_WITH_SUBTITLE =
  "/iplayer/episode/p00y1h7j/adventure-quest-under-capricorn-5-bush-walkabout";

The 😖

const str = `bbc-ipd:download/${episode.id}/${version.id}/${quality}/${downloadKind}/${completeTitleEncoded}/${episode.tleoId}/${titleEncoded}`;
const str = `bbc-ipd:download/${episode.id}/${
  version.id
}/${quality}/${downloadKind}/${completeTitleEncoded}/${
  episode.tleoId
}/${titleEncoded}`;

But it's worth it

How to use?

yarn add --dev prettier

Install ...

{
  // ..
  "scripts": {
    // ..
    "format": "prettier --write '**/*.{js,json,jsx,md}'",
    "format:check": "prettier --check '**/*.{js,json,jsx,md}'"
  }
}

Add script

Update eslint config

// .eslintrc
{
  "root": true,
  "extends": [
    "standard",
    "prettier",
    "prettier/standard"
  ]
}

Config

My vision ...

Prettier used by everyone

  • No time spent formatting
  • No time spent on nitpicks
  • No time spent discussing rules
  • Only useful squiggilies

Questions?

Made with Slides.com