VsCodeのスニペット機能で作業効率を上げよう

## はじめに

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/87924/68464cb2-0d7e-32a8-b127-54ce48814dab.png)


ChatGPTを使ったり、開発をする上で効率を上げる方法はいくつもあると思います。
また、開発をする人は多くの人がVsCodeなどのIDEを使っているでしょう！

よく使うコードを毎回入力するのは無駄だなー、NotionなどVsCode外によく使うコードを置いといて適宜コピペする感じでもいいが、なるべくVsCodeで完結したいなー、って思いつつ今まで調べてませんでした...

今回はそんな人のために役立つスニペット機能ッテいうのを知ったので、簡単に紹介します！

## スニペットとは

スニペットと呼ばれる言語毎の定義jsonファイルに、よく使うコードを登録しておくことで、簡単に呼び出すことが出来る機能です。
スニペットには、
- 特定の言語のスニペットである、`ユーザスニペット`
- 複数もしくはすべてに共通のスニペットである、`グローバルスニペット`
の2種類があります。

## ユーザスニペットを作ってみる

では、実際に作ってみます。
⚙アイコンをクリックし、`スニペット`をクリックします。
今回はtypescript用にするので、`typescript`と打って定義ファイルを開きます。
![スクリーンショット 2025-01-09 204230.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/87924/a1bf87a2-1801-3045-cd81-a56e81bb1474.png)

![スクリーンショット 2025-01-09 205153.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/87924/220cca21-45af-0879-4103-9a71668d48d7.png)

まずは、ログ出力を簡単にしてみます。
- `prefix`に呼び出す際の名前
- `body`に実際のコード
- `description(任意)`にスニペットの説明
を記載します。
```json:typescript.json
{
	// Place your snippets for typescript here. Each snippet is defined under a snippet name and has a prefix, body and
	// description. The prefix is what is used to trigger the snippet and the body will be expanded and inserted. Possible variables are:
	// $1, $2 for tab stops, $0 for the final cursor position, and ${1:label}, ${2:another} for placeholders. Placeholders with the
	// same ids are connected.
	// Example:
	// "Print to console": {
	// 	"prefix": "log",
	// 	"body": [
	// 		"console.log('$1');",
	// 		"$2"
	// 	],
	// 	"description": "Log output to console"
	// }
    "log": {
	    "prefix": ["log"],
		"body": [
			"console.log('');",
		],
        "description": "ログ"
    },
}
```

そして、任意の.tsファイルを開いて`log`と打ってみましょう。
先ほど登録したlogが出てくるので選択すると、bodyに入力したコードが自動で入力されます。
![スクリーンショット 2025-01-09 205811.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/87924/37998881-7c63-f0ea-f283-42db696fce26.png)

![スクリーンショット 2025-01-09 205844.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/87924/e15f9209-32cb-7ac8-e099-edaf3037fe58.png)

こんな短いコードだとあまりメリットを感じないので、次は少し長いコードにしてみます。
cdkのStackを作る際のスニペットです。
```json:typescript.json
{
	// Place your snippets for typescript here. Each snippet is defined under a snippet name and has a prefix, body and
	// description. The prefix is what is used to trigger the snippet and the body will be expanded and inserted. Possible variables are:
	// $1, $2 for tab stops, $0 for the final cursor position, and ${1:label}, ${2:another} for placeholders. Placeholders with the
	// same ids are connected.
	// Example:
	// "Print to console": {
	// 	"prefix": "log",
	// 	"body": [
	// 		"console.log('$1');",
	// 		"$2"
	// 	],
	// 	"description": "Log output to console"
	// }
    "log": {
	    "prefix": ["log"],
		"body": [
			"console.log('');",
		],
        "description": "ログ"
    },
    "cdk-class": {
        "prefix": "cdk-class",
        "body": [
            "import * as cdk from 'aws-cdk-lib';",
            "import { Construct } from 'constructs';",
            "export class $1 extends cdk.Stack {",
            "  constructor(scope: Construct, id: string, props: ${2:cdk.StackProps}) {",
            "    super(scope, id, props);",
            "",
            "    const { accountId, region } = new cdk.ScopedAws(this);",
            "    $3",
            "    $3",
            "  }",
            "}",
        ],
        "description": "cdk appクラス作成"
    },
}
```
`$1,$2,$3`が出てきてますが、このように$xの形式で記載するとその場所に自動でカーソルが当たる状態になります。
`$1から$2`への移動もtabキーを押すだけで可能です。
また、`${2:cdk.StackProps}`のようにすれば初期値も設定することが出来ますし、`同じ番号の$x`を記載すれば入力した文字が`全て同じ$x`に入力されます:smile: 

