Closed15

VSCode Web Extension for Zenn Preview がほしい

ピン留めされたアイテム
kiaikiai

TL; DR

  • markdown-it-zenn みたいな感じで zenn-markdown-html 周りの処理を Plugin として抜き出しましょう(最優先タスク)
  • markdown.previewScriptszenn-embed-elements を使うのがよくわからん(力不足)
  • CSS分離はできたので,package.json の自動更新&拡張機能の自動ビルド手続きがほしい

@catnose99 氏~~~ markdown-it-zenn プラグインだけでもシュシュっとつくっておくれよ~~2時間もあればできる気がするので~~

https://github.com/zenn-dev/zenn-community/issues/364

kiaikiai

Web Extensions

github.dev では,ブラウザ上でリポジトリ内のコードを編集できるが,拡張機能に関しては大きく制限がある(有料版の Codespaces は別らしい? が,ここでは誰でも使えることを想定する)

ブラウザ上でも使える拡張機能を特に "Web Extensions" と呼ぶらしい.
通常の拡張機能と同様に package.json で構成する一方で,main エントリーポイントは機能せず,代わりに browser を使えということになっている[1]

拡張機能をつくるときに両方のエントリポイントを指定することはできるが,Web Extensions を使いたいときに browser が指定されていない場合,github.dev 側でインストールできないように制限されるらしい.

脚注
  1. https://code.visualstudio.com/api/extension-guides/web-extensions#web-extension-anatomy ↩︎

kiaikiai

制限

The web extension's main file is defined by the browser property. The script runs in the web extension host in a Browser WebWorker environment. It is restricted by the browser worker sandbox and has limitations compared to normal extensions running in a Node.js runtime.

ここをみると,どのような制限があるかわかる.まぁ,サーバ側ランタイムである Node.js の記法は使えないから気をつけてね,ってことらしい.JavaScript まったくわからん

つまりは,ブラウザ上で実行できる JS スクリプトだけがつかえるよ!って理解でよさそう.

https://code.visualstudio.com/api/extension-guides/web-extensions#web-extension-main-file

kiaikiai

準備

npm install -g yo generator-code してから yo code ってコマンドを打てばいい感じに制限のギャップを吸収する Configuration (via webpack) を準備してくれるらしい.

example
npm yo code

# ? What type of extension do you want to create? New Web Extension (TypeScript)
# ? What's the name of your extension? vscode-zenn-preview
### Press <Enter> to choose default for all options below ###

# ? What's the identifier of your extension? helloworld
# ? What's the description of your extension? LEAVE BLANK
# ? Initialize a git repository? Yes
# ? Bundle the source code with webpack? No
# ? Which package manager to use? npm

# ? Do you want to open the new folder with Visual Studio Code? Open with `code`

https://code.visualstudio.com/api/get-started/your-first-extension

kiaikiai

Markdown Extension

Web Extension の方にも目を通して罠を避けつつ,Markdown Extension という特設ページの記述を参考にして進めていく.

https://code.visualstudio.com/api/extension-guides/markdown-extension

kiaikiai

CSS の適用

yo code で作成したプロジェクトルートには,package.json が生成されている.これに contributes プロパティが追加されているのを確認し,さらに markdown.previewStyles を追記する.このプロパティの値は配列になっていて,適用したい順番で必要な CSS ファイルへの相対パスを並べる.以下の例では,ルートディレクトリに style.css というファイルを置いて参照している.

package.json
{
  "contributes": {
      "markdown.previewStyles": [
            "./style.css"
      ]
  }
}

https://code.visualstudio.com/api/extension-guides/markdown-extension#changing-the-look-of-the-markdown-preview-with-css

先行事例

Markdown Extension の先行事例として,Markdown Preview Github Styling というものが紹介されていた.VSCode のプレビューに GFM Style を適用する拡張機能である.とりあえずはこれのソースを見て真似てみよう.

https://marketplace.visualstudio.com/items?itemName=bierner.markdown-preview-github-styles

kiaikiai

markdown-it Plugin

The VS Code Markdown preview supports the CommonMark specification[1]. Extensions can add support for additional Markdown syntax by contributing a markdown-it plugin.

VSCode は markdown-it に対応しているらしい.これも有効にするためには, package.jsonContributes プロパティに markdown.markdownItPlugins を追加してやればよい.

package.json
{
  "contributes": {
      "markdown.markdownItPlugins": true
  }
}

https://code.visualstudio.com/api/extension-guides/markdown-extension#adding-support-for-new-syntax-with-markdownit-plugins

Plugin の書き方

拡張機能として extendMarkdownIt(md) という関数を書き,activate してやればいいそうだ.browser のエントリポイントとして指定したファイルに,以下のような記述を書けば良い.

index.ts
import type MarkdownIt from 'markdown-it';
import * as emoji from 'markdown-it-emoji';

export function activate() {
    return {
        extendMarkdownIt(md: MarkdownIt) {
            return md.use(emoji);
        }
    };
}

上記コードは markdown-emoji 内の src/index.ts 中に書かれたものである.なるほど案外簡単に作れそうだし,md.use(somePlugins) っていう書き方は個人的にかな~~り最近みた.なんと都合のいいことに,zenn-markdown-html でも同様の書き方だった.これはイケる(確信)

https://marketplace.visualstudio.com/items?itemName=bierner.markdown-emoji

脚注
  1. 【魚拓】CommonMarkの仕様とか - Qiita ↩︎

kiaikiai

Preview 内部で実行するスクリプト

