Comparing version
{ | ||
"name": "tilg", | ||
"version": "0.0.1", | ||
"description": "A tiny logger.", | ||
"version": "0.1.0", | ||
"description": "A tiny logger hook for debugging React components.", | ||
"keywords": [ | ||
"react", | ||
"react hook", | ||
"logger", | ||
"debug" | ||
], | ||
"main": "index.js", | ||
"types": "dist/development.d.ts", | ||
"files": [ | ||
"LICENSE", | ||
"README.md", | ||
"dist/**" | ||
], | ||
"scripts": { | ||
"test": "echo \"Error: no test specified\" && exit 1" | ||
"build": "pnpm build:dev && pnpm build:prod", | ||
"build:dev": "tsup src/development.ts --dts --env.NODE_ENV development", | ||
"build:prod": "tsup src/production.ts --env.NODE_ENV production", | ||
"coverage": "vitest run --coverage", | ||
"test": "vitest" | ||
}, | ||
@@ -18,3 +34,16 @@ "repository": { | ||
}, | ||
"homepage": "https://github.com/shuding/tilg#readme" | ||
"homepage": "https://github.com/shuding/tilg#readme", | ||
"devDependencies": { | ||
"@types/node": "^17.0.23", | ||
"@types/react": "^18.0.0", | ||
"@types/react-test-renderer": "^17.0.1", | ||
"react": "^18.0.0", | ||
"react-test-renderer": "^18.0.0", | ||
"tsup": "^5.12.4", | ||
"typescript": "^4.6.3", | ||
"vitest": "^0.9.2" | ||
}, | ||
"peerDependencies": { | ||
"react": "^18.0.0 || ^17.0.0" | ||
} | ||
} |
303
README.md
@@ -1,1 +0,302 @@ | ||
# tilg | ||
# `useTilg` | ||
**Tiny Logger** is a magical React Hook to help you debug your components. | ||
<br/> | ||
## Table of Contents | ||
- Installation | ||
- Features | ||
- Lifecycle Events (What) | ||
- Component Name and Props (Who) | ||
- Debug Message (Why) | ||
- What Has Changed? (Why) | ||
- Quick Logs (Why) | ||
- Advanced Features | ||
- Markdown | ||
- Return Original Value | ||
- Auto Deduplication | ||
- CLI Support | ||
- FAQ & Caveats | ||
<br/> | ||
## Installation | ||
The package is released as `tilg`, use: | ||
```sh | ||
npm i tilg | ||
``` | ||
to install it with npm. Or you can choose another package manager. | ||
<br/> | ||
## Features | ||
### 1. Lifecycle Events (What) | ||
Simply insert the `useTilg()` hook into the component, and it will log the **render**, **mount**, **unmount** events in the console: | ||
```jsx | ||
import useTilg from 'tilg' | ||
function MyButton() { | ||
useTilg() | ||
return <button>Click me</button> | ||
} | ||
``` | ||
<p align=center> | ||
<img width="650" alt="lifecycle event logs" src="/screenshots/life-cycle-events.png"> | ||
<br/> | ||
<i>Logs of render and mount events.</i> | ||
</p> | ||
### 2. Component Name and Props (Who) | ||
You might noticed that it also displays the **name** and **props** of the component, which is very helpful for debugging. | ||
```jsx | ||
import useTilg from 'tilg' | ||
function MyButton({ text }) { | ||
useTilg() | ||
return <button>{text}</button> | ||
} | ||
function Title({ children }) { | ||
useTilg() | ||
return <h1>{children}</h1> | ||
} | ||
export default function Page() { | ||
return ( | ||
<> | ||
<Title>Welcome!</Title> | ||
<MyButton text='foo' /> | ||
<MyButton text='bar' /> | ||
</> | ||
) | ||
} | ||
``` | ||
When there’re multiple elements of the same component being rendered, it adds a counter `<MyButton/> (2)` for distinguishing so you know **who** is logging the information: | ||
<p align=center> | ||
<img width="650" alt="information logs" src="/screenshots/info.png"> | ||
<br/> | ||
<i>Information of the logged components.</i> | ||
</p> | ||
### 3. Debug Message (Why) | ||
Another critical thing is to know why does a component re-renders. `useTilg` gives you a simple but powerful API for this: | ||
```jsx | ||
import { useState } from 'react' | ||
import useTilg from 'tilg' | ||
function Counter() { | ||
const [count, setCount] = useState(0) | ||
useTilg()`count = ${count}` | ||
return <button onClick={() => setCount(count + 1)}>{count}</button> | ||
} | ||
``` | ||
When appending a [template literal](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Template_literals) after the `useTilg()` call, it will also log it as the debug message: | ||
```jsx | ||
useTilg()`count = ${count}` | ||
``` | ||
<p align=center> | ||
<img width="650" alt="debug message" src="/screenshots/message.gif"> | ||
<br/> | ||
<i>Logs of “count = ?”.</i> | ||
</p> | ||
You can also know where the message is from: | ||
<p align=center> | ||
<img width="650" alt="trace" src="/screenshots/trace.png"> | ||
<br/> | ||
<i>Trace of the message and a link to the code location.</i> | ||
</p> | ||
### 4. What Has Changed? (Why) | ||
Something troubles me a lot when debugging a component is, it’s sometimes hard to know which state has changed and triggered a re-render. `useTilg` tracks all the arguments in the debug message and tells you **which one has changed since the previous render**: | ||
```jsx | ||
import { useState } from 'react' | ||
import useTilg from 'tilg' | ||
function MyApp() { | ||
const [input, setInput] = useState('') | ||
const [count, setCount] = useState(0) | ||
useTilg()`input = ${input}, count = ${count}` | ||
return ( | ||
<> | ||
<input onChange={(e) => setInput(e.target.value)} value={input} /> | ||
<button onClick={() => setCount(count + 1)}>{count}</button> | ||
</> | ||
) | ||
} | ||
``` | ||
<p align=center> | ||
<img width="650" alt="changed argument" src="/screenshots/changed.png"> | ||
<br/> | ||
<i>A hint for the updated part.</i> | ||
</p> | ||
### 5. Quick Logs (Why) | ||
If you don't need a debug message but only want to quickly log some values, just pass them to the hook directly: | ||
```jsx | ||
import { useState } from 'react' | ||
import useTilg from 'tilg' | ||
function MyApp() { | ||
const [input, setInput] = useState('') | ||
const [count, setCount] = useState(0) | ||
useTilg(input, count) | ||
return ( | ||
<> | ||
<input onChange={(e) => setInput(e.target.value)} value={input} /> | ||
<button onClick={() => setCount(count + 1)}>{count}</button> | ||
</> | ||
) | ||
} | ||
``` | ||
<p align=center> | ||
<img width="650" alt="value without message" src="/screenshots/bare.png"> | ||
<br/> | ||
<i>Debug values quickly.</i> | ||
</p> | ||
<br/> | ||
## Advanced Features | ||
### Markdown | ||
You can use Markdown's code (`` ` ``), italic (`_` or `*`), and bold (`__` or `**`) syntax in your debug message to make it look nicer: | ||
```jsx | ||
function MyApp() { | ||
const [count, setCount] = useState(0) | ||
useTilg()`**Debug**: \`count\` = _${count}_.` | ||
return <button onClick={() => setCount(count + 1)}>{count}</button> | ||
} | ||
``` | ||
<p align=center> | ||
<img width="650" alt="markdown syntax" src="/screenshots/markdown.png"> | ||
<br/> | ||
<i>Markdown syntax in log messages.</i> | ||
</p> | ||
### Return Original Value | ||
The `useTilg()` hook also returns its **first argument**, or the **first value** in the template if specified, so you can quickly debug something in-place by wrapping it with `useTilg()`: | ||
```diff | ||
function MyApp() { | ||
const [count, setCount] = useState(0) | ||
return <button onClick={() => setCount(count + 1)}>{ | ||
+ useTilg(count) | ||
}</button> | ||
} | ||
``` | ||
<p align=center> | ||
<img width="650" alt="return original value" src="/screenshots/return-value.png"> | ||
<br/> | ||
<i>Log and return the original value.</i> | ||
</p> | ||
### Auto Deduplication | ||
Even if you have multiple `useTilg()` hooks in the same component, the lifecycle events will only be logged once per component: | ||
```jsx | ||
function MyApp() { | ||
const [input, setInput] = useState('') | ||
const [count, setCount] = useState(0) | ||
useTilg() | ||
useTilg()`input = ${input}` | ||
useTilg()`count = ${count}` | ||
return ( | ||
<> | ||
<input onChange={(e) => setInput(e.target.value)} value={input} /> | ||
<button onClick={() => setCount(count + 1)}>{count}</button> | ||
</> | ||
) | ||
} | ||
``` | ||
<p align=center> | ||
<img width="650" alt="deduplication" src="/screenshots/deduplication.png"> | ||
<br/> | ||
<i>Render, mount, and unmount events will not be duplicated even if you have multiple useTilg() hooks.</i> | ||
</p> | ||
### CLI Support | ||
If you are running your component during SSR, or running server-side tests, `useTilg()` properly outputs the result in Node.js CLI too: | ||
```jsx | ||
function App() { | ||
const [count, setCount] = useState(42) | ||
useTilg()`The answer is ${{ answer: count }}` | ||
return <button onClick={() => setCount(count + 1)}>{count}</button> | ||
} | ||
``` | ||
<p align=center> | ||
<img width="962" alt="deduplication" src="/screenshots/cli.png"> | ||
<br/> | ||
<i>Node.js CLI output.</i> | ||
</p> | ||
<br/> | ||
## FAQ & Caveats | ||
- **Is it safe to ship code with `useTilg` to production?** | ||
Although `useTilg()` does nothing in a production build (`process.env.NODE_ENV === 'production'`) but only an empty function, I encourge you to remove the hook from the source code after finishing development your component. | ||
- **How do you implement this hook? What can I learn from the code?** | ||
It is very hacky. Don't rely on it or try it in production, or [you will be fired](https://github.com/facebook/react/blob/0568c0f8cde4ac6657dff9a5a8a7112acc35a748/packages/react/index.js#L35). | ||
<br/> | ||
## License | ||
The MIT License (MIT). |
Major refactor
Supply chain riskPackage has recently undergone a major refactor. It may be unstable or indicate significant internal changes. Use caution when updating to versions that include significant changes.
Found 1 instance in 1 package
Environment variable access
Supply chain riskPackage accesses environment variables, which may be a sign of credential stuffing or data theft.
Found 1 instance in 1 package
Empty package
Supply chain riskPackage does not contain any code. It may be removed, is name squatting, or the result of a faulty package publish.
Found 1 instance in 1 package
No tests
QualityPackage does not have any tests. This is a strong signal of a poorly maintained or low quality package.
Found 1 instance in 1 package
21910
4779.73%7
250%358
Infinity%1
-50%303
15050%1
Infinity%8
Infinity%1
Infinity%