kondoumh のブログ

- とあるソフトウェアエンジニアのめったに更新されないブログ -

VS Code の ChangeLog メモ用 Extension を Marketplace に公開しました

数ヶ月前に作った VS Code Extention の changelog-support.

blog.kondoumh.com

ずっと ~/.vscode/extensions に手動配置して使ってましたが、せっかくなので Marketplace からインストールできるようにしようと思い立ちました。

VSTS 改め Azure DevOps にアカウントを作成して Publisher 登録とアクセストークン取得が必要です。

dev.azure.com

話がそれますが、この Azure DevOps では、コードリポジトリが作れて、ビルド・テスト・デプロイのパイプラインが構成できます。GitHub のリポジトリとの連携もできますし、 OSS なら無償で使えるそうです。VSTS って使ったことなかったんですが、UI も洗練されていてよい感じですね。

VSTS から UI が変わりましたが、この記事で書かれている通りにいけました。

blog.toshimaru.net

アカウントを作ったら、ひとまず organization を作成します。そして、organization の Settings 画面で公開用のアクセストークンを取得します。

f:id:kondoumh:20180915082528p:plain

Visual Studio Marketplace の publisher 登録画面から Publisher 登録をします。申請の翌日に verify 通知がきました。

以上で、いつでも Marketplace に Plugin を公開できるようになりました。

公開準備として、Extension プロジェクトの package.json に publisher などの情報を追加しました。

  "publisher": "kondoumh",
  "repository": {
    "url": "https://github.com/kondoumh/changelog-support"
  },
  "author": {
    "name": "kondoumh",
    "url": "https://kondoumh.com/"
  },
  "categories": [
    "Other"
  ]

Extension を公開するための CLI ツール vcse をインストールします。

$ npm install -g vsce

Publisher 名でログインします。

$ vcse login kondoumh

この時、事前に取得したアクセストークンを入力します。

あとは Extension プロジェクトディレクトリで公開用コマンドを叩きます。

$ vsce publish

エラーがなければ、パッケージングと公開が数分で完了します。

marketplace.visualstudio.com

最初 アイコンを SVG で作っていたのですが、SVG はダメというエラーが出たので png に差し替えました。アイコンは、draw.io で10分ぐらいで作りました。

VS Code の拡張ビューから検索してインストールできるのはやはり便利です。

f:id:kondoumh:20180915083456p:plain

Marketplace への公開、めんどくさそうと思っていたのですが、意外と簡単にできました。

Express で REST API を TypeScript で書くための boilerplate ジェネレータ

最近 Node.js の Web App Framework である Express で TypeScript を使って REST API を書く機会がありました。

これまでずっとサーバーサイドは Java や .NET で書いてきたので Node.js で書くこと自体が新鮮でしたし TypeScript も久々でした。

