error: [vuex] vuex requires a promise polyfill in this browser

現象

Vuexで構築したアプリケーションをIE11で動かすとエラーになった。

error:  [vuex] vuex requires a promise polyfill in this browser

promise がIEだと使えないようだ。

解決

babel-polyfill を入れる

babeljs.io

npm install --save-dev babel-polyfill

Vuexのbuild設定を変更

build/webpack.base.conf.js

module.exports = {
  entry: {
+    app: ['babel-polyfill', './src/js/app.ts']
-    app: './src/js/app.ts'
 },

it works!

stylefmtでcssプロパティをアルファベット順に並び替える方法

stylelint-order プラグインとしてインストールすることで可能。

stylelint-order をインストール

$ npm install stylelint-order --save-de

.stylelintrc.json に以下のようにplugins と rules を追加する

{
  "plugins": [
    "stylelint-order"
  ],
  "rules": {
    "order/properties-alphabetical-order": true
  }
}

これでアルファベット順になってすっきりした。

WebRTC(SkyWay)でコネクションを成立後にローカルビデオのon/offを動的に切り替えたい

やりたいこと

WebRTCでコネクションを作ったあとに、自分のビデオ、マイク音声on/offをシームレスに切り替えるようにしたい。

Skypeとかにあるビデオ、音声ミュート機能と同じやつ。 例えば、今ちょっと自分の画面を相手に見せたくないよ、でもコネクションは切りたくないよ、なんていうときに使われるであろう機能。

やり方

最初は、getUserMediaで新しいconstraintsをセットして、streamをreplaceしてやれば良いかな?と思ったけど、 getUserMediaの仕様上、constraintsのvideo, audioのいずれか一方は必須パラメータのため、両方OFFにするケースに対応できず諦めた。(それにちょっとこのやり方はよくない)

調べていると良い方法が見つかったので以下に記載する。

普通にgetUserMediaでローカルストリームを取得する

// get local stream
navigator.mediaDevices
  .getUserMedia(constraints)
    .then(stream => {
      localStream = stream
    })
    .catch(error => {
      // error handling
    })

ビデオ、音声は、取得したローカルストリームのgetVideo/AudioTracks()[0].enabled パラメータにtrue/falseをセットすることで動的にon/offを切り替えられる。 適当に以下のようなfunctionでそれぞれスイッチできた。

const updateVideoEnabled = (enabled) => {
  if (localStream) {
    localStream.getVideoTracks()[0].enabled = enabled
  }
}
const updateAudioEnabled = (enabled) => {
  if (localStream) {
    localStream.getAudioTracks()[0].enabled = enabled
  }
}

都内から格安で富士急ハイランドへ行く

先日初めて富士急ハイランドに行ってきた。

得Qパックという、高速バス往復+フリーパスのチケットが安かった。

bus.fujikyu.co.jp

渋谷から往復して7900円(渋谷以外にも乗り場はある)。フリーパスは正規の値段だと、それだけで5700円なのでかなりお得だ。

都内から意外と近くて、高速バス2時間程で到着。

ええじゃないかに乗って、怖すぎて本当に死ぬかと思った。。

vue-cliの開発サーバをhttps化する

vue-cliを使って開発をしていて、開発サーバをhttps化する必要がでてきたため、vue-cliに組み込まれているdev-serverをhttps化することにした。

ソースを見るとなんてことはない、nodejsのexpressを使ってサーバを起動しているだけなので、expressのhttps化と同じやり方でいけた。

オレオレ証明書を生成する

開発サーバ用のオレオレ証明書なので、build/cert に置くことにする。

$ cd build
$ mkdir cert && cd cert
$ openssl genrsa 2048 > server.key
$ openssl req -new -key server.key -out server.csr
$ openssl x509 -req -sha256 -days 365 -in server.csr -signkey server.key -out server.crt
$ ls
server.crt  server.csr  server.key

dev-serverの設定を変更する

+var https = require('https')
+var fs = require('fs')

-var uri = 'http://localhost:' + port
+var uri = 'https://localhost:' + port

-var server = app.listen(port)
+const sslOptions = {
+  key: fs.readFileSync('build/cert/server.key'),
+  cert: fs.readFileSync('build/cert/server.crt')
+};
+var server = https.createServer(sslOptions, app).listen(port);

開発サーバを立ち上げる

$ npm run dev
 DONE  Compiled successfully in 13751ms

> Listening at https://localhost:8080

これで、httpsでアクセスできるようになった。

Vagrantを再起動したら既存のVMが消えた

現象

Mac上で起動しているVagrantVM内で作業していたところ、バッテリー切れでMacが強制シャットダウンした。 その後、起動して、 Vagrant up でVagrant を起動したところ、作業していたVMではなく、新規VMが立ち上がるようになってしまった。

作業途中のファイルが失われてしまい、とても困った。

復旧する

この方法で以前のVMを起動することができた。

elm-arata.hatenablog.com

VirutalBoxのコマンドラインインターフェース VBoxManage を使って仮想マシンの情報を表示する。

$ VBoxManage list vms
"aaa_1491870543558_52578" {945beac3-3920-4eec-947e-bfce8e017aaa}
"bbb_1493466062889_97138" {462256fa-197f-477d-b1ff-7cc74e401bbb}
"ccc_1505786401940_15041" {9c2a6b5c-7cce-46e3-b60a-76e3e1324ccc}

作成した日時の昇順に表示されるので、一番下が直近に作成したVM。 一番下は、新規作成されたVMなので、1つ前の、bbb_1493… のVMを起動するように設定し直す。

以下のファイルを開き、VMのUID()を置き換える。

$ vi .vagrant/machines/default/virtualbox/id
462256fa-197f-477d-b1ff-7cc74e401bbb

VMを再起動

$ vagrant reload

復旧できた。やったぜ。

vue-cliで作成したアプリケーションをサブディレクトリ上に展開する

vue-cli

github.com

やりたいこと

vue-cliで作成したアプリケーションをサブディレクトリ /test-dir/ に展開したい。

問題

デフォルトの設定でプロダクションビルドし、

$ npm run build

webサーバから {vue-cli-project}/dist/ を参照するようにしたが、このままではパスの問題でアプリケーションが動かなかった。

解決

config/index.js に assetsPublicPath という設定項目がある。この値をvue-cliアプリケーションのルートとなるサブディレクトリパスに書き換えて、 再度ビルドすれば良い。

assetsPublicPath: '/test-dir/',

さらに、vue-router を使ってルーティング設定を行っている場合は、そちらにも設定が必要となる。 コンストラクタオプションの'base' に、サブディレクトリの設定を行う。

ルーターコンストラクタオプション · vue-router

new Router({
  base: '/test-dir/',
  ...
})