zenn-editor が提供する機能のうち,zenn-embed-elements だけはどうすればいいのかわからない.useEffect() を使って Dynamic import しているが,拡張機能は React 製ではないのでう~ん……

などと考えているうちに,要するに後から非同期的にスクリプトが動くようにすればいいんだろ?ということに気づいた.

というか,ご丁寧にも既に公式ドキュメントに書かれていた(まだ試せていないが多分これでおk).

For advanced functionality, extensions may contribute scripts that are executed inside of the Markdown preview. Contributed scripts are loaded asynchronously and reloaded on every content change.

package.json
{
  "contributes": {
    "markdown.previewScripts": [
      "./main.js"
    ]
  }
}

https://code.visualstudio.com/api/extension-guides/markdown-extension#adding-advanced-functionality-with-scripts

非同期に実行するだけでもありがたいのに,ファイルに変更があるたびにリロードしてくれてもう最高じゃん?

kiaikiai

現時点(2022-01-09)での問題点

package.jsonContributes プロパティを追加し,そこへ以下の三項目を追記すればいいことはわかった.

  1. markdown.previewStyles
  2. markdown.markdownItPlugins
  3. markdown.previewScripts

2については true にして有効化するだけで解決するが,1と3については未だ問題がある

どちらも,パッケージではなく「生のファイルデータ」として用意せねばならない.初期状態として設置するのは簡単だが,外部スクリプトを参照している以上,それらの更新に遅れてしまう事態は避けたい


追記:2022/01/09 18:30

逆に1についてはバンドル側でなんとかできてしまった.2も既にできている部分的なものを抽出してやればいいだけっぽい.真の問題は3で,JS のそれなりの経験者じゃないとわからない可能性がある.Node ランタイムじゃないのムズすぎる(は?)


理想的には,zenn-editorのパッケージ として一括管理してもらうのが一番よい.だが,

lerna を使ったモノレポ管理をしています [1]

とあるように,lerna の中に組み込んだコミットを作ってPRを作る必要がありそうだ.モノレポ管理も同時並行で学ぶのはキツイわね……(情弱)

https://github.com/lerna/lerna

脚注
  1. https://github.com/zenn-dev/zenn-editor/blob/main/CONTRIBUTING.md#構成 ↩︎

kiaikiai

markdown.previewStyles の問題

browser のエントリポイントとなるファイル src/extension.ts において zenn-content-css のインポートを宣言しておき,webpack でコンパイルする際に css-loader [1] を活用して分離させればよい [2] ことがわかった.一先ず,「生のファイルデータとして用意する」という問題の方は解決した.

更新云々については,package.json 側の問題にスコープが移ったことになる.何らかの手段で監視し,自動的にパッケージ更新&ビルド&リリースということになるだろうか.この辺の本番環境的な動きは未だ経験浅く想像がおぼつかない…

脚注
  1. https://webpack.js.org/loaders/css-loader/ ↩︎

  2. https://webpack.js.org/plugins/mini-css-extract-plugin/ ↩︎

kiaikiai

markdown.markdownItPlugins の問題

イケる!と書いたが,zenn-markdown-htmlmarkdown-it の plugin ではなく,Markdown 形式のテキストを HTML 形式のテキストに変えているだけであった.[1]

これでは流用できない!他のプラグイン記述部分は export されておらず,外部からは参照できない……

新たなタスクとして,「markdown-it-zenn をつくる」が追加された瞬間である.仕方がねぇな~~猫の鼻がよ~~~~~~😹


markdown-it の GitHub ページには,プラグイン作者へのアドバイスが載せられていた.これを見つつ,既存のプラグインの組み合わせで新たにプラグインを作る感じで頑張る のがいいと思う,[2] がんばるぞい!!

https://github.com/markdown-it/markdown-it/blob/master/docs/development.md#development-recommendations

脚注
  1. 当該部分の markdownHtml(markdown) ↩︎

  2. というかこれはソースコード見て移せばいいだけなのであった(やるだけ定期) ↩︎

kiaikiai

markdown.previewScripts の問題

まんまこのワードで調べてみても,全然何も出てこない.と思ったらこの記法は v1.63 からの新しいものである模様 [1]

https://github.com/microsoft/vscode/issues/136255


追記:2022/01/10

GitHub 全体で検索かけてみた結果を見ると参考になるかもしれない……あとで確認のこと.


唯一まともにまとまっているのが公式っぽい Extension であるところの Markdown Preview Mermaid Support 内部にあるソースコードしかないという事実……つらいねぇ😢

エントリポイントになっている page.js を観察してみると,よくわかったようなわからんような複雑な気持ちになってきてしまった.果たしてこのような形に zenn-embed-elements を適用させることができるのか?というかもしかして Typescript じゃなくて生 JS 書かなきゃあイケない機運かも??なんにせよ今のままでは見識と時間が足りない.一旦後回しとする.

https://marketplace.visualstudio.com/items?itemName=bierner.markdown-mermaid

脚注
  1. Extension Guides にもロクな情報がなくて草ァ ↩︎

kiaikiai

経過報告:2022/01/14

そのまま流用するだけだったのでおそらくプラグイン自体は書けたはずだが,拡張機能としてVSCodeに仕込むのが全然わからん!となっている

そもそも読み込まれているのか?とかどういうときに有効化しているのか?とか全然何もわかってない…

というかもうzenn-cli起動すればいいかな…の気持ちが強くなりつつある(こんなにも苦労しているのに実現できないのは俺が悪いんじゃなくて複雑怪奇になってしまったVSCode側に問題があるんやないか?という話)

このスクラップは2022/11/08にクローズされました