📝

VSCode + 開発コンテナ で Zenn の管理をやってみる

2024/12/06に公開

💬 はじめに

はじめまして、まきのすけです!
今回から自己アウトプットの一環として Zenn を始めることにしました。
今後、Zenn のコンテンツを効率よく管理するために、GitHub と VSCode 、開発コンテナを組み合わせて活用してみます。

調べてみると、Zenn 用のテンプレートリポジトリがいくつか公開されています。
今回はそれらを参考にしつつ、コンテナ作成の勉強も兼ねて自分用のリポジトリを自作してみました。
この記事では、このテンプレートリポジトリの使い方や開発コンテナの概要についてご紹介します。

📦 リポジトリ概要

今回作成したテンプレートリポジトリがこちらです。

https://github.com/mknsk0309/tmp-zenn-contents

VSCode + 開発コンテナで効率的に Zenn の記事や本を執筆できます。
このテンプレートリポジトリの特徴をご紹介します。

  1. VSCode + 開発コンテナでの執筆作業

    Zenn の記事や本を VSCode 上で編集でき、リアルタイムプレビューも可能です。
    VSCode の直感的な操作性と ZennCLI の便利さを組み合わせることで、執筆作業がスムーズに進められます。

  2. Docker で統一された環境

    開発コンテナを使用することで、以下のメリットが得られます:

    • 作業環境を誰でも簡単に再現可能。
    • ローカル環境をクリーンに保ちつつ、セットアップの手間を最小限に抑えられる。
    • 複数の PC を併用しても、同じ環境で作業が可能。
  3. 画像ファイルの自動挿入

    Markdown ファイルにクリップボードから画像をペーストするだけで、画像ファイルが自動的に保存され Zenn に適した形式へ変換されます。

  4. textlint / Markdownlint による文章校正

    文章や Markdown 記法の校正をサポートする lint ツールを導入しています。

🛠️ テンプレートの使い方

さて、このテンプレートリポジトリは GitHub で公開しています。
「細かいことはいいから、使い方を教えてくれ!」という方向けに、先に使い方をご紹介します。

前提条件

まず、このテンプレートを使用するにあたり、以下の環境が整っていることが前提です。

  • GitHub アカウントを持っていること

  • VSCode をインストール済みであること

  • Docker環境 (DevContainer 対応) が構築済みであること

これらの準備が整っていない場合は、公式ドキュメントなどを参考にセットアップしてください。


初期構築手順

前提条件をクリアしている方は、以下の手順でご自身の環境をセットアップしてください。

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

    テンプレートリポジトリ にアクセスし、Use this template ボタンをクリックしてリポジトリを複製します。

    alt text

  2. ローカル環境にリポジトリをクローンする

    複製したリポジトリを手元の環境にクローンします。

    git clone https://github.com/your-username/your-repository.git
    cd your-repository
    
  3. クローンしたリポジトリを VSCode で開く

    クローンしたディレクトリを VSCode で開きます。

    code .
    
  4. 開発コンテナを立ち上げる

    VSCode のコマンドパレットから Dev Containers: Reopen in Container を選択します。
    必要な Docker イメージが自動的にビルドされ、開発環境がセットアップされます。

    コマンドパレットの開き方
    • Windows: Ctrl + Shift + P
    • Mac: Cmd + Shift + P
  5. Zenn Editor にアクセスできることを確認する

    ブラウザで http://localhost:8080 にアクセスし、Zenn Editor が表示されることを確認してください。

  6. Zenn のアカウントから GitHub を連携する

    以下の記事を参考に、GitHub との連携設定を行なってください。
    https://zenn.dev/zenn/articles/connect-to-github

これで Zenn のコンテンツ管理する準備が整いました!


使用コマンド

ZennCLI の操作を簡略化をするため、よく使うコマンドを npm script でラップしています。
以下のコマンドを使用することで、記事や本の作成が手軽に行えます。
また、VSCode のエクスプローラーにある NPM SCRIPTS から GUI による実行も可能です。

  • 新しい記事を作成する

    articles/ ディレクトリに自動生成されたスラッグの記事ファイルが作成されます。

    npm run new-article
    
  • 新しい本を作成する

    books/ ディレクトリに自動生成されたスラッグの本ディレクトリが作成されます。

    npm run new-book
    

🌐 環境詳細

さて、ここからはこのテンプレートの構成や細かい設定内容についてご紹介します。

ディレクトリ構成

以下のディレクトリ構成でコンテンツを管理しています。

