How to build mapbox-gl-js stand-alone on Windows

実質作業メモ。Windowsでの話です。

追記

ビルド作業が初めてではない(下記本編の内容を実施済み等)場合、ツール群のインストールは不要なため、下記手順のみ行う。

  1. cmd開いて cd mapbox-gl-js (ディレクトリ移動)して
  2. SET MAPBOX_ACCESS_TOKEN={YOUR MAPBOX ACCESS TOKEN} して
  3. yarn install して(必要なら)
  4. ファイル生成
    yarn run build-prod-min → dist/mapbox-gl.js
    yarn run build-css → dist/mapbox-gl.css

本編

下記のページに手順が書いてあるので実施していきます。

mapbox-gl-js/CONTRIBUTING.md at master · mapbox/mapbox-gl-js · GitHub

必要なツール群をインストール

Install gitnode.js (version 4 or greater), yarnnpm and node-gyp.

と書いてあるので、それぞれインストールしていきましょう。

git

もう入ってた。

node.js

ダウンロード | Node.js からWindows用のインストーラーをDLして実行して終わり。

Yarn 

Installation | Yarn からWindows用のStable(安定版) ver.のインストーラーをDLして実行して終わり。

npm and node-gyp.

nodejs-guidelines/windows-environment.md at master · microsoft/nodejs-guidelines · GitHub に詳しい。

  1. Windows PowerShell を管理者権限で起動
  2. npm install -g windows-build-tools を実行し、
    windows-build-tools をインストール
    ※トラブルシューティング情報も上記ページに記載あり
  3. Visual Studio Build Tools あるいは Visual Studio 2017 Community より、Visual C++ ビルド環境をインストール
  4. https://www.python.org/downloads/ よりPython2.7をインストール
  5. npm config set python python2.7 を実行
  6. npm config set msvs_version 2017 を実行

リポジトリをクローンする

git clone git@github.com:mapbox/mapbox-gl-js.git とコマンドを打ってもいいし、適当なGitHubクライアントでCloneしてもいい。

※特定のバージョンや安定版がほしい場合は、下記ページからzip等でファイルを取得する。
https://github.com/mapbox/mapbox-gl-js/releases

node moduleの依存関係をインストールする

  1. cd mapbox-gl-js (ディレクトリ移動)して
  2. yarn install を実行してインストール

warning "@mapbox/dr-ui > @mapbox/mapbox-gl-supported@1.4.1" has unmet peer dependency "mapbox-gl@>=0.32.1 <2.0.0". とかみたいなエラーが出たら、cmdを閉じて開き直してインストールコマンドを再実行すると多分解決する。

headless-gl の依存関係をインストールする

依存関係は下記。  https://github.com/stackgl/headless-gl#windows

  • Python 2.7
    ※ 先ほどの手順でインストール済
  • Microsoft Visual Studio
    ※ Visual C++ ビルド環境がほしいだけなので先程の手順でインストール済
  • d3dcompiler_47.dll
    c:\windows\system32に入っているのでOK
  • ES6 (モダンnode.js向け。オプション)
    ※ オプションなので多分不要

