If you want to have a general introduction how to write such a codemod have a look at this Gist from me.
Place the usage.js
and prettiermod.js
in the root of the project. Run:
$ pnpm add globby@^11.0.0 @babel/traverse
If you want to have a general introduction how to write such a codemod have a look at this Gist from me.
Place the usage.js
and prettiermod.js
in the root of the project. Run:
$ pnpm add globby@^11.0.0 @babel/traverse
Every now and then I'd like to apply a so called codemod to my a codebase. A codemod is a piece of code which modifies other code. Very often this is done by running some transformation on the abstract syntax tree (AST).
Whenever I need to do this I look for "What is the best way to apply a codemod on my TS code base right now?", because when I only do this every couple of month I either have forgotten about how to do it or tools have changed and my old way stopped working... or both. Surprisingly every time I search for that I found the existing tools bloated or quirky or not matching my workflow.
As I already use Babel to compile our source code I would like to create a Babel plugin which transforms my code. Sadly Babel alone is not good in preserving whitespace and formatting. Thankfully I use Prettier for that and because Prettier uses Babel internally I can create a Babel visitor to transform my source code.
The actually easiest and _most r
function getNiceUpperBound(value: number) { | |
const zeroCount = String(Math.round(value)).length - 1; | |
const factor = Math.pow(10, zeroCount); | |
return Math.ceil(value / factor) * factor; | |
} | |
const upperBound = getNiceUpperBound(3464634); // 4000000 |
import { DependencyList, useState, useEffect, useRef } from 'react'; | |
// use this instead of useMemo of you need a stable value | |
// see https://twitter.com/0xca0a/status/1314326386555924480 | |
export function useStableMemo<T>(factory: () => T, deps: DependencyList): T { | |
const [value, setValue] = useState<T>(factory); | |
const firstRun = useRef(true); | |
useEffect( | |
() => { |
import { useState, useEffect } from 'react'; | |
import { useLocation, useHistory } from 'react-router-dom'; | |
import { useSessionStorage } from './use-storage'; // see https://gist.github.com/donaldpipowitch/7310d7b9e4b6d467134c425e8732adc6 | |
type UseLocationStateOptions<T> = { | |
defaultValue?: T; | |
scope?: string; | |
filter?: (value: T) => boolean; | |
}; |
import React, { FC, useMemo } from 'react'; | |
import { | |
LocalStorageProvider, | |
SessionStorageProvider, | |
} from './use-storage'; | |
// this is just a dumb mock of the storage interface | |
class MemoryStorage implements Storage { | |
private data: Record<string, string> = {}; |
// @ts-check | |
/** @type {import("eslint").Rule.RuleModule} */ | |
const rule = { | |
meta: { | |
docs: { | |
description: `If you use a Jest test name like "hello (world)" you can't run \`$ jest -t "hello (world)"\` to select this test.`, | |
}, | |
fixable: 'code', | |
}, |
// @ts-check | |
/** @type {import("eslint").Rule.RuleModule} */ | |
const rule = { | |
meta: { | |
docs: { | |
description: `You can export a type and a value with the same name in the same file, but that confuses refactoring tools.`, | |
}, | |
}, | |
create(context) { |
Know your brackets!
( ) – parentheses, round brackets, first brackets
{ } – braces, curly brackets, second brackets, moustache brackets 👨🏻
[ ] – square brackets, third brackets
⟨ ⟩ - angle brackets (aka. _not_ less-than/greater-than signs 👀)
‹ › - angle quotes (aka. _not_ less-than/greater-than signs 👀)
< > - less-than/greater-than signs
import { | |
CognitoUserPool, | |
CognitoUserAttribute, | |
CognitoUser, | |
AuthenticationDetails, | |
CognitoUserSession, | |
CodeDeliveryDetails, | |
} from 'amazon-cognito-identity-js'; | |
import React, { FC, useState } from 'react'; |