Open7

理解の整理メモ

RyotaRyota

dependabotについて

やってくれること

  • Dependabot version updates:最新バージョンを検知し、PRを作成する
  • Dependabot alerts:脆弱性を検知したらalertを作成する
  • Dependabot security updates:alertを解決するためのPRを作成する

PRのversion updatesとsecurity updatesの見分け方

insights → Dependency graph → Dependabotタブから該当のパッケージ管理ファイルを選択すると、Version update/Security updateの記載がある。

pnpmのエラー

dependabotがパッケージを更新する際、こんなエラーが出る。

Note that in CI environments this setting is true by default. If you still need to run install in such cases, use "pnpm install --no-frozen-lockfile"

出る条件は「package.jsonは更新しているがpnpm-lock.yamlを更新していないため、package.jsonと矛盾が生じる」ケース

lock fileを更新せずエラーを吐いて止まる理由は--frozen-lockfileがCIではtrueになっているため。

true の場合、 pnpm はロックファイルを生成しません。 lockfile がマニフェストと同期しておらず、更新が必要な場合、またはロックファイルが存在しない場合は、インストールが失敗します。

https://pnpm.io/ja/next/cli/install#--frozen-lockfile

つまりdependabotがpackage.jsonのみしか更新していない場合、CI/CD実行時にpnpm-yarn.lockが更新されるが、これはローカルと差分があるということであり、CIテストと開発環境で結果が一致しない可能性がるので失敗させると言ったところか。

RyotaRyota

git authorについて

gitにはauthorとcommiterの概念がある。

  • author:元のコードを書いた人
  • committer:コミットした人

これはrebaseやcherry-pickのケースで役に立つ。
ブランチAへのコミットaをブランチBにcherry-pickしコミットbを生成した場合、コミットbのauthorとcommiterは以下の通り。

  • author:元のコミットAをした人
  • committer:cherry-pickした人

以下コマンドでauthor, committerどちらも確認可能

git log --pretty=full
RyotaRyota

フロントエンドのテストの分類

https://zenn.dev/koki_tech/articles/a96e58695540a7
https://qiita.com/KNR109/items/7cf6b24bed318dab5715

主に以下の分け方のイメージ

  • 静的テスト(eslintなど)
    • コーディング規約の強制、アンチパターンの発見などに便利
  • 単体テスト(jestなど)
    • 関数のI/Oなどのテスト
  • 結合テスト(testing-libraryなど)
    • イメージはReactのcomponentテスト。複数componentを組み合わせて挙動をチェックする
    • node環境で実行するので、ブラウザAPIやユーザー操作はあくまで仮想的な実行
  • E2Eテスト(playwrightなど)
    • ブラウザで実際に実行する
    • ユーザーの操作に最も近い
  • VRT(storybookのスクショ機能とreg-suiteを組み合わせるとか?)
    • 画面のUIの差分を比較し、意図しない変化を検知する
RyotaRyota

npmライブラリとd.ts

jsで書かれたnpmライブラリはそれだけでは型情報がなく、tsファイルで読み込もうとするとdeclareファイルがない旨のエラーを出す

  • そのままでは型が分からず全てany型になってしまう
  • tsファイルで書かれたものなら、当然だが関数自体への型付けもしくは型推論が効く

これを解消するためにd.tsファイルを定義する(tsファイルでも可)

書き方の例

hogeライブラリのfuga.jsファイルにある関数fooに型をつける場合

  • npmパッケージhogeにはfuga.d.tsファイルを作成し、以下のように記述
  • ファイル名もmoduleも適当な名前はNG
declare module 'hoge/fuga' {
    export function foo(): string;
}

利用者側はimport { foo } from 'hoge/fuga'で呼び出して使える。

index.jsを使う

fuga.jsindex.jsにすれば既定で省略可能なため、楽
この場合のdeclareファイルはindex.d.ts

declare module 'hoge' {
  export function foo(): string;
}

利用者側はimport { foo } from 'hoge'で呼び出して使える。

RyotaRyota

Tanstack Query的なものが恋しくなる瞬間