![スクリーンショット 2025-01-09 210034.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/87924/fdc2b30e-d7ae-d389-50ef-26467195f39c.png)
![スクリーンショット 2025-01-09 210128.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/87924/1d48ab10-c95a-9bba-c1c0-f1ce3db5172d.png)
![スクリーンショット 2025-01-09 210811.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/87924/932ce528-3eb8-5768-ad7f-61cc20dfe149.png)


他にも例えばQiitaなどで記事を書いている場合、ある程度自分なりのテンプレを作ることもあるかと思います。
それをマークダウンのスニペットに登録しておけば、簡単に呼び出すことができます。
```json:markdown.json
{
	// Place your snippets for markdown here. Each snippet is defined under a snippet name and has a prefix, body and
	// description. The prefix is what is used to trigger the snippet and the body will be expanded and inserted. Possible variables are:
	// $1, $2 for tab stops, $0 for the final cursor position, and ${1:label}, ${2:another} for placeholders. Placeholders with the
	// same ids are connected.
	// Example:
	// "Print to console": {
	// 	"prefix": "log",
	// 	"body": [
	// 		"console.log('$1');",
	// 		"$2"
	// 	],
	// 	"description": "Log output to console"
	// }
    "qiita": {
        "prefix": "qiita",
        "body": [
            "## はじめに",
            "",
            "こんにちは、中里です。",
            "みなさんxxx使っていますか？",
            "今回はxxxについて記事を書いていこうと思います。",
            "",
            "### この記事でわかること",
            "",
            "この記事では以下について説明しています。",
            "- わかること1",
            "- わかること2",
            "",
            "### この記事の対象者",
            "",
            "- Qiita投稿の初心者",
            "- 技術系の記事を書いてみたいけど何から始めればいいか分からない人",
            "- Qiita投稿のテンプレートをコピペして使いたい人",
            "",
            "### 動作環境・使用するツールや言語",
            "",
            "## 見出し1",
            "",
            "### 見出し1-1",
            "### 見出し1-2",
            "",
            "## 見出し2",
            "",
            "### 見出し2-1",
            "### 見出し2-2",
            "",
            "",
            "## 参考資料",
            "記事の構成や何を書くべきかを教えてくれます。",
            "",
            "- [xxx](https://example.com)",
            "- []()",
            "",
            "",
            "",
            "",
            "",
            "",
            "",
            "",
            "## おわりに",
            "",
            "今回はxxxについて説明しました。",
            "xxxを学ぶことで～～～",
        ],
        "description": "Qiitaのテンプレ"
    }
}
```

:::note info
マークダウンのスニペットみたいに長いと自前で`body`に書くのめんどくさいですよね...
そんな方のため？に、[専用のサイト](https://migi.me/vsc_snippet/)がありました！
ここで作ってコピペするのが楽そうです:smile:
:::

## グローバルスニペットの作り方

グローバルスニペットも作ってみましょう！
ユーザスニペットと違い、定義ファイルがないので自分で任意の名前で作成します。(何ファイルでも作れるっぽいです)
![スクリーンショット 2025-01-09 204230.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/87924/4caefa11-0462-7706-5986-ecfa228fe21d.png)


![スクリーンショット 2025-01-09 204501.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/87924/10240b2d-d2b9-f201-54f8-e4f2b8cbca8c.png)

globalという名前を入力すると、`global.code-snippets`というファイルが出来ます。
ユーザスニペットと違い`scope`がありますが、scopeに言語を書くとそのファイルで使えるスニペットになります。
下の例だとjavascriptとtypescriptのファイルでlogという呼び出しで使えるスニペットです。

```json:global.code-snippets
{
	// Place your GLOBAL snippets here. Each snippet is defined under a snippet name and has a scope, prefix, body and 
	// description. Add comma separated ids of the languages where the snippet is applicable in the scope field. If scope 
	// is left empty or omitted, the snippet gets applied to all languages. The prefix is what is 
	// used to trigger the snippet and the body will be expanded and inserted. Possible variables are: 
	// $1, $2 for tab stops, $0 for the final cursor position, and ${1:label}, ${2:another} for placeholders. 
	// Placeholders with the same ids are connected.
	// Example:
	"Print to console": {
	 	"scope": "javascript,typescript",
	 	"prefix": "log",
	 	"body": [
	 		"console.log('$1');",
	 		"$2"
	 	],
	 	"description": "Log output to console"
	 }
}
```


## おわりに

今回はスニペット機能による開発効率化について紹介しました！
知っている方が多い機能かもしれませんが、使い方次第で開発スピードが上がりそうですね。