※スマホ対応はしてません。

カテゴリー: JavaScript

“VCBuild.exe”がないと言われたけど、windows-build-toolsを入れたら解決したよ。

カテゴリー: JavaScript

正直あんまりわかってないけどまあ解決したのでメモしておく。

ざっくり

管理者権限のPowerShellで npm install --global windows-build-tools したら解決した。

  • https://www.npmjs.com/package/windows-build-tools

環境

  • node v4.5.0
  • Windows 10

なお現在node.jsの最新バージョンはv8.4です。

問題: “VCBuild.exe”がないと言われる

何かをインストールしようとしたとき、こんなエラーが出ました。

C:\Users\Ginpei\project\foo>npm install
> contextify@0.1.15 install C:\Users\Ginpei\project\foo\node_modules\jsdom\node_modules\contextify
> node-gyp rebuild


C:\Users\Ginpei\project\foo\node_modules\jsdom\node_modules\contextify>if not defined npm_config_node_gyp (node "C:\Users\Ginpei\AppData\Roaming\nvm\v4.5.0\node_modules\npm\bin\node-gyp-bin\\..\..\node_modules\node-gyp\bin\node-gyp.js" rebuild )  else (node "" rebuild )
Building the projects in this solution one at a time. To enable parallel build, please add the "/m" switch.
MSBUILD : error MSB3428: Could not load the Visual C++ component "VCBuild.exe". To fix this, 1)  install the .NET Framework 2.0 SDK, 2) install Microsoft Visual Studio 2005 or 3) add the loca tion of the component to the system path if it is installed elsewhere.  [C:\Users\Ginpei\project\foo\node_modules\jsdom\node_modules\contextify\build\binding.sln]
gyp ERR! build error
...

MSBUILD : error MSB3428: Could not load the Visual C++ component “VCBuild.exe”.

node-gypでこける。なんかFAQだった気がする。

対応

MS Visual Studioをインストールすればいいのかなーと思ったけど、windows-build-toolsなるnpmパッケージでいけるらしい。npmパッケージじゃないのもあるのかなあ。

Windows PowerShellを管理者権限で起動

管理者権限じゃないとエラー。

>npm install --global --production windows-build-tools

-
> windows-build-tools@1.3.2 postinstall C:\Program Files\nodejs\node_modules\windows-build-tools

> node ./lib/index.js

Downloading BuildTools_Full.exe
[>                                            ] 0.0% (0 B/s)
Downloading python-2.7.13.msi
[>                                            ] 0.0% (0 B/s)
Downloaded python-2.7.13.msi. Saved to C:\Users\Ginpei\.windows-build-tools\python-2.7.13.msi.
Starting installation...
Please restart this script from an administrative PowerShell!
The build tools cannot be installed without administrative rights.
To fix, right-click on PowerShell and run "as Administrator".
npm ERR! Windows_NT 10.0.15063
...

Please restart this script from an administrative PowerShell!

というわけで、言われた通りに管理者権限でPowerShellを起動。

右クリックしてRun as administrator

で、この一行です。

npm install --global --production windows-build-tools

ここでツールをビルドしてるっぽくて相当時間かかった。

10分くらいかかった。

終わったら npm install し直すと、今度は成功した。やったね。

おしまい。

アンインストール

どうもwindows-build-toolsインストール前の状態への戻し方がわからない。npmのパッケージを削除してみたが、特に問題なく npm install が成功するようになってしまった。(まあ別にいいんだけど!)

>npm uninstall --global windows-build-tools

WindowsのSystem settingsから “Add or remote program” で一覧を開いて、今日インストールされたものの中からそれっぽいものを探す。どうやら以下の三つ。

  • Python 2.x.x
  • Microsoft Visual C++ Build Tools
  • Microsoft Visual C++ 2015 Redistributable (x64)

アンインストールするコマンドっぽいものはドキュメントに書いてあるんだけど、使い方がわからない……。これ↓と同じ症状。

参考

Vue+Webpackの開発がすごい楽ちんだ。(Vue.js始めるおれおれアドベントカレンダー2016 – 17日目分)

カテゴリー: JavaScript

Vue.js始めるおれおれアドベントカレンダー2016 – 17日目分(28日公開)

これこれ。

インストール

vue-webpack-boilerplate自体は特にインストール作業はなさそうなんだけど、その前にvue-cliが必要です。

$ npm install -g vue-cli

これでコマンドラインから vue コマンドが使えるようになります。 “vue-cli” はそのコマンドをインストールする的なやつで、ブラウザが読み込む vue.js とは別物。

開始

出力結果は省略してるけど、こんな感じ。

$ vue init webpack my-project
$ cd my-project
$ yarn install

開発サーバー起動。

$ npm run dev

Listening at http://localhost:8080

URLを開くと最初のページが出てきます。やったね。

テンプレートから生成された画面。

Ctrl+C で終了。

