🚂

VSCodeが導くZenn執筆環境ボイラープレート

2022/10/11に公開
5

Zenn CLIに最適化されたVSCode環境で書くために

これから「Zennに記事をたくさん投稿するぞ!」の気持ちを意気込みだけで終わらせないために、VSCodeに最適化されたZenn執筆環境のボイラープレート[1]を作成しました。

Zenn執筆環境のボイラープレート

Githubのテンプレートリポジトリとして公開しているので、テンプレートを複製してすぐに記事を書き始めることができます。

Zenn執筆環境ボイラープレートの特徴

  • Zenn執筆に最適化されたVSCode拡張機能やスニペットが自動的にインストールされます。
  • VSCodeの見た目がZennライクなテーマカラーになって編集対象が明確になります。
  • Zenn CLIを使ってローカル環境でプレビューを確認しながら記事を書くことができます。
  • 記事の内容は markdownlint,textlint で静的解析(lint)を行います。
  • 英単語の誤字がないか cspell(Code Spell Checker)でチェックします。
  • huskylint-staged でコミット時に自動でlintします。そのため、不正な形式の文章はコミットされません。

前提:VSCodeとDocker(Dev Container)が必要

記事を編集するエディタはVSCode(Visual Studio Code)を使います。Zennの執筆に最適化されたVSCodeの拡張機能やスニペットがインストールされます。

また、Dockerで専用コンテナを準備して執筆環境をつくります。そのため、ローカル環境にDockerのインストールが必要です。特にこだわりが無ければ、GUIで簡単にDockerコンテナを導入できるDocker Desktopが(個人利用であれば)無料で使えて便利です。VSCodeからコンテナにアクセスして執筆するためDev ContainersのVSCode拡張機能も必要です。

VSCodeのdevcontainer環境は、独立した開発環境をつくるには打って付けの構築手法です。しかし構築のための手間と準備は必要なので、面倒だしちょっと難しそうだと思われる方もいるでしょう。

ボイラープレートであれば事前に必要な設定がすべて組み込まれているので、VSCodeとDockerさえインストールされていれば、そのまま使うことができます。

ボイラープレートの使い方

Githubテンプレートからリポジトリを複製する

Githubのテンプレートリポジトリの右上にある "Use this template" をクリックして、ボイラープレートからリポジトリを複製します。

ボイラープレートからリポジトリを複製
Githubテンプレートからリポジトリを複製

コンテナを立ち上げる

VSCodeで複製したリポジトリをクローンして "Reopen in Container" でコンテナを立ち上げます。

zenn-template_devcontainerの起動
VSCodeでDev Containerを立ち上げ

Dockerコンテナの構成管理のために、Docker Composeを使っています。コンテナを立ち上げると ./docker-compose.ymldocker/Dockerfile の内容に基づきコンテナ環境を構築します。

その後で package.json に記述したライブラリがインストールされます。さらに devcontainer.json に書かれた設定によって、VSCode拡張機能がインストールされます。

devcontainerの中からルート直下のdocker-compose.ymlを使っている理由

実際のコンテナ構成として使われるのはルート直下にある ./docker-compose.yml の設定ファイルです。.devcontainer/docker-compose.yml では、既存の設定ファイルをオーバーライドする記述を入れてます。(公式が提供しているこちらの設定ファイルを参考にしています)このような構成にしておくと、VSCode環境以外でもDocker Composeの設定ファイルを使い回すことができます。

既存のDocker Composeをオーバーライドする方法については以下の記事にとても詳しくまとまっていました。

https://zenn.dev/saboyutaka/articles/9cffc8d14c6684

Zenn CLIを使う準備をする

ローカルのエディタでZennの記事が執筆できる zenn-cli もインストールされます。GitHubリポジトリと連携手順はZenn公式が書いている以下の記事で丁寧に解説されています。

https://zenn.dev/zenn/articles/connect-to-github

ここまでの手順でZennの記事を書き始める準備は完了しています。zenn-cli を使った記事の書き方は、同じくZenn公式が書いている以下の記事を参考にしてください。

https://zenn.dev/zenn/articles/zenn-cli-guide

ボイラープレートの設定内容

記事を書く際は、Zennに最適化されたVSCode拡張機能やスニペットを使うと便利です。また、コミット時に静的解析(lint)が実行されます。文章が不正な場合、警告メッセージが表示されてコミットできません。

詳しい設定について、後述していきます。

記事を書くための設定

Zenn CLIコマンドはnpmスクリプトから1クリックで実行

