100倍という表現はだいぶ大げさだと思うのですが、自分はこの方法を使ってからそれくらいnpmパッケージのコードリーディングがかなりしやすくなったので自分がこの方法を知った時の感覚をタイトルに反映させてみました!
方法というのはシンプルでnpmパッケージの気になる箇所にconsole.logを仕込んでデバックをするだけです!
今回はその「npmパッケージの気になる箇所にconsole.logを仕込んでデバックをする方法」について解説をします
デバックするライブラリはreact-hook-formにしました!
npmパッケージの気になる箇所にconsole.logを仕込んでデバックをする方法
少し手順が多いのですが、なるべくコピペするだけで良いようにしました!
また、一度この手順を踏めば次からのデバックはかなり楽になるはずです
1 適当なディレクトリを作り、そこにreact-hook-formをクローンする
mkdir react-hook-form_debug
cd react-hook-form_debug
git clone https://github.com/react-hook-form/react-hook-form.git
2 debug用のreactプロジェクトを作成し、react-hook-formをinstallする
yarn create react-app react-hook-form_code-reading --template typescript
cd react-hook-form_code-reading
yarn add react-hook-form
cd ..
3 react-hook-formをビルドする
cd react-hook-form
yarn
yarn build
cd ..
4 react-hook-formのパッケージと先程作成したreactプロジェクトをリンクさせる
cd react-hook-form_code-reading/node_modules/react-hook-form
rm -rf dist
ln -s ../../../react-hook-form/dist
cd ../..
※lnコマンドはファイルやディレクトリのリンクを作るときに使うコマンド
5 reactプロジェクトでreact-hook-formを使用する
https://react-hook-form.com/get-started のコードをコピペしましょう
import React from "react";
import { useForm, SubmitHandler } from "react-hook-form";
type Inputs = {
example: string,
exampleRequired: string,
};
export default function App() {
const { register, handleSubmit, watch, formState: { errors } } = useForm<Inputs>();
const onSubmit: SubmitHandler<Inputs> = data => console.log(data);
console.log(watch("example")) // watch input value by passing the name of it
return (
/* "handleSubmit" will validate your inputs before invoking "onSubmit" */
<form onSubmit={handleSubmit(onSubmit)}>
{/* register your input into the hook by invoking the "register" function */}
<input defaultValue="test" {...register("example")} />
{/* include validation with required or other standard HTML validation rules */}
<input {...register("exampleRequired", { required: true })} />
{/* errors will return when field validation fails */}
{errors.exampleRequired && <span>This field is required</span>}
<input type="submit" />
</form>
);
}
6 reactプロジェクトをスタートさせる
yarn start
もし以下のようなReactの重複参照エラーが発生した場合はreact-hook-formのReactのバージョンを利用する
Uncaught Error: Invalid hook call. Hooks can only be called inside of the body of a function component. This could happen for one of the following reasons:
1. You might have mismatching versions of React and the renderer (such as React DOM)
2. You might be breaking the Rules of Hooks
3. You might have more than one copy of React in the same app
cd node_modules
rm -Rf ./react ./react-dom
ln -s ../../react-hook-form/node_modules/react
ln -s ../../react-hook-form/node_modules/react-dom
※React18を利用する場合はindex.tsxファイルも修正する必要が有ります
import React from 'react';
import ReactDOM from 'react-dom';
import './index.css';
import App from './App';
import reportWebVitals from './reportWebVitals';
ReactDOM.render(<App />, document.getElementById("root"));
// If you want to start measuring performance in your app, pass a function
// to log results (for example: reportWebVitals(console.log))
// or send to an analytics endpoint. Learn more: https://bit.ly/CRA-vitals
reportWebVitals();
7 react-hook-formのhandleSubmit
関数にconsole.logを仕込む
const handleSubmit: UseFormHandleSubmit<TFieldValues> =
(onValid, onInvalid) => async (e) => {
console.log("submit!!") // console.logを追加
if (e) {
e.preventDefault && e.preventDefault();
e.persist && e.persist();
}
let hasNoPromiseError = true;
let fieldValues: any = cloneObject(_formValues);
_subjects.state.next({
isSubmitting: true,
});
try {
if (_options.resolver) {
const { errors, values } = await _executeSchema();
_formState.errors = errors as FieldErrors<TFieldValues>;
fieldValues = values;
} else {
await executeBuildInValidation(_fields);
}
if (
isEmptyObject(_formState.errors) &&
Object.keys(_formState.errors).every((name) => get(fieldValues, name))
) {
_subjects.state.next({
errors: {} as FieldErrors<TFieldValues>,
isSubmitting: true,
});
await onValid(fieldValues, e);
} else {
if (onInvalid) {
await onInvalid({ ..._formState.errors }, e);
}
_options.shouldFocusError &&
focusFieldBy(
_fields,
(key) => get(_formState.errors, key),
_names.mount,
);
}
} catch (err) {
hasNoPromiseError = false;
throw err;
} finally {
_formState.isSubmitted = true;
_subjects.state.next({
isSubmitted: true,
isSubmitting: false,
isSubmitSuccessful:
isEmptyObject(_formState.errors) && hasNoPromiseError,
submitCount: _formState.submitCount + 1,
errors: _formState.errors,
});
}
};
8 react-hook-formをビルドする
別のターミナルを起動して
cd react-hook-form
yarn build
buildのwatchモードを使いたかったのですが、うまく動かなかったので断念
9 ブラウザで確認する
submit!!というのがlogで出力されているのを確認することが出来ると思います!
もし反映されていなかったらリロードしてみてください
いかがだったでしょうか?
この方法は他のパッケージのコードリーディングをするときもかなり使えると思うので、是非ためしてみてください!
参考資料
https://github.com/apollographql/apollo-client/blob/main/CONTRIBUTING.md