🙃

Next.jsをVS Codeで快適に書くスニペット

2022/01/20に公開

モチベーション

新しいコンポーネントを作る時にいつも書くことを、スニペットにして楽をしたい。

VS Codeにはスニペットを登録できる

えらべる設定方法

2種類ある。

  • コマンドパレットからVS Code全体に設定すること。(参考)
  • .vscodeディレクトリに*.code-snippetsにマッチするファイル名をおくことで、プロジェクト単位で利用すること。(参考)
    • プロジェクト単位で設定する場合はscopeプロパティを使って利用する言語を指定できる。

こちらの記事で詳しく解説されてる。
https://zenn.dev/miz_dev/articles/157a7aaad0bdcf

すごい多機能

いろいろできる。書くのがめんどくさい書ききれないので詳しくはドキュメントへ。
例として

  • ファイル名・ディレクトリ名などを埋め込める(正規表現も使える)
    • デフォルト値を選択などもできる
  • スニペットを貼った後のカーソル位置を指定できる。
    など。

自分の書いたスニペット

ファイル名と同じ名前のFunction componentの雛形を作る

スニペット本体
{
  "new Function Component": {
    "prefix": "FC", // ⬅ スニペット呼び出しのためにエディタに入力する文字列
    "body": [ // ⬅ 挿入される文字列。配列にすると複数行を入力できる。
      "import { FC } from 'react';",
      "", 
      "type Props = {};",
      "const ${1:$TM_FILENAME_BASE}: FC<Props> = ({}) => {",
      "  return <></>;",
      "};",
      "export default ${1:$TM_FILENAME_BASE};"
    ],
    "description": "Template of new FC",
  },

スニペットを使ったファイル名がCard.tsxのとき

アウトプット
  import { FC } from 'react';
  
  type Props = {};
  const Card: FC<Props> = ({}) => {
    return <></>;
  };
  export default Card;

ファイル名をコンポーネント名にしている。

ディレクトリ名と同じ名前のNextPageの雛形を作る

  • /pages/**/PageName/Index.tsxに置かれるNextPageの雛形を作りたい。
  • 名前はPageNameにしたい。
スニペット本体
  "new Next Page": {
    "prefix": "nextPage",
    "body": [
      "import type { NextPage } from 'next';",
      /* ここらへんはプロジェクトごとによしなに */
      "import HeadWrapper from '@/components/layout/HeadWrapper';", 
      "import Layout from '@/components/layout/Layout';",
      "import NeedLogin from '@/components/layout/NeedLogin';",
      "",
      /* POINT① */
      "const ${TM_DIRECTORY/.*\\/(.)(.+)$/${1:/upcase}$2/}: NextPage = () => {", 
      "  return (",
      "    <HeadWrapper>",
      "      <NeedLogin>",
      "        <Layout>",
      "          <main></main>",
      "        </Layout>",
      "      </NeedLogin>",
      "    </HeadWrapper>",
      "  );",
      "};",
      "",
      "export default ${TM_DIRECTORY/.*\\/(.)(.+)$/${1:/upcase}$2/};"
    ],
    "scope": "typescriptreact"
  }
}

POINT①では

  1. TM_DIRECTORYは絶対パスなので、正規表現を使ってファイルのあるディレクトリ名を取得
  2. ディレクトリ名の先頭1字を大文字にする

ことをしている。

スニペットを使ったファイルのパスがpages/**/mypage/Index.tsxのとき

アウトプット
import type { NextPage } from 'next';
import HeadWrapper from '@/components/layout/HeadWrapper';
import Layout from '@/components/layout/Layout';
import NeedLogin from '@/components/layout/NeedLogin';

const Mypage: NextPage = () => {
  return (
    <HeadWrapper>
      <NeedLogin>
        <Layout>
          <main></main>
        </Layout>
      </NeedLogin>
    </HeadWrapper>
  );
};

export default Mypage;

スニペットの拡張機能もうあった😇

すでにReactのスニペットの拡張機能がmarketplaceにありました。
こちらの記事で詳しく解説されています。
https://zenn.dev/nbr41to/articles/a2e6363e8755e5c9a9ba
ただ、自分としては

  • スニペットが覚えづらい。
  • デフォルトがFragmentではなくdivになってしまう。
  • Propsと型が自動でつかない。
  • コンポーネント名にディレクトリ名じゃなくてファイル名が常に使われる。
  • 自分で作ったスニペットのほうが愛着がある

といった理由でオリジナルのスニペットを使い続けようと思います。

GitHubで編集を提案

Discussion