記事のプレビュー(npx zenn preview)や記事の新規作成(npx zenn new:article)はnpmスクリプトに登録しています。VSCodeのサイドバーから1クリックで実行できます。

Zenn CLIのコマンドはサイドバーから1クリックで実行
Zenn CLIのコマンドはサイドバーから1クリックで実行

VSCode拡張機能でマークダウンを効率よく書く

マークダウンの文章を書く効率を上げる目的で以下の拡張機能を入れています。

拡張機能 説明
Markdown All in One ショートカットや便利なコマンド
:emojisense: 絵文字入力の補助
Insert Date String 現在時刻をショートカット入力(Zennの日時フォーマット YYYY-MM-DD hh:mm で入力されるよう設定済)
Copy file name ファイル名を右クリックメニューからコピー
Path Intellisense パスを入力補完

拡張機能の使い方は以下の記事で詳しく解説しています。よければ参考にしてください。

https://qiita.com/waicode/items/1310d3f0aeb24f393b88

独自のマークダウン記法はVSCodeスニペットで

.vscode/markdown.code-snippets にZenn独自の記法を含むマークダウン記法のスニペットを登録しています。使っていきながらご自身で使いやすいスニペットに書き換えることも可能です。

https://zenn.dev/zenn/articles/markdown-guide

静的解析(lint)の設定

テキストにはコンパイルもなければ、実際に読まれるときの動的なチェックもありません。事前の静的解析は「糸くず(lint)」を取る以上に重要な役割を占めると考えています。