大丈夫そうなので、今回生成されたファイルを見ていきます。

(さらに…)

propsのvalidationをさらっと書けるvue-props-templateを作りました。(Vue.js始めるおれおれアドベントカレンダー2016 – 18日目)

カテゴリー: JavaScript

Vue.js始めるおれおれアドベントカレンダー2016 – 18日目

作りましたというか、まだもうちょっといじろうと思ってるんだけど、動きはします。

ginpei/vue-props-template: Write vue’s props through template literal.

Reactもそうなんだけど、オブジェクトを入れ子にしてく書き方、なかなか面倒じゃないですか。そういうのをなんかこう装飾子みたいにさらってできねえかなーそういやテンプレート文字列は改行も含められるんだなーあれでやれたらいいなーと考えて作ってみました。

propsの検証

Vueの機能として、型等を指定することができます。

こんな感じ。

const MyComponent = {
  props: {
    simpleString: { type: String },
    requiredNumber: { type: Number, required: true },
    defaultBoolean: { type: Boolean, default: true },
    validatedObject: {
      validator: function (value) {
        return (value.flag1 && value.flag2)
      }
    }
  }
}

vue-props-template

さっきの指定を、だいたいこう書けるようになります。

const pt = require('vue-props-template')

const MyComponent = {
  props: pt`
    string simpleString
    required number requiredNumber
    boolean defaultBoolean = true
  `
}

どうでしょうか、こういうの。

あとは validatedObject をどうしようかなあというところです。現状こんなん。

const pt = require('vue-props-template')

const MyComponent = {
  props: pt.extend(pt`
    object validatedObject
    `, {
      validatedObject: {
        validator: function (value) {
          return (value.flag1 && value.flag2)
        }
      }
    }
  }
}

よくわからないこと

便利?

個人的にはあんな風に書けたら便利だと思ってるんだけど、他の人はどうなんだろ。まあ自分で使う用でも構わないんだけど。

既存でこういうのないか?

ちょっと探して見つからなかったけどありそうで怖い。

validator の扱い

埋め込み値 ${…} の中に関数を書くのってどうかなあ。別に良いかなあ。例えばこういうの。

props: pt`
  validatedObject as ${function (value) {
    return (value.flag1 && value.flag2)
  }}
`

あーこういうのも悪くないかなあ。どうかなあ。

この場合、他の「型 名前」の順の書き方と違ってきちゃうけど、んーまあ良いか。

最近のライブラリの作り方

Vue本体を参考に、ブラウザで読み込んでもNode.js(vueify)経由でも動くようにはした。でも今はそれを直接元コードに書いてて、なんかこう「ビルド」をしてそういうのを出力するやり方の方が良いだろうか。

あとバージョン管理も実はあんまりよくわかってない。semverは良いんだけど、なんか手動でぽちぽちやるんじゃなくてnpm scriptに更新コマンドも用意して、なんて話を前聞いた気がする。

他にやること

これ全部終わったらv1.0.0ということにしようかなと思ってます。

  • validator の扱い
  • バベる
  • ドキュメントの見直し
  • GitHub pagesの充実
  • npm登録

そうか、要素に触るなら$refsとmountedを組み合わせれば良いのか。(Vue.js始めるおれおれアドベントカレンダー2016 – 16日目分)

カテゴリー: JavaScript

Vue.js始めるおれおれアドベントカレンダー2016 – 16日目分(24日公開)

しゅんしゅん動くよ。

アニメーション付きのナビバーを作ってみました、簡単でした。やったね。

基本的な作り方

  • location.hash を監視して情報更新
  • hashに該当する内容を表示
  • バー位置をhashの候補の順序から算出

簡単に作れたは良いんだけど、最後のやつどうしようかなと。

バー位置をhashの候補の順序から算出

最初に書いたコードはこう。

<nav>
  <a href="#">Home</a>
  <a href="#about">About</a>
  <a href="#contact">Contact</a>
  <span :style="underlineStyle"></span>
</nav>
const store = require('./store.js')

const hashes = ['', '#about', '#contact']

module.exports = {
  data () {
    return store.state
  },
  computed: {
    underlineStyle () {
      const itemWidth = 100
      const left = itemWidth * hashes.indexOf(this.hash)
      return {
        transform: 'translateX(' + left + 'px)'
      }
    }
  }
}

これで全然動くんだけど、疑問点が二つ。

  • 候補値 '', '#about', '#contact' をHTML側と共有しているの、どうにかならんかな
  • 項目の幅 100 をCSS側と共有しているの、どうにかならんかな

jQueryであれば実際の要素を見てあれこれするんだけど、Vueはそうはしないじゃないすか。普通。

$refs を使う?

とか言いつつ要素を見てあれこれするやつ、使ったらできるにはできた。

<nav ref="list">
  <a href="#">Home</a>
  <a href="#about">About</a>
  <a href="#contact">Contact</a>
  <span :style="underlineStyle"></span>
