error while loading shared libraries: libfontconfig.so.1

環境

CentOS release 6.5

事象

karmaでPhantomJSを起動しようとするとエラーでこけた。エラーは以下。

ERROR [launcher]: Cannot start PhantomJS
    xx/node_modules/phantomjs-prebuilt/lib/phantom/bin/phantomjs: error while loading shared libraries: libfontconfig.so.1: cannot open shared object file: No such file or directory

解決

fontconfig をインストールすることで正常に起動するようになった。

$ yum -y install fontconfig-devel
15 12 2017 15:16:49.997:INFO [launcher]: Launching browser PhantomJS with unlimited concurrency
15 12 2017 15:16:50.035:INFO [launcher]: Starting browser PhantomJS

vue-cliのwebpack productionビルド時にconsoleログ出力を削除したい

vue-cliでwebpackでproductionビルドを行う際に、以下のように

UglifyJsPluginにcompress.drop_console オプションを追加するとconsole.log, console.errorなどのconsole.xのコードを削除できる

build/webpack.prod.conf.js

    new webpack.optimize.UglifyJsPlugin({
      compress: {
        warnings: false,
        drop_console: true // added
      },
      sourceMap: true
    }),

オプション一覧はこちらを参照

https://github.com/mishoo/UglifyJS2/tree/harmony#minify-options

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
  }
}