最終的にやりたいことは下記コマンドの通り。
copy node_modules/headless-gl/deps/windows/dll/x64/*.dll c:\windows\system32

headless-glをクローンする

stackgl/headless-gl: 🎃 Windowless WebGL for node.js をクローンする。

※特定のバージョンや安定版がほしい場合は、下記ページからzip等でファイルを取得する。
https://github.com/stackgl/headless-gl/releases

dllファイルをコピー

headless-gl\deps\windows\dll\x64\以下のdllファイルをc:\windows\system32 にコピーする。

ビルドに使うデバッグサーバの用意

mapboxアクセストークンの取得

  1. Mapbox のアカウントを作成
  2. Account | Mapbox > Tokens > Create a token からアクセストークンを作成
  3. Tokens にて、作成したトークンをコピー

デバッグサーバ起動確認

  1. cmdを起動して cd mapbox-gl-js (ディレクトリ移動) して
  2. SET MAPBOX_ACCESS_TOKEN={YOUR MAPBOX ACCESS TOKEN} を実行
    ※ここでSETした環境変数は、このセッションでのみ有効。cmdを終了すると消去される。
  3. yarn run start-debug を実行

デバッグサーバ http://localhost:9966/debug にアクセスできることを確認する。

スタンドアロンビルドを作成

以下のコマンドを実行する。
yarn run build-prod-min
yarn run build-css

dist/mapbox-gl.jsdist/mapbox-gl.css が生成されるので確認する。
HTMLではこの2つのファイルを読み込んで利用する。

余談

yarn run build-prod-min 実行時の出力が下記である。
なにやら警告?エラー?がいっぱい出ている。

mapbox-gl-js>yarn run build-prod-min
yarn run v1.19.0
$ rollup -c --environment BUILD:production,MINIFY:true

src/index.js, src/source/worker.js → rollup/build/mapboxgl...
(!) Circular dependency: src\util\ajax.js -> src\util\mapbox.js -> src\util\ajax.js
(!) Circular dependency: src\style-spec\expression\parsing_context.js -> src\style-spec\expression\compound_expression.js -> src\style-spec\expression\parsing_context.js
(!) Circular dependency: src\style-spec\validate\validate.js -> src\style-spec\validate\validate_function.js -> src\style-spec\validate\validate.js
(!) Circular dependency: src\style-spec\validate\validate.js -> src\style-spec\validate\validate_function.js -> src\style-spec\validate\validate_object.js -> src\style-spec\validate\validate.js
(!) Circular dependency: src\style-spec\validate\validate.js -> src\style-spec\validate\validate_function.js -> src\style-spec\validate\validate_array.js -> src\style-spec\validate\validate.js
(!) Circular dependency: src\style-spec\validate\validate.js -> src\style-spec\validate\validate_layer.js -> src\style-spec\validate\validate_paint_property.js -> src\style-spec\validate\validate_property.js -> src\style-spec\validate\validate.js
(!) Circular dependency: src\style-spec\validate\validate.js -> src\style-spec\validate\validate_layer.js -> src\style-spec\validate\validate.js
(!) Circular dependency: src\style-spec\validate\validate.js -> src\style-spec\validate\validate_light.js -> src\style-spec\validate\validate.js
(!) Circular dependency: src\style\style_layer\symbol_style_layer.js -> src\data\bucket\symbol_bucket.js -> src\style\style_layer\symbol_style_layer.js
(!) Circular dependency: src\geo\lng_lat.js -> src\geo\lng_lat_bounds.js -> src\geo\lng_lat.js
(!) Circular dependency: src\source\tile.js -> src\data\feature_index.js -> src\source\source_state.js -> src\source\tile.js
(!) Circular dependency: src\index.js -> src\ui\map.js -> src\style\style.js -> src\util\global_worker_pool.js -> src\util\worker_pool.js -> src\util\browser\web_worker.js -> src\index.js
created rollup/build/mapboxgl in 11.7s

rollup/mapboxgl.js → dist/mapbox-gl.js...
created dist/mapbox-gl.js in 2s
Done in 14.43s.

「Circular dependency」って何??
直訳すると「循環依存」 となるのでやんわりと察した。
AがBに依存し、BはAに依存しているのでウロボロスって話。

警告は出ているけど mapbox-gl.js は生成されているし、HTML側で読み込んでも(おそらく)正常に動いている(ように見える)。

とりあえず様子見。

Ghost Inspector テストの共通化

弊社では、製品の自動テストにGhost Inspectorを利用しています。

ある日のことです。

「この画面消して新しい画面に置き換えるからテストの方も修正しといてよ」

OKまかせろ。

意気揚々とGhost Inspectorのダッシュボードを開きます。

コピペで複製されたものに微妙に改変が加わったり加わらなかったり無造作に乱立したガバガバテスト群を目撃したぼく「がっでむ」

キレた

プログラミングを行う際、共通の処理は関数化を行うなど、なるべく記述を重複させないという方針がございます。
いわゆるDRY原則というやつですね。(厳密には、よく聞くDRY原則は誤認されたものだと言われていますが、話が逸れるので適当なネット記事に任せます)

コードを書いている感覚の少ないGhost Inspectorだって、共通した処理の再利用は重要です。

  • メンテナンスコストの軽減
  • テスト修正時の修正漏れの防止
  • 再利用性の向上
  • 似ているテスト同士の差分確認の容易化

あたりの利点はパッと思いつきますね。特に上2つが現場的には嬉しいところです。

本題

実際に共通化を行っていきます。
今回は、「元々(ほぼ)同じ内容のテストがコピペ乱立していたものを、1つの共通テストを再利用する形に修正し、メンテナンスコストを軽減する」といったシナリオです。泥臭い箇所もございます。

0. 作業フローの確認

  1. 共通化を行いたいテスト内容を持つ、テストA, Bの差分を確認する。
  2. 共通部分を別の「共通テスト」とし、可能なら差分箇所を抽象化する。
  3. テストA, Bは共通テストを参照してテストを行う形に変更する。抽象化した箇所(認証情報やアドレス等)を適宜指定してテストが走るようにする。

1. テスト内容の差分確認

いきなり技術力のカケラも感じないアナログチェックです。

2つのテスト内容を見比べます。

差分のチェックにはdifff《デュフフ》を利用しました。

差分が存在しない場合は、素直にテストを DuplicateMoveしてしまえばOKだと判断できます。

テストの内容に差分が生じている(=異なるテスト項目がある)場合は、内容を吟味して共通テストが吸収したりしなかったりするだけです。何も恐れることはありません。

2. 「共通テスト」の作成

差分の確認ができたら、次は共通で利用するテストを作成します。

共通のテスト項目となる箇所を、個別のテストとして保存します。
DuplicateMoveするなりうまくやりましょう。
わかりやすく「共通テスト」などといったTest Suiteに放り込むと良いでしょう。

テストA, Bそれぞれで利用することになるため、ログイン認証など、テストごとに異なる可能性のある箇所は変数を利用して抽象化します。

参考:Creating and Using Variables – Ghost Inspector

  • テストAとテストBで、同じ名前の変数に値を入れる。
  • 共通テストでは、変数を参照するのみにする(値を入れない)。

このようにすることで、「共通したテスト項目を、複数のアカウントでテストする」といったことが簡単に実現できます。

3. 共通テストを利用したテストの実行

「共通テスト」の作成が完了したら、作成した共通テストを読み込んでテストを実行しましょう。

参考:Modularizing Tests – Reusing Test Steps – Ghost Inspector

Import steps from testすれば、他のテストからテスト項目を読み込んでテストを走らせることができます。

これにより、ログイン情報のみテストA, Bで入力(変数に値を設定)し、画面上のフォームへ値を投入する共通の処理は共通テストで一本化するといったことが可能になります。

このとき、変数に値を設定する処理をテストごとに記述してもいいのですが、Test Suite単位で使うアカウントがほぼ固定であるようなケースも多いと思います。
そういったケースでは、Suite-level Variablesを設定しましょう。より管理が簡単になります。

変数を指定して問題なく動けば作業完了です。

4. その他

テスト毎のStart URLを個別に指定するのも煩雑です。
Suite SettingsTest Defaultsから、Suite単位で共通のStart URLを設定することができます。

※各テストでStart URLを指定しなかった場合のデフォルトの値を指定するだけなので、テストによって別途Start URLを指定している場合でも問題は生じません。

Ghost Inspectorのテスト管理がぐちゃぐちゃで参った人は参考にしてみてください。

※もちろん、ログイン認証部分のテストも共通化してImport steps from testするとよりスマートなのだろうと思いますが、弊社はそこまで綺麗に整えていません……

Ubuntu 18.04 LTS Desktop 日本語Remix セットアップ

ひどい頭痛眼痛に悩まされながら泥沼セットアップを行ったので備忘録的に記事化。

やったこと

  1. UbuntuインストールDVDの作成
  2. インストールDVDからUbuntuをインストール
  3. GPUを積んだので、NVIDIAのドライバをインストール

1. インストールDVDの作成

  1. Ubuntu 18.04 LTS Desktop 日本語Remixのisoイメージダウンロード。
    ubuntu-ja-18.04.2-desktop-amd64.isoを使いました。
  2. 書き込み可能な空のDVDを用意して書き込み可能なドライブに挿入。
  3. isoイメージを右クリック→ディスクへ書き込み→挿入したDVDを選択。
  4. 書き込みが完了したら内容を確認して終了。

参考: Ubuntu 15.10 インストールDVDの作成

2. Ubuntuのインストール

沼①

  1. インストールDVDをセット。
  2. 起動時にF11を長押ししてブートメニューを開く。
    • BIOSがASRockだったため。ブートメニューがBIOS設定内に存在する種類なら、ブートの順位でディスクを入れたドライブを最優先にするだけでOK。
  3. ディスクからの起動を選択し、インストールDVDからUbuntuを起動。
  4. あとはこちらの記事を参考にポチポチとメニューを進めていく。
    Ubuntu 18.04 LTSインストールガイド【スクリーンショットつき解説】
    • このとき、USB起動かUEFIかといった選択肢が出てきたが、UEFIではないので(BIOSなので) USBを選択した。選択肢が「USB」であったのは、DVDドライブがUSB接続の外付けドライブだったことによると思われる。
    • 差分や選択肢の進み方をメモしておく。
      • モード選択
        今回はUbuntuを単体でクリーンインストールするので「Ubuntuをインストール」を選択。
      • インストールタイプ
        通常のインストール。
        アップデートをダウンロード → ✖(ネットワーク接続してなかったので)
        追加のソフトウェア類 → ✖
      • ストレージ設定
        ディスクを削除してインストール。
        インストールの暗号化 → ✖
        LVMを使用 → ✖
  5. インストールが完了するまで待ち、再起動のメニューが出たら再起動。
  6. ログイン後、初期設定
    1. 新機能はスルー。
    2. Livepatchは設定しても良かったかもしれない (特に設定しなかった)。
    3. 改善支援のデータ送信 → ✖

参考: Ubuntu 18.04 LTSインストールガイド【スクリーンショットつき解説】

3. NVIDIAのドライバダウンロード

Windowsマシンなら付属のCDを入れるだけで良さそうなのに、Ubuntuはこのあたり面倒。

※apt-getでドライバをインストールする方法(「NVIDIA apt-get」🔍)もある。今回入れるドライバは、まだダウンロード可能なドライバリストになかったので、runファイルを落としてきて入れる方針。

  1. 積んでいるGPUの種類を調べる。(購入した商品の箱とかに型番書いてあるのでそれ見てもOK)
    1. 情報更新 sudo update-pciids
    2. 情報表示 lspci | grep -i nvidia あるいは lspci | grep -i VGA
      後ろの方の[ ]で挟まれた部分が知りたい情報
  2. NVIDIAのサイトからドライバをダウンロード
    https://www.nvidia.co.jp/Download/index.aspx?lang=jp
    型番選んでダウンロードタイプを選んで検索→ダウンロード。
    ダウンロードタイプはGRDにした(SDがなかった)
  3. NVIDIA-Linux-x86_64-430.14.runというファイルがダウンロードされた。

4. NVIDIAのドライバインストール

沼②

  1. nouveauドライバの無効化
    参考: Ubuntu 18.04 LTS : NVIDIAドライバーをインストール : Server World
    1. 下記コマンドを実行。
      vi /etc/modprobe.d/blacklist-nouveau.conf
    2. 最終行に以下を追記。
      blacklist nouveau
      options nouveau modeset=0
    3. 下記コマンドを実行。
      update-initramfs -u
    4. 下記コマンドを実行(再起動)。
      reboot
  2. gccのインストール
    ※runファイルの実行時に必要だったのでインストール
    1. 下記コマンドの実行。
      sudo apt install build-essential
    2. 下記コマンドの実行(gccの動作確認)。
      gcc --version
  3. ドライバのインストール
    1. 下記コマンドの実行。
      sudo ~/Downloads/NVIDIA-Linux-x86_64-430.14.run
    2. 途中度々選択肢が出るが、基本OK連打になる。
      参考[1]: Deep Learning 用 Workstation 構築記録 その3(OS / ドライバ / CUDA&cuDNN インストール) – Qiita
      参考[2]: Ubuntu 16.04にNVIDIAドライバをインストールする方法 : 回れ右の内輪差
    3. インストールが完了し、黒いターミナルの画面に戻ったら、以下のコマンドを実行(再起動)して終了。
      sudo reboot
  4. 下記のコマンドを実行し、接続が正常に認識されているか確認する。
    nvidia-smi

以上。疲れた。

AWS フォルダの作成……?

弊社サービスでは、ユーザーのアップロードしたファイル群を Amazon S3 に保管しています。

元々は自社サーバに保存していたのですが、とある仕事でAWSに縁があり、なんやかんやあってS3使おうぜ!ということになりました。

ある日の開発者は思います。

「ファイルの保存先フォルダをユーザーごとに分けたいなぁ」

「そのためには動的にフォルダを生成する必要があるなぁ」

「あれ?いちいちS3にフォルダの存在確認したりフォルダ生成したりする必要があるんじゃ……? 」

うっわこれめんどいやつっぽいぞ

……と、既存の実装からイメージして勝手にうわぁと思っていたのですが、調べてみると、どうやらそうでもなさそうなんですよね。

S3 バケット内でフォルダを使用する方法 – Amazon Simple Storage Service

なるほどね。

つまるところ、実務上の要点は以下のようです。

  • S3はフラットな構造であり、内部的に階層はない。(=いわゆるディレクトリは実在しない)
  • 利便性のためにフォルダという概念をサポートしており、UI上ではフォルダ構造があるように見せている
  • ファイルをアップロードする際、ファイル名に区切り文字/を含ませれば、自動的に階層構造として処理される……?

3つ目。怪しいですね。確認しましょう。

例えば、アップロードする際のファイル名を、以下のように記述したとします。

'file_name' => 'user_image/' . $user_id . '/' . $file_name

このとき、file_nameuser_image/0123/hogehoge.pngのようになります。

さて、アップロードを実行してみましょう……

やったぜ

問題なくアップロードされましたね。
フォルダの階層構造も意図したとおりに表現されています。

この結果から、S3にファイルをアップロードする際、フォルダを作ってファイルを整理したい~といった場合には、特にフォルダの作成とかについて考える必要はないことがわかりました。楽ちん。

おさらい

  • S3はフラットな構造であり、内部的に階層はない。(=いわゆるディレクトリは実在しない)
  • 利便性のためにフォルダという概念をサポートしており、UI上ではフォルダ構造があるように見せている
  • ファイルをアップロードする際、ファイル名に区切り文字/を含ませれば、自動的に階層構造として処理される

参考

便利ツール紹介のコーナー #2

プライバシーポリシーとか利用規約が気になるという話は尤も。

PlayCode – Code Sandbox. Online Code Editor.

https://playcode.io/

「ブラウザ上で使えるJavaScriptの開発環境」の有名所。

ページを開いたらすぐにコードが書け、 出力結果がリアルタイムで出てくるため、ちょっとしたプログラムの動作確認などにもサクサク使える。

書いたコードは特に登録等せずとも保存が可能で、 アカウント登録をすれば、 ページを公開するといったことも可能になっている。
今の所はプログラムのちょっとした動作確認程度にしか使えていない。


PHP Sandbox, test PHP online, PHP tester

http://sandbox.onlinephpfunctions.com/

ブラウザ上でちょろっとPHPの動作確認ができる。内容を見るに、PHPの学習サイトっぽい。

PHPのバージョンが選択できるのは嬉しいポイント。
セキュアじゃないのが気になるところではある。 たまに使うことがある。


Regexper

https://regexper.com/

正規表現パターンをグラフ化してくれるサイト。
パターンを入力してワンクリックで綺麗に図示される。大変便利。
正規表現解読による頭痛とおさらばできる。彼女もできる。

図は保存ボタンが用意されているし、アドレスで共有することもできる。

すまんやっぱ彼女はできない。でも便利。正規表現と戦う機会があったら是非。


Trello

https://trello.com/ja

タスク管理に求められる機能、見やすいUI、外部ツールとの連携、快適な操作性を備えた人気のカンバン(ボード)方式タスク管理ツール。
基本的な機能はすべて無料で利用でき、個人利用なら十分なレベル。

利用例や活用方法、便利なChrome拡張機能などの情報がネット上に多数転がっており、 使用方法で困ることは少ないだろう。

外部ツールとの連携を行うことで、Slackに通知を飛ばしたり、受信したメールから即座にタスクを生成するといったことも可能になる。

強力なコラボレーション支援機能を有し、個人でのタスク管理やTo Do Listレベルの利用にとどまらず、チームのプロジェクト管理まで行えるパワーのあるツールとなっている。


Asana

https://app.asana.com/

基本無料で利用できるタスク管理ツールとして、非常に評価の高いツール。
基本的な機能は無料で利用可能。個人利用なら必要十分。

Trelloのようなカンバン(ボード)方式、To Do Listのようなタスクリスト方式の2種類の表示方法でタスクを一覧できる。
機能が豊富なだけでなく、美麗で親しみやすいUIは、こういったツール等に馴染みのない層にも使いやすい。

Trello同様、数多くの外部ツールと連携が可能であり、業務効率改善に繋がる。

元々プロジェクト管理ツールとして構築されているため、チームで利用する機能も当然作り込まれている。
個人からチームまで利用可能な、非常にパワフルなツールといえよう。


今回はここまで。