.
├─ .devcontainer/    # 開発コンテナ設定ファイル
├─ .github/          # GitHub 設定ファイル
├─ articles/         # Zenn 記事ファイル
├─ books/            # Zenn 本ファイル
├─ images/           # 画像ファイル
│  ├─ articles/      # 記事用画像ファイル
│  └─ books/         # 本用画像ファイル
├─ scripts/          # スクリプトファイル
└─ setting/          # 設定ファイル

VSCode の設定

このテンプレートでは、Zenn の記事執筆や管理を効率化するため、VSCode の各種設定や拡張機能を活用しています。

VSCode 拡張機能

VSCode の開発コンテナ内では、以下の拡張機能が自動的にインストールされます。


VSCode 設定

VSCode の動作をカスタマイズする設定内容は、.vscode/settings.json に定義されています。
以下に主な項目を解説します。

  • ファイル保存時の動作

    • "editor.formatOnSave": true
      保存時にコードフォーマットを自動実行。

    • "emeraldwalk.runonsave"
      ファイル保存時に画像パスを更新するスクリプトを実行。
      詳細は その他の便利機能 の章を参照。

  • Markdown 設定

    • "markdown.copyFiles.destination"
      画像ファイルを自動保存するディレクトリを指定。

    • "markdowntable.formatOnSave": true
      Markdown ファイル内のテーブルをファイル保存時に自動的整形。


コードスニペット

Markdonw の執筆を効率化するため、Zenn 用にカスタマイズしたスニペットを用意しています。
詳しくは .vscode/zenn.code-snippets を参照してください。


コンテナの設定

コンテナの設定は主に以下のファイルで構成されています。

VSCode 開発環境の定義 (.devcontainer/devcontainer.json)

https://github.com/mknsk0309/tmp-zenn-contents/blob/f958f9dec023190ec6262393e4dc0ddb50a9bf44/.devcontainer/devcontainer.json#L1-L22

  • name
    コンテナの名前を Zenn Contents Manager に設定しています。

  • dockerComposeFile
    コンテナの起動に使用する Docker Compose 設定ファイル(docker-compose.yml)を指定しています。

  • service
    起動するサービスとして zenn を指定しています(docker-compose.yml に定義)。

  • workspaceFolder
    作業ディレクトリを /workspace に指定しています。

  • customizations.vscode.extensions
    コンテナ内で自動的にインストールされる VSCode 拡張機能のリストを定義しています(詳細は「VSCode 拡張機能」のセクションを参照)。


Docker Compose によるサービス定義 (.devcontainer/docker-compose.yml)

https://github.com/mknsk0309/tmp-zenn-contents/blob/f958f9dec023190ec6262393e4dc0ddb50a9bf44/.devcontainer/docker-compose.yml#L1-L17

  • services.zenn.build

    • context: コンテナのビルドコンテキストをルートディレクトリ (..) に設定。
    • dockerfile: 使用する Dockerfile を .devcontainer/Dockerfile に指定。
    • args: Dockerfile に渡すビルド引数を設定。ユーザー名 (ENV_USERNAME) や作業ディレクトリ (ENV_WORKDIR) を指定。
  • services.zenn.ports
    ホストの 8080 ポートをコンテナ内の 8000 ポートにマッピングします。これにより、ローカル環境のブラウザから Zenn Editor にアクセス可能。

  • services.zenn.volumes

    • ..:/workspace:cache: ローカルのプロジェクトディレクトリをコンテナの /workspace にマウント。
    • node_modules:/workspace/node_modules: node_modules を独立したボリュームとして管理し、キャッシュを活用。
  • services.zenn.command
    コンテナ起動時に yarn zenn preview コマンドを実行し、Zenn Editor のプレビュー環境を提供。


Dockerイメージのカスタマイズ (.devcontainer/Dockerfile)

https://github.com/mknsk0309/tmp-zenn-contents/blob/f958f9dec023190ec6262393e4dc0ddb50a9bf44/.devcontainer/Dockerfile#L1-L19

  • FROM
    ベースイメージとして軽量な Node.js 環境 (node:alpine) を使用。

  • ARGENV

    • ENV_USERNAME: ユーザー名(デフォルトは zenn)。
    • ENV_WORKDIR: 作業ディレクトリ(デフォルトは /workspace)。
    • 環境変数として日本語環境 (LANG) とタイムゾーン (TZ) を設定。
  • RUN

    • 必要なツール(gitbashtzdata)を追加でインストール。
    • 作業ユーザーの作成と、ディレクトリの権限を設定。
  • WORKDIRUSER
    作業ディレクトリを /workspace に設定し、作業ユーザーを zenn に切り替え。

  • COPYRUN
    必要な依存関係ファイル(package.jsonyarn.lock)をコピーし、yarn install で依存パッケージをインストール。