作業はもちろん VS Code で行いました。TypeScript への最適化が進んでおり、Eclipse で Java を書いてる (Visual Studio で C# を書いてる)レベルとまでは行かないものの、IDE + 静的型付け言語の開発体験に近づきつつある感じです。コードの見た目も Java や C# にそっくりになります。NPM でなじみのパッケージをインストールして使ったりできるし、型定義ファイルがなくてもコード書けるし、いい感じに緩くてなかなか居心地の良い環境です。

Java ではアプリケーションサーバの起動やモジュールのローディングに時間がかかるため、コード修正 -> 動作確認のサイクルが長くなってしまいますが、Node.js の起動は早いので作業が早く済みます。

Java のサポートが有償化され、Java 離れが進むことが予想される中、Express (および類する Node.js のフレームワーク) も移行先として有力な選択肢になるかもしれません。

ところで、フレームワークを使って開発を始める時は、定型的なコードをたくさん書くのが面倒なので、プロジェクトテンプレートやボイラープレートの類が欲しくなります。もちろん Express でもたくさん提供されていて、すぐに見つかるのが Express Generater というやつです。

www.npmjs.com

これは、TypeScript ではなく JavaScript のコードを生成しますので TypeScript に置き換える作業が面倒です。

ということで見つけたのがこちら。

www.npmjs.com

Yeoman を使用してコード生成するジェネレータです。

$ yo express-no-stress myapp

でアプリが生成されます。

f:id:kondoumh:20180905215250p:plain

Swagger も統合されていていい感じに API 開発できそうです。

Express では ejs というテンプレートエンジンがあり、サーバーサイドレンダリング処理も普通に書けますが、このジェネレータは API にフォーカスしているようです。今回は、API 開発の用途で探してたのでこれ以上追及はしていません。

GitBook + GitHub Pages でレガシードキュメントを移行

iEdit のユーザーズマニュアルはとてもレガシーです。

iEdit ユーザーズマニュアル

以前 Google Sites に引っ越そうと思って、サイト作ってカスタムドメイン設定してたのですが、リリースノートを更新するのみで放置して何年も経ってしまいました。その間 Google Sites もリニューアルされ HTTPS 対応もしましたが、WYSIWYG に寄り過ぎていて構造化されたドキュメントを書くプラットフォームとしてはちょっと・・という気がします。

最近、GitBook でドキュメントを Markdown で記述して静的コンテンツを公開できることを知り移行作業をしてみました。

GitBook の CLI をインストール

$ npm install gitbook-cli -g

プロジェクトを作成

$ mkdir iedit-doc
$ cd iedit-doc
$ gitbook init

空ディレクトリの場合、SUMMARY.md / README.md が生成されます。SUMMARY.md にドキュメントの構造を記述します。

# Summary

* [イントロダクション](README.md)
* [インストール](overview/install.md)
* [ノードの作成と編集](editing/edit_node.md)
 * [ノード作成](editing/edit_node.md#ノード作成)
 * [ノード編集](editing/edit_node.md#ノード編集)
* [リンクの作成と編集](editing/edit_link.md)
 * [リンク作成](editing/edit_link.md)
 * [リンク編集](editing/edit_link.md)
* [インポート・エクスポート](features/import_export.md)
* [検索](features/search.md)
* [メニューコマンド](features/menu.md)
* [各種設定](settings/README.md)
 * [オプション設定](settings/option_settings.md)
 * [ファイルタイプの登録・削除](settings/filetype_registry.md)
* [リリースノート](releasenotes/README.md)

README.md が index.html に変換されます。

SUMMARY.md が決まったら gitbook init を再実行すると、フォルダ構成と必要なファイルを作ってくれます。あとは、書きながら調整していくのがよいでしょう。

book.json を追加して、ドキュメントのタイトルや GitBook のバージョン設定、サイドバーのリンクなどを記述します。plugins に GitBook のプラグイン (実体は NPM モジュール) を指定できます。

{
    "title": "iEdit User's Guide",
    "description": "",
    "plugins": ["expandable-chapters", "ga"],
    "language": "ja",
    "gitbook": ">= 3.0.0",
    "links": {
        "sidebar": {
            "kondoumh.com": "https://kondoumh.com/software/iedit/"
        }
    },
    "pluginsConfig": {
        "ga": {
            "token": "UA-XXXXXXX-X"
        }
    }
}

plugins でプラグインを指定して以下のコマンドでプラグインのインストールが可能です。

$ gitbook install

NPM モジュールなので package.json を記述して npm install でもインストール可能です。その場合は、パッケージ名のプレフィクス gitbook-plugin- が必要になります。

サイドバーの見出しを折りたたむことができる expandable-chapters プラグインと Google Analytics のトラッキングコードを埋め込む ga プラグインを追加してみました。

www.npmjs.com

www.npmjs.com

他にも YouTube の動画を組み込むプラグインなど色々と提供されてます。

ローカルでブラウザでプレビューしながら Markdown を書いていけます。

$ gitbook serve

localhost:3000 にアクセスすると、サイドバー付きのページを確認できます。

この状態で、既存の HTML から内容をコピペ&リライトしながら移行していきました。

ある程度できたところで公開先を検討。最初これまで通り kondoumh.com に配置することも考えましたが、リリースノートも移行して旧 Google Sites サイトを廃止しつつ URL が変らないようにしたいということで独立サイトにすることにしました。GitHub Pages は独自ドメインと HTTPS に対応していて GitBook ドキュメントも簡単に公開できることを知り、渡りに船ということで GitHub Pages を使うことに決定。

ライブリロード中に HTML の変換は随時やってくれますが、シンタックスエラー等でちゃんと反映されてない可能性もありますので、最終的に build します。

$ gitbook build

デフォルトの出力先は、_book ですが、GitHub Pages のお手軽設定だと docs にしておくのがよいです。その場合は、以下のようにします。

$ gitbook build <source dir> ./docs

ついでですが、ライブプレビューでも build と同じ引数で起動した方がいいでしょう。

$ gitbook serve <source dir> ./docs

ここまでくると、package.json を導入して npm script を書いた方がいいですね。ちなみに Markdown ファイルを置く <source dir> は books.json の root キーで指定可能ですが、出力先の指定はできません。Issue が上がっていました。

github.com

ともかく、ドキュメントが書けたら、GitHub に docs フォルダを含めて push します。

github.com

push したリポジトリの Settings タブを開き、GitHub Pages を有効化し設定します。

f:id:kondoumh:20180826123244p:plain

Source で master branch /docs folder を設定します。master への push が即座に反映されるため gh-pages ブランチを作成して push する方法よりも、一人作業だと手軽でよいと思います。

Google Sites のドメイン設定を解除して、Custom Domain に設定しました。Enforce HTTPS も数分で有効化することができました。

リニューアルしたサイト

イントロダクション · iEdit User's Guide

中身はほとんど変えてないし、スクリーンショットも古いのを流用しているので新しい感は薄いかもしれませんが、外側はレスポンシブなモダンな感じになりました。更新も手軽になりましたし。

Jekyll と比べても導入が楽で、手軽に公開・更新でき、PDF も生成できる GitBook はドキュメント作成環境として有力な選択肢だと思います。

vcpkg で OSS のライブラリを導入し Visual C++ プロジェクトに静的リンクする

仕事では久しく C++ のコードを書いていませんが、最近 iEdit で JSON を扱えるようにしようと思って C++ の REST 関連ライブラリを物色していたところ、Microsoft が C++ REST SDK という OSS ライブラリを開発しているのを知りました。

github.com

Java でいうと Jersey と Jackson が一緒になったようなライブラリです。JSON の読み書きしか使いませんが、なかなかよいので採用することにしました。

最初は NuGet でパッケージをインストールして開発してました。必要な C++ のヘッダーファイルと DLL が降ってくるので開発は問題なくできるのですが、配布の際に DLL を同梱する必要があります。利用者の利便性を考えると極力ワンバイナリで提供したいので static リンクする方法を調べました。

昔は C/C++ のライブラリは、個別にソースコードをダウンロードして make / make install してました。Linux だと APT などのパッケージマネージャでバイナリを取得・インストールできますし、Mac の brew のようにソースコードベースのパッケージ管理システムもあります。

今回知ったのですが、Microsoft も近年クロスプラットフォームのソースコードベースパッケージ管理システムを OSS として開発しています。

github.com

ということで、まず vcpkg をビルド (PowerShell で実行します)。

PS> .¥bootstrap-vcpkg.bat

vcpkg.exe が生成されたディレクトリが vcpkg のルートディレクトリとなり、配下にパッケージを取得してビルド・インストールしていきます。

この時点で Visual Studio とのインテグレートをやっておきます。

PS> .¥vcpkg integrate install

あとは、導入したいパッケージを指定してインストールするだけです。

C++ REST SDK を公式 README 通りに以下のコマンドでインストールしました。

PS> .¥vcpkg install cpprestsdk cpprestsdk:x64-windows

C++ REST SDK は Boost C++ ライブラリに依存しているので、2コアの Core i5 マシンだとビルドに48分ぐらいかかりました。

その後、自プロジェクトから NuGet 版を削除してリビルド。エラーなく完了しました。

これは便利。integrate install しているため Visual C++ のプロジェクト設定で include パスの指定や lib の追加をしなくても大丈夫になっています。OSS のライブラリを気軽に試せますね。

ところで、生成されたバイナリのフォルダを確認したところ削除したはずの cpprest_2_10.dll がいました。ダイナミックリンク版になってしまっているようです。これだと時間かけてビルドしたのに NuGet と同じ結果です。

StackOverflow に QA がありました。

stackoverflow.com

static link 版はパッケージ名が違いました。しかも static link 版は integrate install していても自プロジェクト側で include パスなどを設定する必要があるそうです。

ということでまず static link 版をインストールしました。

PS> .¥vcpkg install cpprestsdk:x86-windows-static

その上で自プロジェクトの構成プロパティを設定(後述)。しかし、自プロジェクトをビルドするとやっぱり DLL を取ってきてしまいます。どうも DLL 版のパッケージがインストールされているとそちらを優先するようです。そこで DLL 版パッケージを削除しました。

PS> .¥vcpkg remove cpprestsdk:x64-windows

この状態でビルドしたところ、無事に static link されたバイナリが生成されました。

自プロジェクト側の構成プロパティ設定です。

C/C++ → プリプロセッサ → プリプロセッサの定義に _NO_ASYNCRTIMP を追加します。

f:id:kondoumh:20180822210420p:plain

C/C++ → コード生成 → ランタイムライブラリで マルチスレッド(MT) を選択します。

f:id:kondoumh:20180822205959p:plain

VC++ ディレクトリ → 全般 → ライブラリディレクトリに vcpkg のインストール先の lib ディレクトリを追加します。

f:id:kondoumh:20180822210900p:plain

リンカー → 入力 → 追加の依存ファイルに静的リンクしたいライブラリのファイル名を追加します。

f:id:kondoumh:20180822210937p:plain

C/C++ → 全般 → 追加のインクルードディレクトリに vcpkg のインストール先の include ディレクトリを追加します。

f:id:kondoumh:20180822211147p:plain

ディレクトリは相対パス指定がうまくできなかったので $(HOMEDRIVE)$(HOMEPATH) で逃げました。

ちょっと面倒ですが、NuGet で DLL 取得するのではなく vcpkg でビルドすることで好みの設定で使うことが可能ということですね。

Microsoft Remote Desktop 10 で macOS から Windows 10 ラップトップを使う

会社支給のラップトップが交換時期でリニューアルされました。Let' note CF-SZ6 です。

panasonic.biz

Windows 10 マシンなので開発機として利用することにしました。

自宅では MacBook Pro 13 inch オンリーですので、これまで Windows は VMware Fusion の仮想マシンで運用してきました。メモリ4GB / コア数2という構成で Visual Studio で .NET や C++ 開発はできますがやや非力です。SZ6 は Core i5 / 8GB RAM なので仮想マシンよりかなりキャパがあります。

自宅ワークスペースは狭くて2台のマシンを置いて使うことはできません。それに、外部ディスプレイの WQHD 解像度は SZ6 の HDMI からは出力できません。※ そこで MacBook から Remote Desktop で接続して使うことにしました。

※ 2018.9.17 追記 Intel Graphics の設定でカスタム解像度を追加して選択すると反映されました。

最初は以前にインストールしていた Microsoft Remote Desktop 8 を使いました。ドメインユーザの設定ができず毎回ログインし直しが必要だったり、Mac の 英数 / かな キーをスペースキーと認識してしまい IME のオンオフを別キーに割り当てなければいけなかったりと、かなりイマイチでした。これは常用厳しいなと思って App Store を見るとバージョン10が別アプリとしてリリースされています。

Microsoft Remote Desktop 10

Microsoft Remote Desktop 10

  • Microsoft Corporation
  • ビジネス
  • 無料

インストールして試したところ、上記の問題はすでに解消されており快適に使えるようになりました。レビューにあるような JIS キーボード認識されない問題も発生しませんでした。

さらに 8 ではなかった特徴として、

  • セッションが切れてもキャッシュが残っていれば再接続してくれる
  • macOS の キーショートカットを有効にできる
  • クリップボードのテキストデータをローカルとリモートで相互に共有できる
  • 実行中のリモートデスクトップ をサムネイル表示できる

といった機能まで実装されています。

f:id:kondoumh:20180812023036p:plain

これで仮装マシンから乗り換えられそうです。WiFi 経由でレイテンシーがあるため VMware Fusion で使っているのと体感的に大差ありませんが、実際には 2コア(Hyper-Threading で論理的には4コア) マシンを外部で使っているわけで MacBook のリソースにも余裕が出ます。

仮想マシンではリソースをケチるため Chrome や VS Code もインストールしてませんでしたし WSL も使ってませんでしたが、それらの制約もなくなりました。

VMware Fusion の仮想マシンは予備環境として眠らせておくことにしました。

Fintie Apple Magic キーボードケース for iPad を購入

Anker の iPad キーボードカバー TC930 愛用してるんですが、突然 7, 8, 9, 0 のキー (Shift を押すと &, *, (, )) が入力できなくなってしまいました。

scrapbox.io

重量と取り回しの良さでは出色だったので別の選択肢がなかなかありません。

以前、Magic Keyboard と iPad の組み合わせが非常に良いという話を書きました。

blog.kondoumh.com

Magic Keyboard を iPad のコンパニオンとして持ち歩ければいいのですが、カバーと違って iPad スタンドがありません。Finite 製の Magic Keyboard ケースが良さげなのは以前から見ていましたが、国内未発売。今回 iPad キーボードを物色して Amzaon.jp を見ていたら、なんと同ケースが出品されていました。しかも4000円代。残り1点の表示で反射的にポチってしまいました。

Fintie Apple Magicキーボードケース

Fintie Apple Magicキーボードケース

こういうケースに Magic Keyboard をはめ込み

f:id:kondoumh:20180801001558j:plain

カバーの紐部分をこのように組み立て(マグネット製)

f:id:kondoumh:20180801001611j:plain

iPad を置く台をセットアップします。Magic Keyboard はジャストフィットではまるので安定感あります。

f:id:kondoumh:20180801001338j:plain

iPad との大きさ比較はこのような感じ

f:id:kondoumh:20180801001425j:plain

やはり iPad のカバータイプと比べるとかなり大きいです。

クラムシェルにならないので Surface 同様、スタンド部分の奥行きが必要です。iPad は固定されていないですが、膝上でも使えなくはないです。

で、結論としては使うかどうか微妙って感じです。

キーボードを取り出して、セットアップするまで数ステップあるので取り回しという点では、TC930 にはかなり劣ります。Magic Keyboard JP ということで Mac とほぼ同じ感じで入力できるところは Good ですが・・とりあえず新幹線移動などで使ってみようかと思います。

静的サイトの構造見直し

2年以上前に mh.home のデザインをリニューアルしました。

blog.kondoumh.com

この時は、Google Web Starter Kit を使いました。Material Design っぽい Responsive なページが作れて、BrowserSync でクロスブラウザテストが簡単。Gulp でのタスクパイプラインが用意されていてすぐに作成に取りかかれるというものでした。

github.com

2016 年までリリースされてましたが、更新止まってます。

静的サイトは更新頻度少ないので、たまにメンテしようとすると、NPM や Gulp のエラーが出て萎えます。HTML 書くのもだるいです。

最近は、static site generator が流行っているので乗り換え先候補として、React StaticHexo の使い心地を試してみました。Markdown で書けて更新楽そうです。

これらツールで生成されたサイトは、わかりやすいパス構造のディレクトリが掘られ、パスごとに index.html を配置するという構成になっています。かたや mh.home は適当な命名の html ファイルを直接参照する方式。static site generator を導入する前に今の構造を見直した方が良さそうです。

ということで、久々に Web Starter Kit のプロジェクトの package を更新して、Gulp のエラーを解消し、サイト構造を修正しました。

before after
Top /index.html /
Profile /profile.html /profile/
History /history.html /history/
Software /software/index.html /software/
iEdit /software/iedit.html /software/iedit/
iEdit Download /software/dliedit.html /software/iedit/download/
iEdit Tools /software/iedittools.html /software/iedit/tools/

パス構造がわかりやすく正規化されました。URL 末尾のスラッシュ (trailing slash) はファイルではなくディレクトリへの要求を表すことになるそうです。

既存のページへのリクエストをリダイレクトさせるため .htaccess で Rewrite を設定。

今回はここで力尽きました。

kondoumh.com