const HogeComponent = () => {
  // 1. fetchしたデータをキャッシュさせたい時
  // キャッシュを自作するのは結構面倒
  const data = fetchData();

  // 2. ローディング中やerror時の処理を書きたい時
  // dataがundefinedかつerrorが空ならisLoading、という条件分岐を一々書くのは面倒
  // errorも同様。dataの中を一々errorプロパティ見るの面倒なのでカスタムフックに切りだした方が良い
  return (
    <>
      {/* 3.
        複数のコンポーネントで同じdataを使いたい時、親から渡す必要がある。
        React Queryなどはcontextで管理しているのでそれぞれのコンポーネント内からfetchでき、かつキャッシュ使えば複数回ネットワークを渡らない。
        別に親からでも良いけど、Layoutコンポーネントのような特殊なケースで欲しくなった
     */}
      <Content1 data={data} />
      <Content2 data={data} />
    </>
  );
};
RyotaRyota

フロントエンドの開発にnode.jsを使い出した経緯?

https://qiita.com/amenoyoya/items/3512d712675c5751ec38

もちろん、JSを書いてブラウザに読み込ませるだけでも良いが、

  • ES6にブラウザが対応しきれていなかったため、ES6で書いたJSをtranspileやpolyfillしたい(node.js × babelなど)
  • importがなかった頃はファイルの分割やライブラリの仕様が手間だったため、node.jsのrequireなどを利用して効率的に開発したい(node.js × webpackなど)
  • ホットリロードやエラー検知が便利
  • よく考えたらTypeScriptで開発するなら必須だわ
RyotaRyota

ReactでCSSを実現する方法色々

1. Inline Styles

コンポーネント内でstyleプロパティを使って直接CSSを記述する原始的な方法。
JavaScriptのオブジェクトとして記述するため、値に変数や式を使うことができる。

function App() {
  const buttonStyle = {
    backgroundColor: 'blue',
    color: 'white',
    padding: '10px',
    borderRadius: '5px',
  };

  return <button style={buttonStyle}>Click Me</button>;
}

export default App;

2. 従来のCSSファイル

通常のCSSファイルを作成し、importして使う方法。
スタイルはグローバルに適用されるため、他のコンポーネントとスタイルが干渉しやすい。

.button {
  background-color: blue;
  color: white;
  padding: 10px;
}
import './styles.css';

function App() {
  return <button className="button">Click Me</button>;
}

export default App;

3. CSS Modules

CSSファイルをコンポーネントごとに分けてスコープを限定する方法。
クラス名は自動でユニークになるので、他のコンポーネントと干渉しない。
CSSファイル名は〇〇.module.css

.button {
  background-color: blue;
  color: white;
  padding: 10px;
}
import styles from './Button.module.css';

function Button() {
  return <button className={styles.button}>Click Me</button>;
}

export default Button;

4. CSS-in-JS

クライアントJSでCSSを生成している。
そのためReact Server Componentと相性が悪い。

試しにStyled Componentsを使ったら以下のエラーが出た。裏側ではcontextを使っているのか。
Error: createContext only works in Client Components

Styled Components

Styled Componentsを使用する方法。
スタイルをJavaScriptで定義するため、動的なスタイルを簡単に実現できる。

import styled from 'styled-components';

const StyledButton = styled.button`
  background-color: blue;
  color: white;
  padding: 10px;
  border-radius: 5px;

  &:hover {
    background-color: darkblue;
  }
`;

function App() {
  return <StyledButton>Click Me</StyledButton>;
}

export default App;

Emotion

Styled Componentsと同じくCSS-in-JSのライブラリ。
styledcssの2つのスタイル指定方法があり、柔軟にCSSを記述できる。

/** @jsxImportSource @emotion/react */
import { css } from '@emotion/react';

const buttonStyle = css`
  background-color: blue;
  color: white;
  padding: 10px;
  border-radius: 5px;

  &:hover {
    background-color: darkblue;
  }
`;

function App() {
  return <button css={buttonStyle}>Click Me</button>;
}

export default App;

5. CSS フレームワーク

Tailwind CSS(Utility-first)

Tailwind CSSは、ユーティリティクラスを使ってスタイリングを行う方法。
Reactでのスタイル指定も容易で、特定のクラスを組み合わせてコンポーネントのデザインを構築できる。

function App() {
  return (
    <button className="bg-blue-500 text-white px-4 py-2 rounded">
      Click Me
    </button>
  );
}

export default App;

MUI(Component-based)

内部でCSS in JS(styled componentsかemotion)を使用しているためRSCと相性が悪いとのことだが、emotionであればRSCでも機能した。
Ant Designなんかはデフォルトで直接CSSファイルを使用しているようで、RSCとも相性は悪くなさそう。

import * as React from 'react';
import Button from '@mui/material/Button';

function App() {
  return (
    <div>
      <Button variant="contained" color="primary">
        Click Me
      </Button>
    </div>
  );
}

export default App;