このボイラープレートには、以下に対してlintする設定が入っています。

  • マークダウンの形式(markdownlint
  • 文章の校正(textlint
  • 英単語の誤字(cspell

くわえて、マークダウンファイル以外はコードフォーマット(自動整形)を prettier を使って実施します。マークダウンファイルはmarkdownlintと設定が競合するため、意図的に対象から外しています。

VSCodeエディタ上で問題があればリアルタイムで確認

静的解析(lint)はVSCodeの拡張機能も入れているので、問題があればエディタ上で常に確認できます。

拡張機能 説明
markdownlint VSCodeのエディタ上でマークダウン構造を解析
vscode-textlint VSCodeのエディタ上でテキストを解析
Code Spell Checker VSCodeのエディタ上で英単語の誤字をチェック
Prettier - Code formatter VSCodeでコードフォーマット(自動整形)

コミット時にも確認して不正な形式のマークダウンを警告

huskylint-staged でコミット時に自動でlintします。そのため、不正な形式の文章はコミットされません。

コミット時のlintについては以下の記事に詳しく書いてます。知りたい方は参考にしてください。

https://qiita.com/waicode/items/33311d0a511dc821f53f

lintの詳細設定

ボイラープレートなので、特に設定を変更せずそのまま使えます。この部分も、使っていきながら好みの設定に書き換えてください。以下では初期設定内容について説明します。

markdownlint

デフォルトの構文チェックは厳しめに設定されています。

そのため .vscode/settings.json.markdownlint-cli2.jsonc で一部ルールを調整しています。

"markdownlint.config": {
  "line-length": false, // MD013: Disable the maximum number of characters per sentence
  "no-duplicate-heading": false, // MD024: Allow duplicate heading text
  "no-trailing-punctuation": false, // MD026: Allow headings with . ,;:
  "no-inline-html": false, // MD033: Allow HTML description
  "no-bare-urls": false // MD034: Allow URLs to be written as is
}

textlint

ベースとして以下の2つのプリセットを適用しています。

プリセット名 説明
textlint-rule-preset-ja-spacing 日本語のスペース有無を決定するtextlintルールプリセット
textlint-rule-preset-ja-technical-writing 技術文書向けのtextlintルールプリセット

プリセットのままだと厳し過ぎる箇所があるため .textlintrc で設定を一部上書きしています。

.textlintrc
{
  "plugins": {
    "@textlint/markdown": {
      "extensions": [
        ".md"
      ]
    }
  },
  "filters": {
    "comments": true
  },
  "rules": {
    "prh": {
      "rulePaths": [
        "./prh/index.yml"
      ]
    },
    "preset-ja-technical-writing": {
      "sentence-length": {
        "max": 150
      },
      "no-exclamation-question-mark": {
        "allowFullWidthExclamation": true,
        "allowFullWidthQuestion": true
      },
      "ja-no-successive-word": false,
      "ja-no-mixed-period": {
        "allowPeriodMarks": [
          ":",
          ":"
        ]
      },
      "no-doubled-joshi": {
        "strict": false,
        "allow": [
          "も",
          "や",
          "か"
        ],
        "separatorCharacters": [
          ",",
          ",",
          "、",
          ".",
          ".",
          "。",
          "?",
          "!",
          "?",
          "!",
          "「",
          "」",
          "\"",
          "”",
          "“"
        ]
      }
    },
    "preset-ja-spacing": {
      "ja-space-around-code": {
        "before": true,
        "after": true
      }
    }
  }
}

また、校正用辞書を /prh/rules へ追加できるようにしています。初期設定では /prh/rules/tech.yml に技術用語の校正辞書をいくつか登録しています。必要に応じて用語を追加してください。

/prh/rules/tech.yml
meta:
  - title: 技術用語の固有名詞ルール
rules:
  - expected: インターフェース
    patterns:
      - インターフェイス
      - インタフェース
      - インタフェイス
    prh: 技術用語
  - expected: ソフトウェア
    pattern: ソフトウェアー
    prh: 技術用語
  - expected: ハードウェア
    pattern: ハードウェアー
    prh: 技術用語
  - expected: デフォルト
    pattern: ディフォルト
    prh: 技術用語

cspell

許可する言葉は .cspell.jsonwords に追加します。対象の文字列にカーソルを合わせてVSCodeのクイックフィックスで登録するのが便利です。

VSCodeのクイックフィックスでcspellのwordsに登録
VSCodeのクイックフィックスでcspellのwordsに登録

Prettier

.prettierignore*.md 記載して、マークダウンファイルをコードフォーマットの対象外にしています。その他の設定は特に入れていません。自動整形時はデフォルト設定が適用されます。

Zenn執筆環境ボイラープレートのGithubリポジトリ

ここまでお読みいただきありがとうございました。Zenn CLIで記事を書いてみたい!と思っていたけど設定が面倒でこれまで重い腰が上がらなかった方は、この機会にぜひご利用ください。

https://github.com/waicode/zenn-content-boilerplate

Qiita執筆環境のボイラープレート

同様の仕組みで作成したQiita執筆環境のボイラープレートも公開しています。非公式のQiita連携ツールを使って、ZennのようにGithub連携して記事を書くことができます。Qiitaで記事を書いている方は、こちらも合わせて参考にしてみてください。

https://qiita.com/waicode/items/61ec0f9478fdb8a8e542

技術ブログと同じ環境でZennを書けるようにした結果

もともと「技術ブログと同じ環境で記事が書けたら、効率もモチベーションも上がりそう」がボイラープレート作成に至ったきかっけでした。実際につくってみて、作業効率以上に情報発信面でメリットを感じることができました。

詳しくは以下の記事にまとめています。よろしければご覧ください。

https://archt.blue/articles/boilerplate

脚注
  1. 中身を自分で埋める必要がある「テンプレート」に対して、変更せずにそのまま使える定型的なソースコードや設定ファイル群を意味します。 ↩︎

GitHubで編集を提案

Discussion

haoblackjhaoblackj

良記事ありがとうございます。
devcontainer便利ですよね……。

cspellは初めて知りました、早速取り入れてみようと思います。

誤字がございましたので、PRを発行しております。
お手すきの際にご確認いただければ。
https://github.com/waicode/zenndocc/pull/1

hankei6kmhankei6km

ボイラープレートの公開ありがとうございます。

Zenn 記事作成の環境を見直したいなと思っていたので textlint の設定など参考になります。

そして少し確認なのですが、こちらのボイラープレートは GitHub Codespaces はサポート外でしょうか?

参考に動かしてみようと Codespace を作成したところ Codespace では workspaceFolder が無視されてしまうので動作しませんでした。

状況としては Codespace 側がマウントしているワークスペース(リポジトリ)では node_modules にマウントされているボリュームが見えないため NPM スクリプトなどが失敗します。

現在、困っている状況ではないのでサポート外であっても支障はありません。ですが、念の為お知らせしておいた方がよいかと思いコメントしました。

あとは、node_modules が空の状況のときに、npx でエラーになっていました。

https://github.com/hankei6km/zenn-content-boilerplate/commit/9230feb7580846bafdaf9ec3cfce14447223040d

こちらは、あとで Issue か PR を送ります。

waicodewaicode

Codespace、未検証でした。VSCodeがよく使われうる環境は対応したいので、確認します。
プルリクもありがとうございます!確認させていただきます。

hankei6kmhankei6km

ご返信ありがとうございます。

それでは、わかっている範囲で GitHub の方に Issue 立てます。よろしくお願いいたします。