静的解析 (Markdownlint) の設定

デフォルトの設定だと使いづらい部分もあるため、以下の項目については個別で設定しています。

https://github.com/mknsk0309/tmp-zenn-contents/blob/f958f9dec023190ec6262393e4dc0ddb50a9bf44/.vscode/settings.json#L22-L30

  • MD013: 1文の最大文字数を制限

    • Textlint の設定と競合するため無効化。
  • MD024: 見出しの重複禁止

    • 同じ文字列の見出しを必要とする場合があるため、重複を許容。
  • MD026: 見出しに特定の記号(.,;:)を禁止

    • 記号を含む見出しを必要とする場合があるため許容。
  • MD033: HTML 記述の禁止

    • Markdown 内に HTML を記述する柔軟性を確保するため許容。
  • MD034: URL のプレーンテキスト記述の禁止

    • URL をそのまま記述するケースがあるため許容。
  • MD041: ファイルの最初がトップレベル見出しであることを要求

    • 必要に応じて、トップレベル見出し以外の構成を許容。
  • MD045: 画像の代替テキストが必須

    • 一部のケースでは代替テキストを省略する必要があるため許容。

静的解析 (textlint) の設定

このテンプレートでは以下のフィルターやプリセットを使用して文章を校正します。

https://github.com/mknsk0309/tmp-zenn-contents/blob/f958f9dec023190ec6262393e4dc0ddb50a9bf44/config/.textlintrc.jsonc#L1-L69

使用フィルター

  • textlint-filter-rule-comments
    コメント内の文章はフィルタリングし、解析対象外とします。

使用ルールプリセット

以下、使用しているルールプリセットと、デフォルト値から変更しているルールについて紹介します。

  • textlint-rule-preset-ja-spacing
    日本語文章のスペースに関するルールを適用。

    • ja-space-between-half-and-full-width

      • 半角英数字と全角文字の間にスペースを挿入。
      • 適用対象: アルファベット、数字。
    • ja-space-around-code

      • インラインコード(バッククォート)前後にスペースを挿入。
    • ja-space-around-link

      • リンクの前後にスペースを挿入。
  • textlint-rule-preset-ja-technical-writing
    技術文書向けのルールセットを適用。

    • sentence-length

      • 1 文の最大文字数を 150 に制限。
    • no-exclamation-question-mark

      • 全角の感嘆符(!)や疑問符(?)の使用を許可。
    • ja-no-mixed-period

      • 文末記号に「:」や「:」を許可。
    • no-doubled-joshi

      • 同じ助詞が連続する場合をチェック(例外として「も」「や」「か」を許可)。
      • 分かち書きの文字として句読点や括弧も許可。
    • no-mix-dearu-desumasu

      • 敬体(ですます調)と常体(である調)の混在を検出。

その他の便利機能

画像ファイルパスの自動修正

VSCode には、クリップボードの画像をペーストするだけで、自動的に画像ファイルを特定のフォルダに保存し、そのパスを Markdown ファイルに貼り付けてくれます。
しかし、この機能では画像ファイルへのパスが相対パスとして記載されるため、そのままでは Zenn に記事を公開する際に正しく読み込まれません。

Zenn 公式ガイド では、画像パスについて次の注意点があります。

参照するには、画像埋め込み記法の URL 部分に /images/ から始まる絶対パスを指定します。相対パスで指定しないようご注意ください。

つまり、画像ファイルへのパスを Zenn のルールに従って絶対パスに修正する必要があるのです。

VSCode の標準機能ではこの絶対パスへの変換を自動化できなかったため、このテンプレートでは以下の仕組みで実現しています。

  1. 画像パス置換用のスクリプトを用意

    Markdown ファイルに記載された画像ファイルのパスを絶対パスに置換する スクリプト を作成。

  2. 保存時にスクリプトを自動実行

    Run on Save 拡張機能を利用し、books/ および articles/ ディレクトリ内の Markdown ファイルが保存された際に、上記スクリプトを自動実行する。
    以下が、実際の設定内容です。

https://github.com/mknsk0309/tmp-zenn-contents/blob/f958f9dec023190ec6262393e4dc0ddb50a9bf44/.vscode/settings.json#L31-L38

🏁 まとめ

このようにして、Zenn のコンテンツを管理する環境が整いました🎉
この環境を活用しながらこれからアウトプットし続けるサイクルを生み出していきます!

Discussion