</nav>
computed: {
  /**
   * 項目の幅の実測値を返す。
   */
  itemWidth () {
    const elList = this.$refs.list
    const elItem = elList.firstElementChild
    return elItem.clientWidth
  },

  /**
   * 項目の `href` からhash候補値を得る。
   */
  hashes () {
    const elList = this.$refs.list
    const elItems = elList.children
    const hashes = Array.from(elItems).map(elItem => {
      let hash = elItem.getAttribute('href')
      if (hash === '#') {
        hash = ''
      }
      return hash
    })
    return hashes
  },

  underlineStyle () {
    let left

    // 最初のDOM構築の際には当然underlineStyleは呼ばれるが、
    // 最初だからDOMがまだないので、 `$refs` が使えない。
    if (this.$refs.list) {
      left = this.itemWidth * this.hashes.indexOf(this.hash)
    } else {
      // `hash` 変更時にキャッシュ値を更新するよう、
      // ここで呼んで記憶してもらう
      left = this.hash.length * 0
    }

    return {
      transform: 'translateX(' + left + 'px)'
    }
  }
},

うわあ、すごく危険な香りがする。

実際公式ガイドにもやめてねって書いてあるし。

$refs はコンポーネントが描画された後にのみ追加されます。そしてそれはリアクティブではありません。直接子コンポーネントを操作するための最終手段としての意味しかありません。テンプレートまたは算出プロパティの中での $refs の使用は避けるべきです。

うん。

テンプレートまたは算出プロパティの中での $refs の使用は避けるべきです。

そう思います。

マウントのタイミングで確認したい……

……マウント……ライフサイクル……ん?

module.exports = {
  data () {
    return {
      itemWidth: 999,
      hashes: [],
      state: store.state
    }
  },
  mounted () {
    const elList = this.$refs.list
    const elItems = elList.children

    this.itemWidth = elItems[0].clientWidth

    this.hashes = Array.from(elItems).map(elItem => {
      let hash = elItem.getAttribute('href')
      if (hash === '#') {
        hash = ''
      }
      return hash
    })
  },
  computed: {
    underlineStyle () {
      const left = this.itemWidth * this.hashes.indexOf(this.state.hash)
      return {
        transform: 'translateX(' + left + 'px)'
      }
    }
  }
}

なるほど、こういう感じか。これなら良さそう。

バンクーバーの電車遅延情報をSlackで流すよ。(Frog Advent Calendar 2016 – 16日目)

カテゴリー: JavaScript

Frog Advent Calendar 2016 – 16日目

カナダの西海岸に位置する、海も山も和食もある街バンクーバーのFrog Houseからお届けします。

技術の話ですが、せっかくなのでバンクーバーの紹介もさせて頂こうかと思います。

概要

  • シェアハウス内はSlackで連絡を取っている
  • バンクーバーの電車遅延はウェブページで公開されている
  • ページをスクレイピング、加工して情報取得
  • Slack botで定期的に情報を取得、問題があれば通知する

こんな感じ。チュートリアルではないのであんまり細かい手順やコードは載せてません、各種公式ドキュメントや実装コードをご確認願います。

遅延と回復を検知して通知。

フロッグハウス

Frog Houseというシェアハウスがバンクーバーにございまして、私ギンペイは現在そこに在住しております。住人は七名、うち私を含む五名がウェブ制作方面の人間です。

Slack

かつてはFacebookメッセージで家の中の連絡をしていたんですが、なかなか煩雑なのと検索性能が低いことから、Slackを導入しました。今のところうまく回っているようです。Slackはいいぞ。

最近二軒目Frog House 2ndも統合して、別チャンネル同チームで運用しております。なんか家賃とかそういうアレの管理をまとめてしたかったんですって。

現在チームには20のチャンネルが作成されていまして、全体用 #general と一軒目用 #general-1 みたいに分けて運用してます。まあ各自で適当に作ったりしてもらえれば良いかと。

先に申し上げた通りウェブ系の人が多いので、 #webdev チャンネルを設けて情報共有したりもしてます。たのしい。

とまあそんな感じで、日常生活にSlackを組み込んだ感じですね。

バンクーバーの交通事情

割と北米は車文化が根強い感じはあるんですが、バンクーバーでは “SkyTrain” という呼称で電車が走ってます。バンクーバーのダウンタウン(中心街)を軸に三本の路線が稼働中です。

ちなみに電車、無人運転です

東京のゆりかもめ線みたいな感じ。すげーぞカナダ人。

車両の先頭はこんな景色。あ、わかりづらいこれ……

あと改札も無人。前は性善説もとい諸事情により扉もなく開放されていたんですが、最近はSuicaみたいな “Compass” というカードが導入されまして、通るたびにピッピッとやります。オートチャージはなくて、駅に設置の機械でチャージしてやります。

(さらに…)