moment.jsでマシン依存しないサーバ時間を扱いたい

moment.jsを扱っていて、クライアントサイドアプリケーションでマシン依存しない時間を扱いたい場合の方法。

サーバからタイムスタンプを予め取得し、マシン時間との差分を保持しておく。 以降はその差分を計算することで正確な現在時刻を求める。

// timestampを返すAPI
axios.get('/timestamp').then(timestamp => {
    serverTimeOffset = moment(timestamp, 'X').diff(moment(), 'seconds')
})
let currentTime = moment()
currentTime.add(serverTimeOffset, 'seconds')

nodejsで簡単なAPIモックサーバを作る

フロントエンド開発をしていて、API実装前にさらっと動きを確認したいときなど、モックAPIがあると便利。

json-serverを使っていたけど、意外と細かいところに手が届かなかった*1の自分用に前でモックAPIのテンプレートを作った。

source

// api mock server
const fs = require('fs')
const https = require('https')
const express = require('express')
const bodyParser = require('body-parser')
const server = express()
const log4js = require('log4js')
const cors = require('cors')
const port = 8081

// allow cors
server.use(cors())
// logging
log4js.configure ({
  appenders: {
    access: { type: 'console' }
  },
  categories: {
    default: { appenders: ['access'], level: 'info' }
  }
})
const accessLogger = log4js.getLogger('access')
server.use(log4js.connectLogger(accessLogger))

// ssl support
const sslOptions = {
  key: fs.readFileSync('cert/server.key'),
  cert: fs.readFileSync('cert/server.crt')
}

const readJson = (filePath) => {
  return new Promise(resolve => {
    fs.readFile(filePath, (err, data) => {
      resolve(JSON.parse(data))
    })
  })
}

server.get ('/test', (req, res) => {
  readJson('db/test.json').then(data => { res.json(data) })
})

https.createServer (sslOptions, server).listen(port, () => {
  console.log('api server started on port ' + port)
})

github.com

使用しているツール

github.com github.com github.com

*1:RESTでない独自な実装してるものとか...

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でアクセスできるようになった。