Skip to content

Commit

Permalink
feat: rename all hook implementation files to index.ts (#1065)
Browse files Browse the repository at this point in the history
feat: replace named hook files with index.ts

After some reconsideration - cjs bundle is back! At the moment of time pure ESM requires too much hustle around it therefore we decided to bring CJS back

BREAKING CHANGE: all current hook implementation fies renamed to index to allow usage of directory imports and avoid redundant reexporting.
Such change breaks previous direct imports, but simplifies import string and solves redundant hook name duplication.

4ex:
```
// previously
import { useUpdate } from "@react-hookz/web/useUpdate/useUpdate"

// now
import { useUpdate } from "@react-hookz/web/useUpdate"
```
  • Loading branch information
xobotyi authored Jan 5, 2023
1 parent fcbfc78 commit 34c36f2
Show file tree
Hide file tree
Showing 88 changed files with 760 additions and 732 deletions.
5 changes: 2 additions & 3 deletions .github/workflows/ci-cd.yml
Original file line number Diff line number Diff line change
Expand Up @@ -55,9 +55,8 @@ jobs:
- name: "Build"
run: yarn build

# ToDo: uncomment when https://github.com/facebook/jest/issues/13715 will be fixed
# - name: "Tests against build"
# run: yarn jest --selectProjects dom-package
- name: "Tests against build"
run: yarn jest --selectProjects dom-package

test:
name: "Test"
Expand Down
3 changes: 2 additions & 1 deletion .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -2,4 +2,5 @@
node_modules
/coverage
/storybook-build
/dist
/cjs
/esm
3 changes: 2 additions & 1 deletion .npmignore
Original file line number Diff line number Diff line change
@@ -1,2 +1,3 @@
*
!/dist
!/cjs
!/esm
59 changes: 32 additions & 27 deletions CONTRIBUTING.md
Original file line number Diff line number Diff line change
Expand Up @@ -27,55 +27,60 @@ If you are contributing for the first time, we recommend reading this
> git branch --set-upstream-to=upstream/master master
> ```
>
> After running these commands you'll be able to easily pull changes from the original repository with
> After running these commands you'll be able to easily pull changes from the original repository
> with
> `git pull`.
## Development
0. Perform self-check on hook usefulness. We're not interested in hooks that has too specific
usecase or hooks that can be easily achieved by composition of existing hooks.
1. Implement the hook in the `src` folder.
- The file should be named after the hook and placed in a subdirectory also named after the hook.
- The file with hook implementation should be named `index.ts` and placed in a subdirectory
named after the hook.
- The hook should have return types explicitly defined.
- The hook should have a JSDoc comment containing a description of the hook and an overview of its arguments.
- The hook should be exported by name, not by default.
- If the hook has custom types in its parameters or return values, they should be exported as well.
- Types and interfaces should not have prefixes like `I` or `T` (currently some types like this
still exists for compatibility reasons, but they will be removed in the future).
- The hook should be developed with SSR in mind.
- If the hook is stateful and exposes `setState` method, or is has async callbacks (that can
theoretically be resolved after component unmount), it should use `useSafeState` instead of
`useState`.
- If your hook reuses other @react-hookz/web hooks, import them as `import { useSafeState } from '../useSafeState/useSafeState';` instead of
- The hook should have a JSDoc comment containing a description of the hook and an overview of
its arguments.
- The hook should be exported by name, not default-exported.
- If the hook has custom types in its parameters or return values, they should be exported as
well.
- Types and interfaces should not have prefixes like `I` or `T`.
- The hook should be developed with SSR in mind, meaning that usage of hook in SSR environment
should not lead to errors.
- If your hook reuses other @react-hookz/web hooks, import them as
`import { useSafeState } from '../useSafeState';` instead of
`import { useSafeState } from '..';`
2. Re-export the hook implementation and all its custom types in `src/index.ts`.
3. Fully test your hook. The tests should include tests for both DOM and SSR environments.
- Hook's tests should be placed in `__tests__` subdirectory, next to the source file - `dom.ts` for DOM
environment, `ssr.ts` for SSR environment.
For example: `src/useFirstMountState/__tests__/dom.ts` and `src/useFirstMountState/__tests__/ssr.ts`.
- Ideally, your hook should have 100% test coverage. If that is impossible, you should leave a comment
in the code describing why.
- Each hook should have at least 'should be defined' and 'should render' tests in `SSR`
- Hook's tests should be placed in `__tests__` subdirectory, next to the source file - `dom.ts`
for DOM environment, `ssr.ts` for SSR environment.
For example: `src/useFirstMountState/__tests__/dom.ts`
and `src/useFirstMountState/__tests__/ssr.ts`.
- Ideally, your hook should have 100% test coverage. If that is impossible, you should leave a
comment in the code describing why.
- Each hook should have at least `'should be defined'` and `'should render'` tests in `SSR`
environment.
- All utility functions should also be tested.
4. Write docs for your hook.
- Docs should be placed in `__docs__` sub-folder, near the source file.
For example: `src/useFirstMountState/__docs__/story.mdx`.
- Docs are built with Storybook. You can run `yarn storybook:watch` to preview your work.
- Write a short example demonstrating your hook in `example.stories.tsx` within the `__docs__` folder.
(If the filename misses the `.stories.tsx` part, Storybook won't find your example.)
- Write a short example demonstrating your hook in `example.stories.tsx` within the `__docs__`
folder. (If the filename misses the `.stories.tsx` part, Storybook won't find your example.)
For example: `src/useFirstMountState/__docs__/example.stories.tsx`.
- Docs are written in MDX format.
- Docs are written in MDX format.
[Read more about storybook docs](https://storybook.js.org/docs/react/writing-docs/introduction).
5. Add a summary of the hook and a link to the docs to `README.md`.
6. After all the above steps are done, run `yarn lint:fix` to ensure that everything is styled by our
standards.
6. After all the above steps are done, run `yarn lint:fix` to ensure that everything is styled by
our standards and there are no linting issues.
7. `yarn new-hook myAwesomeHook` will help you to create a proper file structure for the new hook.
### Notes on porting a hook from `react-use`
- Check from #33 and the [migration guide](src/__docs__/migrating-from-react-use.story.mdx)
that the hook has been approved for porting. If there is no previous discussion on the hook in #33,
leave a comment there asking if you could port the hook. In your comment, provide a valid use-case
for the hook.
- Check from #33 and the [migration guide](src/__docs__/migrating-from-react-use.story.mdx) that the
hook has been approved for porting. If there is no previous discussion on the hook in #33, leave a
comment there asking if you could port the hook. In your comment, provide a valid use-case for the
hook.
- Don't just copy-paste the hook. Think through the code:
- Is there sufficient tests?
- Could the hook be implemented by reusing existing hooks in `@react-hookz/web`?
Expand Down
13 changes: 7 additions & 6 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -36,10 +36,9 @@ Also, as React does not support IE, `@react-hookz/web` don't either.

## Usage

> This package distributed with ESNext language level and ES modules syntax. It helps us to ease the
> support and provide you with the best hooks quality.
> But also this means that depending on your browser target and bundling configuration you might need
> to transpile it. Every major bundler provides a way to transpile `node_modules` fully or partially.
> This package distributed with ESNext language level and both, CJS and ES imports.
> It means that depending on your browser target you might need to transpile it. Every major
> bundler provides a way to transpile `node_modules` fully or partially.
> Address your bundler documentation for more details.
You can import hooks two ways:
Expand All @@ -48,11 +47,13 @@ You can import hooks two ways:
// from the root of package
import { useMountEffect } from '@react-hookz/web';
// or single hook directly
import { useMountEffect } from '@react-hookz/web/useMountEffect';
import { useMountEffect } from '@react-hookz/web/esm/useMountEffect';
```

In case your bundler supports tree-shaking (most of modern does) - both variants are equal and only
necessary code will get into your bundle. Direct hook imports should be considered otherwise.
necessary code will get into your bundle. Direct hook imports should be considered otherwise.
In case, for some reason, you are not able to use ES imports - you should direct-import hooks from
`@react-hookz/web/esm` folder.

## Migrating from react-use

Expand Down
20 changes: 9 additions & 11 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -21,22 +21,20 @@
"access": "public"
},
"files": [
"dist"
"cjs",
"esm"
],
"main": "dist/index.js",
"types": "dist/index.d.ts",
"module": "dist/index.js",
"esnext": {
"browser": "dist/index.js",
"module": "dist/index.js"
},
"main": "./cjs/index.js",
"types": "./cjs/index.d.ts",
"module": "./esm/index.js",
"sideEffects": false,
"scripts": {
"prepare": "husky install",
"commit": "git-cz",
"build": "yarn build:cleanup && yarn build:dist",
"build": "yarn build:cleanup && concurrently yarn:build:cjs yarn:build:esm",
"build:cleanup": "rimraf ./dist",
"build:dist": "ttsc -p ./tsconfig.build.json",
"build:cjs": "ttsc -p ./tsconfig.build.json --module CommonJS --outDir ./cjs",
"build:esm": "ttsc -p ./tsconfig.build.json --module ESNext --outDir ./esm",
"new-hook": "node ./utility/add-new-hook.js",
"test": "jest --selectProjects dom ssr",
"test:coverage": "yarn test --coverage",
Expand Down Expand Up @@ -101,14 +99,14 @@
"@swc/core": "^1.3.24",
"@swc/jest": "^0.2.24",
"@testing-library/react-hooks": "^8.0.1",
"@testing-library/user-event": "^14.4.3",
"@types/jest": "^29.2.5",
"@types/js-cookie": "^3.0.2",
"@types/react": "^18.0.17",
"@types/react-dom": "^18.0.6",
"babel-loader": "^9.1.2",
"commitizen": "^4.2.6",
"commitlint": "^17.4.0",
"concurrently": "^7.6.0",
"husky": "^8.0.3",
"jest": "^29.3.1",
"jest-environment-jsdom": "^29.3.1",
Expand Down
2 changes: 1 addition & 1 deletion src/__docs__/ImportPath.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ export const ImportPath: FC<ImportPathProps> = ({ root = true, direct = true })

if (direct) {
imports.push(
`// direct import\nimport { ${componentName} } from '@react-hookz/web/${componentName}';`
`// direct import\nimport { ${componentName} } from '@react-hookz/web/esm/${componentName}';`
);
}

Expand Down
15 changes: 8 additions & 7 deletions src/__docs__/Introduction.story.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -41,23 +41,24 @@ transpile your `node-modules` in order to run in IE.

## Usage

> This package distributed with ESNext language level and ES modules syntax. It helps us to ease the
support and provide you with the best hooks quality.
> But also this means that depending on your browser target and bundling configuration you might need
to transpile it. Every major bundler provides a way to transpile `node_modules` fully or partially.
Address your bundler documentation for more details.
> This package distributed with ESNext language level and both, CJS and ES imports.
> It means that depending on your browser target you might need to transpile it. Every major
> bundler provides a way to transpile `node_modules` fully or partially.
> Address your bundler documentation for more details.
You can import hooks two ways:

```ts
// from the root of package
import { useMountEffect } from '@react-hookz/web';
// or single hook directly
import { useMountEffect } from '@react-hookz/web/useMountEffect';
import { useMountEffect } from '@react-hookz/web/esm/useMountEffect';
```

In case your bundler supports tree-shaking (most of modern does) - both variants are equal and only
necessary code will get into your bundle. Direct hook imports should be considered otherwise.
necessary code will get into your bundle. Direct hook imports should be considered otherwise.
In case, for some reason, you are not able to use ES imports - you should direct-import hooks from
`@react-hookz/web/esm` folder.

## Migrating from react-use

Expand Down
Loading

0 comments on commit 34c36f2

Please sign in to comment.