<?xml version="1.0" encoding="utf-8" ?>
<rss version="2.0"
xmlns:dc="http://purl.org/dc/elements/1.1/"
xmlns:content="http://purl.org/rss/1.0/modules/content/"
xml:lang="ja">
<channel>
<title>ウォンビン ビール瓶。</title>
<link>http://d.hatena.ne.jp/teppeis/</link>
<description>ウォンビン ビール瓶。</description>
<dc:creator>teppeis</dc:creator>


<item>
<title>[javascript][node.js][testing]Stylus/mochaがやってるGlobal leakテストとNode.js Debugger</title>
<link>http://d.hatena.ne.jp/teppeis/20120115/1326610019</link>

<description><![CDATA[
<div class="section">
<p>先日、<a href="https://github.com/LearnBoost/stylus" target="_blank">Stylus</a>のコードをいじってたらグローバルリークがあったので、修正して<a href="https://github.com/LearnBoost/stylus/pull/506" target="_blank">Pullリクエスト</a>しました。（TJが即マージして<a href="https://github.com/LearnBoost/stylus/commit/5622d3c77eff204242dbff816c92f2f5b00eb836" target="_blank">リリース済み</a>だよ！）</p>
<p>リークを見つけたのは、StylusのテストコードにGlobalオブジェクト汚染を検出するテストがあってそれをたまたま走らせただけなのですが、このテストがシンプルかつ効果的でいいなと思いました。</p>
<p><a href="https://github.com/LearnBoost/stylus/blob/master/test/run.js" target="_blank">https://github.com/LearnBoost/stylus/blob/master/test/run.js</a></p>
<pre class="syntax-highlight">
<span class="synComment">// Testの初期化時にデフォルトのグローバルオブジェクトのキーを保存。</span>
<span class="synIdentifier">var</span> globals = <span class="synType">Object</span>.keys(global);
...

<span class="synComment">// Testが終わったらグローバルオブジェクトの差分をチェック</span>
<span class="synIdentifier">function</span> done() <span class="synIdentifier">{</span>
  <span class="synType">Object</span>.keys(global).forEach(<span class="synIdentifier">function</span>(name)<span class="synIdentifier">{</span>
    <span class="synStatement">if</span> (!~globals.indexOf(name)) <span class="synIdentifier">{</span>
      console.error(<span class="synConstant">'  </span><span class="synSpecial">\033</span><span class="synConstant">[31mglobal leak:</span><span class="synSpecial">\033</span><span class="synConstant">[0m %s'</span>, name);
      ++failures;
    <span class="synIdentifier">}</span>
  <span class="synIdentifier">}</span>);
  ...
</pre>

<p><a href="http://f.hatena.ne.jp/teppeis/20120115151838" class="hatena-fotolife" target="_blank"><img src="http://cdn-ak.f.st-hatena.com/images/fotolife/t/teppeis/20120115/20120115151838.png" alt="f:id:teppeis:20120115151838p:image" title="f:id:teppeis:20120115151838p:image" class="hatena-fotolife"></a></p>
<p>JavaScriptってvarとかnewとか忘れただけでグローバルリークしちゃうので（CoffeeScriptなら以下略）、これテストフレームワークに入れて全メソッドでチェックしたらいんじゃない？と思って、Stylusの作者TJが作ってるテストフレームワーク<a href="http://visionmedia.github.com/mocha/" target="_blank">mocha</a>を見てみたら、やっぱりGlobal leakをチェックする機能が入ってました。デフォルトでチェックしてくれるみたいです（"―ignore-leaks"で抑制可能）。</p>
<p>使っているテストフレームワークにこの機能がなくても、単純なテストなので、setup()やteardown()に仕込んどくのがいいんじゃないでしょうか。</p>
<br>

<p>ちなみに、グローバルリークってだいたいnewかvarの付け忘れだと思うんですが、今回の"lineno"プロパティはいろんなクラスに継承されるNodeというベースクラスのコンストラクタでセットされるプロパティなので、newが漏れてる箇所を単純なgrepでは見つけにくいところでした。なので、</p>
<pre class="syntax-highlight">
<span class="synIdentifier">var</span> Node = module.exports = <span class="synIdentifier">function</span> Node()<span class="synIdentifier">{</span>
  <span class="synStatement">if</span> (<span class="synIdentifier">this</span> === global) <span class="synStatement">debugger</span>; <span class="synComment">// newを忘れてたらここでbreakされる</span>
  <span class="synIdentifier">this</span>.lineno = nodes.lineno;
  <span class="synType">Object</span>.defineProperty(<span class="synIdentifier">this</span>, <span class="synConstant">'filename'</span>, <span class="synIdentifier">{</span> writable: <span class="synConstant">true</span>, value: nodes.filename <span class="synIdentifier">}</span>);
<span class="synIdentifier">}</span>;
</pre>

<p>みたいに条件付きdebuggerを仕込んでテストをdebugで動かしたら一発で見つかりました。</p>
<pre class="syntax-highlight">
$ node debug test/run.js
&#60; debugger listening on port 5858
connecting... ok
debug&#62; c

&#60;     arithmetic.color
&#60;   &#10004; arithmetic.color
&#60;     arithmetic
&#60;   &#10004; arithmetic
&#60;     arithmetic.unary
break in lib/nodes/node.js:23
 21 
 22 var Node = module.exports = function Node(){
 23   if (this === global) debugger;
 24   this.lineno = nodes.lineno;
 25   Object.defineProperty(this, &#39;filename&#39;, { writable: true, value: nodes.filename });
debug&#62; bt
#0 node.js:23:23
#1 boolean.js:23:8
#2 Boolean.negate boolean.js:78:10
#3 Evaluator.visitUnaryOp evaluator.js:428:31
#4 Visitor.visit index.js:28:39
#5 Evaluator.visit evaluator.js:74:18
#6 Evaluator.visitExpression evaluator.js:451:26
#7 Visitor.visit index.js:28:39
#8 Evaluator.visit evaluator.js:74:18
#9 Evaluator.visitProperty evaluator.js:489:22
debug&#62; o
break in lib/nodes/boolean.js:24
 22 var Boolean = module.exports = function Boolean(val){
 23   Node.call(this);
 24   if (this.nodeName) {
 25     this.val = !!val;
 26   } else {
debug&#62; o
break in lib/nodes/boolean.js:79
  77 Boolean.prototype.negate = function(){
  78   return Boolean(!this.val);   // newが抜けてる！！！
  79 };
  80 
  81 /**
debug&#62; 
</pre>

<p>gdbライクなNode.jsの<a href="http://nodejs.org/docs/latest/api/debugger.html" target="_blank">Debugger</a>、覚えてるとちょっとしたときに便利ですね。</p>
</div>
]]></description>

<dc:creator>teppeis</dc:creator>

<pubDate>Sun, 15 Jan 2012 06:46:59 GMT</pubDate>



<category>javascript</category>

<category>node.js</category>

<category>testing</category>


</item>

<item>
<title>[node.js][mac]Mac OS X &amp; Homebrewでcairoのインストール</title>
<link>http://d.hatena.ne.jp/teppeis/20120103/1325598908</link>

<description><![CDATA[
<div class="section">
<p><a href="https://github.com/LearnBoost/node-canvas" target="_blank">node-canvas</a>をインストールするために、依存する<a href="http://www.cairographics.org/" target="_blank">cairo</a>をbrewで入れようとしたらなんかエラー。</p>
<pre class="syntax-highlight">
$ brew install cairo
...
ld: lto: could not merge in .libs/cairo-analysis-surface.o because Unknown instruction for architecture x86_64
collect2: ld returned 1 exit status
make[3]: *** [libcairo.la] Error 1
make[2]: *** [install] Error 2
make[1]: *** [install-recursive] Error 1
make: *** [install] Error 2
==&#62; Exit Status: 2
http://github.com/mxcl/homebrew/blob/master/Library/Formula/cairo.rb#L20
==&#62; Environment
HOMEBREW_VERSION: 0.8
HEAD: 2cd086421ee5b01e3684a938795d4d8c12979db7
HOMEBREW_PREFIX: /usr/local
HOMEBREW_CELLAR: /usr/local/Cellar
HOMEBREW_REPOSITORY: /usr/local
HOMEBREW_LIBRARY_PATH: /usr/local/Library/Homebrew
Hardware: quad-core 64-bit sandybridge
OS X: 10.7.2
Kernel Architecture: x86_64
Ruby: 1.8.7-249
/usr/bin/ruby =&#62; /System/Library/Frameworks/Ruby.framework/Versions/1.8/usr/bin/ruby
Xcode: 4.2.1
GCC-4.0: build 5494
GCC-4.2: build 5666
LLVM: build 2336
Clang: 3.0-211.1
MacPorts or Fink? false
X11 installed? true
==&#62; Build Flags
CC: /usr/bin/llvm-gcc =&#62; /usr/llvm-gcc-4.2/bin/llvm-gcc-4.2
CXX: /usr/bin/llvm-g++ =&#62; /usr/llvm-gcc-4.2/bin/llvm-g++-4.2
LD: /usr/bin/llvm-gcc =&#62; /usr/llvm-gcc-4.2/bin/llvm-gcc-4.2
CFLAGS: -O3 -march=core2 -w -pipe
CXXFLAGS: -O3 -march=core2 -w -pipe
MAKEFLAGS: -j4

Error: Failed executing: make install 
These existing issues may help you:
    https://github.com/mxcl/homebrew/issues/7658
    https://github.com/mxcl/homebrew/issues/8144
    https://github.com/mxcl/homebrew/issues/9180
Otherwise, please report the bug:
    https://github.com/mxcl/homebrew/wiki/checklist-before-filing-a-new-issue
</pre>

<p>提示されたURLはどうも的外れっぽい。</p>
<p>なんかLLVMが怪しいので、gccでコンパイルしたらあっさり通りました。</p>
<pre class="syntax-highlight">
$ brew install cairo --use-gcc
</pre>

<p>もう、ソースからビルドしろよって感じですね。</p>
<p><a href="https://github.com/LearnBoost/node-canvas/wiki/Installation---OSX" target="_blank">node-canvasのビルドマニュアル</a>が超親切です。</p>
</div>
]]></description>

<dc:creator>teppeis</dc:creator>

<pubDate>Tue, 03 Jan 2012 13:55:08 GMT</pubDate>



<category>node.js</category>

<category>mac</category>


</item>

<item>
<title>[css][sass]Sass&amp;CompassでPath風のメニューを作ってみた</title>
<link>http://d.hatena.ne.jp/teppeis/20111228/1325029083</link>

<description><![CDATA[
<div class="section">
<p>みんな気になってしょうがないPathのアレを、Sass, Compass, CSS3 Animationsのお勉強をかねて作ってみました。Chrome, Safari, Firefox, IE10で動きます。</p>
<p><a href="http://f.hatena.ne.jp/teppeis/20111228052929" class="hatena-fotolife" target="_blank"><img src="http://cdn-ak.f.st-hatena.com/images/fotolife/t/teppeis/20111228/20111228052929.png" alt="f:id:teppeis:20111228052929p:image" title="f:id:teppeis:20111228052929p:image" class="hatena-fotolife"></a></p>

<ul>
<li> Demo: <a href="http://teppeis.github.com/menu-like-path/" target="_blank">http://teppeis.github.com/menu-like-path/</a></li>
<li> Source: <a href="https://github.com/teppeis/menu-like-path" target="_blank">https://github.com/teppeis/menu-like-path</a></li>
</ul>
<p>「CSSでPath風メニュー」っていうのは国内外ですでにたくさんあるので、気になったところなどSass&Compass寄りでいくつか書きます。</p>
<h4>SCSSの記述量はCSSの約5分の1</h4>
<p>今回作ったもので、SCSSで約300行（後述の自作ライブラリ含む）、コンパイル後はCSSで約1550行になりました。</p>
<p>大きいのは、繰り返しで@forループできたところと、ベンダープレフィックスですね。border-radiusやanimation, box-shadowなどを多用する場合はこのぐらいに成ると思います。Sass形式で書くとブレースがない分、まだ若干減りますね。</p>
<h4>transition-propertyでtransformを指定する方法</h4>
<p>前述のとおり、Compassの最大の利点はベンダープレフィックスをよろしく付けてくれるmixinが用意されてることです。SCSSをこう書くと、</p>
<pre class="syntax-highlight">
<span class="synComment">/* SCSS */</span>
@include border-radius(50%);
</pre>

<p>コンパイル後にこうなります。</p>
<pre class="syntax-highlight">
<span class="synComment">/* CSS */</span>
-moz-border-radius: 50%; 
-webkit-border-radius: 50%; 
-o-border-radius: 50%; 
-ms-border-radius: 50%; 
-khtml-border-radius: 50%; 
border-radius: 50%; 
</pre>

<p>ところが、transition-propertyのように値に対象のプロパティ名を指定するケースでは、値の方にベンダープレフィックスをつけてくれません。これが、</p>
<pre class="syntax-highlight">
<span class="synComment">/* SCSS */</span>
@include transition-property(transform);
</pre>

<p>こうなってしまいます。</p>
<pre class="syntax-highlight">
<span class="synComment">/* CSS */</span>
-moz-transition-property: transform;
-webkit-transition-property: transform;
-o-transition-property: transform;
transition-property: transform;
</pre>

<p>本当はこうなってほしいのです。</p>
<pre class="syntax-highlight">
<span class="synComment">/* CSS */</span>
-moz-transition-property: -moz-transform;
-webkit-transition-property: -webkit-transform;
-o-transition-property: -o-transform;
transition-property: transform;
</pre>

<p>なので、プロパティ名と値の両方にプレフィックスを付けるmixinを作ってtransition-propertyに使ってみました。</p>

<ul>
<li> <a href="https://github.com/teppeis/menu-like-path/blob/master/sass/_shared.scss" target="_blank">https://github.com/teppeis/menu-like-path/blob/master/sass/_shared.scss</a></li>
<li> <a href="https://github.com/teppeis/menu-like-path/blob/master/sass/_transition.scss" target="_blank">https://github.com/teppeis/menu-like-path/blob/master/sass/_transition.scss</a></li>
</ul>
<p>transitionとtransformでベンダープレフィックスサポートが異なる場合もあるので、実はあんまりいけてないmixinですけど。。</p>
<h4>Compassのベンダープレフィックスサポートはわりとテキトー？</h4>
<p>IE10からCSS3 Transitionに対応していますが、上の出力例で分かるようにCompassはtransition-propertyに-msを出力しません。IE10でもTransitionしたいのに！一方、<a href="https://github.com/chriseppstein/compass/pull/405" target="_blank">CSS3 Flexible Layout</a>関連には-msが出力されます。<a href="https://github.com/chriseppstein/compass/issues/590" target="_blank">Issuesの議論</a>を見ると、入れるかどうかの判断基準は割とゆるそうです。</p>
<h4> 座標計算をするにはCompassがほぼ必須</h4>
<p>Pathのメニューは円形なので、座標計算のためにはsin(), cos(), piなどが必要になります。そういうのがSassには用意されてるものだと思ったのですが、Sassの組み込み数値計算関数は四則演算と丸め関数ぐらいしかありません。</p>

<ul>
<li> <a href="http://sass-lang.com/docs/yardoc/Sass/Script/Functions.html" target="_blank">Module: Sass::Script::Functions</a></li>
</ul>
<p>そこでCompassのリファレンスを見てみるとsin, cos含めていくつかのヘルパー関数が用意されていました。</p>

<ul>
<li> <a href="http://compass-style.org/reference/compass/helpers/" target="_blank">Compass Helpers | Compass Documentation</a></li>
</ul>
<p>Compassって、-moz-transitionみたいなベンダープレフィックスの便利帳みたいな印象だったのですが、こういう組み込み関数も充実してるんですね。もうSassはCompassとワンセットだと思った方が良さそうです。</p>
<h4>@keyframesが鬼門すぎる</h4>
<p>CSS3 AnimationsをSass&Compassでうまいことクロスブラウザ対応するのは非常に苦労しました。結論としては以下の2つでなんとかなりました。</p>

<ul>
<li> Sass-3.2.0（alpha版）から導入される@contentを使う</li>
<li> SCSS形式をあきらめて一部をSass形式にする (Partial Sass)</li>
</ul>
<h5>やりたいこと</h5>
<p>CSS3 Animationsの基本構文は以下のようになります。</p>
<pre class="syntax-highlight">
<span class="synComment">/* CSS */</span>
@-webkit-keyframes anim-1 <span class="synIdentifier">{</span>
  <span class="synConstant">0%</span> {
    <span class="synType">width</span>: <span class="synConstant">0px</span>;
  <span class="synIdentifier">}</span>
  100% <span class="synIdentifier">{</span>
    <span class="synType">width</span>: <span class="synConstant">100px</span>;
  <span class="synIdentifier">}</span>
<span class="synError">}</span>
<span class="synSpecial">.</span>hoge <span class="synIdentifier">{</span>
  -webkit-animation-name: anim<span class="synConstant">-1</span>;
  -webkit-animation-duration: <span class="synConstant">1s</span>;
<span class="synIdentifier">}</span>
</pre>

<p>やりたいことは2点</p>

<ol>
<li> @keyframesのベンダープレフィックスを自動生成したい</li>
<li> 複数要素に対してを繰り返しで@keyframesを生成したい（メニューの周りのちっちゃい丸用）</li>
</ol>
<h5>@keyframesのベンダープレフィックスを自動生成したい</h5>
<p>これはmixinとかいろいろ試したのですが、根本的に@keyframesがCSSとしては例外的にネストしている構文なせいで、コンパイルエラーになるか、コンパイル後におかしなCSSになってしまってだめでした。</p>
<p>で、SassのIssuesを漁っていると、<a href="https://github.com/nex3/sass/pull/167" target="_blank">@contentというのが次期バージョンから追加される</a>ことが分かりました。これは、mixinを呼び出した側のブロックの中身を呼び出されたmixin側が@contentで参照できるもの。まさに@keyframesや@media用に作られたっぽいです。こんな感じ。</p>
<pre class="syntax-highlight">
<span class="synComment">/* SCSS */</span>
@mixin keyframes <span class="synIdentifier">{</span>
  @-moz-keyframes anim<span class="synConstant">-1</span> {
    @<span class="synType">content</span>
  <span class="synIdentifier">}</span>
  @-webkit-keyframes anim-1 <span class="synIdentifier">{</span>
    @<span class="synType">content</span>
  <span class="synIdentifier">}</span>
  @-ms-keyframes anim-1 <span class="synIdentifier">{</span>
    @<span class="synType">content</span>
  <span class="synIdentifier">}</span>
  @keyframes anim-1 <span class="synIdentifier">{</span>
    @<span class="synType">content</span>
  <span class="synIdentifier">}</span>
<span class="synError">}</span>
<span class="synComment">/* 使い方。この中身が全ての@contentに代入される。 */</span>
@include keyframes <span class="synIdentifier">{</span>
  <span class="synConstant">0%</span> {
    <span class="synType">width</span>: <span class="synConstant">0px</span>;
  <span class="synIdentifier">}</span>
  100% <span class="synIdentifier">{</span>
    <span class="synType">width</span>: <span class="synConstant">100px</span>;
  <span class="synIdentifier">}</span>
<span class="synError">}</span>
</pre>

<p>開発版のSassのGemはこんな感じでインストールできます。（rvmを使うと複数のGemのバージョンを管理できるのでオススメです）</p>
<pre class="syntax-highlight">
$ gem install sass -v 3.2.0.alpha.35
</pre>

<h5>複数要素に対してを繰り返しで@keyframesを生成したい</h5>
<p>ほんとはこんな感じで複数の要素に異なるkeyframesを割り当てたいのです。</p>
<pre class="syntax-highlight">
<span class="synComment">/* SCSS */</span>
@mixin keyframes($name) <span class="synIdentifier">{</span>
  @-moz-keyframes #{$name<span class="synIdentifier">}</span> <span class="synIdentifier">{</span>  <span class="synComment">/* ここでコンパイルエラー！ */</span>
    @<span class="synType">content</span>
  <span class="synIdentifier">}</span>
  <span class="synSpecial">...</span>
  @keyframes #<span class="synIdentifier">{</span>$name<span class="synIdentifier">}</span> <span class="synIdentifier">{</span>
    @<span class="synType">content</span>
  <span class="synIdentifier">}</span>
<span class="synError">}</span>
<span class="synComment">/* 3つの要素に繰り返しkeyframesを生成して設定 */</span>
@for $<span class="synStatement">i</span> from 1 through 3 <span class="synIdentifier">{</span>
  @include keyframes(anim-#{$i<span class="synIdentifier">}</span>) <span class="synIdentifier">{</span>
    <span class="synConstant">0%</span> {
      <span class="synType">width</span>: <span class="synConstant">0px</span>;
    <span class="synIdentifier">}</span>
    100% <span class="synIdentifier">{</span>
      <span class="synType">width</span>: <span class="synConstant">10px</span> * $i;
    <span class="synIdentifier">}</span>
  <span class="synError">}</span>
  <span class="synStatement">li</span>:nth-of-type(#{$i}) <span class="synIdentifier">{</span>
    @include animation-name: anim-#{$i<span class="synIdentifier">}</span>;
  <span class="synError">}</span>
<span class="synError">}</span>
</pre>

<p>ところが、keyframesの$nameを設定するところでコンパイルエラーになってしまいます。</p>
<pre>
Line 1: Invalid CSS after &#34;($name) &#34;: expected expression (e.g. 1px, bold), was &#34;{&#34;
</pre>

<p><a href="https://github.com/nex3/sass/issues/207" target="_blank">https://github.com/nex3/sass/issues/207</a> に書いてあるように'#{$name}'のように引用符で囲むとコンパイルは通りますが、CSSとしては引用符で囲むのはInvalidなので、Firefoxでは動きません。。</p>
<p>諦めてsedで置換しようと思ったのですがw、どうもSCSSのパーサーが怪しい気がしたので、Sass形式で試してみるとうまく動きました！</p>
<pre class="syntax-highlight">
/<span class="synType">* Sass */</span>
@mixin keyframes($name)
  @<span class="synStatement">-</span>moz<span class="synStatement">-</span>keyframes<span class="synComment"> #{$name}</span>
    @content
  @<span class="synStatement">-</span>webkit<span class="synStatement">-</span>keyframes<span class="synComment"> #{$name}</span>
    @content
  @<span class="synStatement">-</span>ms<span class="synStatement">-</span>keyframes<span class="synComment"> #{$name}</span>
    @content
  @keyframes<span class="synComment"> #{$name}</span>
    @content
</pre>

<p>Sassにはアンダースコアで始まるSassファイルを@importで読めるPartialsという機能がありますが、これはSCSS形式でもSass形式でも区別なく読めます。読み出し側と呼ばれる側の形式が異なっても問題なし。なので、普段はSCSS形式で書いていて、keyframesのmixinだけ_keyframes.sassとしてSassファイルで保存すれば、SCSSファイルから、</p>
<pre class="syntax-highlight">
<span class="synComment">/* SCSS */</span>
<span class="synPreProc">@import &#34;keyframes&#34;;</span>
</pre>

<p>として呼び出せます。Partial Sassとでも言いましょうか。素晴らしい！</p>
<br>

<p>CompassではAnimations関連のmixinが定義されていない（このkeyframes問題のせいかな？）ので、まるっと定義しました。ほとんどTransitionsのコピペですが。</p>

<ul>
<li> <a href="https://github.com/teppeis/menu-like-path/blob/master/sass/_animation.scss" target="_blank">https://github.com/teppeis/menu-like-path/blob/master/sass/_animation.scss</a></li>
<li> <a href="https://github.com/teppeis/menu-like-path/blob/master/sass/_keyframes.sass" target="_blank">https://github.com/teppeis/menu-like-path/blob/master/sass/_keyframes.sass</a></li>
</ul>
<h4>まとめ</h4>
<p>以前は、HTMLで構造を、CSSで見た目を、JavaScriptで振る舞いを、と言われていましたが、CSSで「動きの見た目」まで定義した方が、JSにはロジックだけ書けてすっきりするし、CSSを適切に書ければ自然とProgressive Enhancementになるので良いかなと思います。ただし、素のCSSは「動き」を記述するにはあまりに貧弱なので、Sass的なものが必須になってきます。</p>
<br>

<p>SassもCompassもまだ発展途上でいろいろ問題がありますが、現在進行形で発展しているのでおもしろいです。ガリガリ書き始めると、Sass/SCSSは@includeなど記述の冗長性が気になりますが、デザイナーさんと協業しているところは必要経費かもしれません。</p>
<br>

<p>個人的には、より自然で簡易な記述が出来るStylusが気になってます。Rubyで書かれたSassよりもJSのStylusの方が個人的に読みやすいのでｗ</p>
</div>
]]></description>

<dc:creator>teppeis</dc:creator>

<pubDate>Tue, 27 Dec 2011 23:38:03 GMT</pubDate>



<category>css</category>

<category>sass</category>


</item>

<item>
<title>[javascript][node.js]Node.jsの管理をHomebrewからnaveに移行した</title>
<link>http://d.hatena.ne.jp/teppeis/20110925/1316964759</link>

<description><![CDATA[
<div class="section">
<p>昔HomebrewでNode.jsをインストールしたけどnaveに移行したよという話。作業ついでに調べたことのメモ。</p>
<br>

<p>こんな生Node.jsはいやだ！（Homebrewとかのパッケージ管理やソースから入れたときの問題点）</p>

<ul>
<li> Node.jsのバージョンがもりもり上がる（これはソースから入れたときの問題）</li>
<li> 0.4系(stable)と0.5系(dev)を気軽に切り替えて試せない</li>
<li> Node.js本体とnpmの権限が違ったりして、sudoするとかしないとか面倒</li>
</ul>
<br>

<p>Node.js本体を管理するユーティリティとして<a href="https://github.com/creationix/nvm" target="_blank">nvm</a>と<a href="https://github.com/isaacs/nave" target="_blank">nave</a>っていう2つがあって機能はだいたい一緒。ただし、nvmはzshとの相性が悪いようでパッチを当てなきゃならんらしく、zsh厨としてはとりあえずnaveを選択。naveはnpmと作者が同じなので相性もいいはず（という願い）。</p>
<br>

<p>今回は、個人の開発環境用に全部ユーザーのホームディレクトリ以下にインストールする形にする。</p>
<h4>1. 古いNode.jsのアンインストール</h4>
<p>まずはHomebrewで入れた古いNode.jsのアンインストール、の前に、先にnpmのアンインストールをしておく。（npmをあとから消すのはパスの設定とかめんどくさかった）</p>
<pre class="syntax-highlight">
$ sudo npm uninstall npm -g
</pre>

<p>上のコマンドだとnpmでインストール済みのモジュール群は削除されない。削除したい人は、npm lsの結果をnpm rmするか、以下のコマンドで削除できるよって<a href="http://npmjs.org/doc/README.html" target="_blank">公式README</a>に書いてあった（怖いから試してない）。</p>
<pre class="syntax-highlight">
$ npm explore npm -g -- sh scripts/clean-old.sh
</pre>

<p>次いでNode.js本体のアンインストール。</p>
<pre class="syntax-highlight">
$ sudo brew uninstall node.js
</pre>

<p>あとNODE_PATHとかの環境変数を.profileとかに書いてたら消しとく。</p>
<h4>2. naveとNode.jsのインストール</h4>
<p>実際にはnave.shさえあればいいのだけど、手っ取り早くcloneする。</p>
<pre class="syntax-highlight">
$ git clone https://github.com/isaacs/nave.git ~/.nave
</pre>

<p>nave.shにパスを通す。ここではパスの通ったディレクトリにリンクしてるけど、aliasにしてもいい。</p>
<pre class="syntax-highlight">
$ ln -s ~/.nave/nave.sh ~/local/bin/nave
</pre>

<p>次にnaveコマンドでNode.js本体をインストール</p>
<pre class="syntax-highlight">
$ nave use stable
$ node -v
v0.4.12
</pre>

<p>"stable"だと安定板0.4系の最新バージョン、"latest"だと0.5系の最新バージョンをインストールした上で、もろもろの環境変数を設定してくれる。もちろん"nave use 0.4.12"とか直接バージョンを指定してもいい。</p>
<br>

<p>実際にインストールしてから分かったのだけど、このnaveというのは各種環境変数を設定したshellを起動するシェルスクリプト。なので何回もnave useすると何層もシェルをラップするような感じになってしまう。ちょっといやな感じ。どうやらnvmの方はシェル起動ではなく現在のシェルの上で環境変数をよろしくするタイプらしいのだけど、うーん。どっちもどっちか。</p>
<br>

<p>ということなので、常時Node.jsを有効にするためには、nave use stableを.profileに書いておくか、.bashrc系なら以下のように書くとnave useするたびに多重起動しちゃうのを防げる。</p>
<pre class="syntax-highlight">
if [ ${NAVELVL-0} -lt 1 ]; then
    nave use stable
fi
</pre>
<p>$NAVELVLはnave useを呼んだ回数、現在何層目かを記憶しているトーテム<span class="footnote"><a href="/teppeis/#f1" name="fn1" title="リンボーに落ちないように気をつけろ！">*1</a></span>のようなものなので、これで判定するのが良いでしょう。</p>
<h4>3. npmのインストール</h4>
<p>npmは普通にインストール。</p>
<pre class="syntax-highlight">
$ curl http://npmjs.org/install.sh | sh
</pre>

<p>試しにexpressをインストール。</p>
<pre class="syntax-highlight">
$ npm install express -g
</pre>

<p> -gオプションを付けると、現在useしているバージョンのNode.js全体で使えるようにインストールしてくれる。逆に付けないとカレントディレクトリのnode_modulesにインストールしちゃうので、アプリ単位で必要なときに使う。</p>
<h4>4. ディレクトリ構成の確認</h4>
<p>そうするとだいたいこんな感じになる。</p>
<pre>
.nave/
├── installed
│&#160;&#160; ├── 0.4.12
│&#160;&#160; │&#160;&#160; ├── bin
│&#160;&#160; │&#160;&#160; │&#160;&#160; ├── express -&#62; ../lib/node_modules/express/bin/express
│&#160;&#160; │&#160;&#160; │&#160;&#160; ├── node
│&#160;&#160; │&#160;&#160; │&#160;&#160; ├── node-waf
│&#160;&#160; │&#160;&#160; │&#160;&#160; ├── node_g
│&#160;&#160; │&#160;&#160; │&#160;&#160; ├── npm -&#62; ../lib/node_modules/npm/bin/npm.js
│&#160;&#160; │&#160;&#160; │&#160;&#160; ├── npm-g -&#62; ../lib/node_modules/npm/bin/npm.js
│&#160;&#160; │&#160;&#160; │&#160;&#160; └── npm_g -&#62; ../lib/node_modules/npm/bin/npm.js
│&#160;&#160; │&#160;&#160; ├── include
│&#160;&#160; │&#160;&#160; ├── lib
│&#160;&#160; │&#160;&#160; │&#160;&#160; ├── node
│&#160;&#160; │&#160;&#160; │&#160;&#160; ├── node_modules
│&#160;&#160; │&#160;&#160; │&#160;&#160; │&#160;&#160; ├── express
│&#160;&#160; │&#160;&#160; │&#160;&#160; │&#160;&#160; ├── npm
│&#160;&#160; │&#160;&#160; │&#160;&#160; │&#160;&#160; └── socket.io
│&#160;&#160; │&#160;&#160; │&#160;&#160; └── pkgconfig
│&#160;&#160; │&#160;&#160; └── share
│&#160;&#160; └── 0.5.7
└── src
    ├── 0.4.12
    └── 0.5.7
</pre>
<p>Node.js本体もnpmでインストールされたモジュールも、全部ユーザーのホームに作った.naveに入ってて、かつ本体のバージョンごとに分かれていることが分かる。</p>
<br>

<p>個人の開発環境としてはかなり開発しやすくなったと思います。お疲れさまでした！</p>
</div>
<div class="footnote">
<p class="footnote"><a href="/teppeis/#fn1" name="f1">*1</a>：リンボーに落ちないように気をつけろ！</p>
</div>
]]></description>

<dc:creator>teppeis</dc:creator>

<pubDate>Sun, 25 Sep 2011 15:32:39 GMT</pubDate>



<category>javascript</category>

<category>node.js</category>


</item>

<item>
<title>[mac]Mac OS X Lionで外部モニターを接続するとクラッシュする原因はInsomniaTだった</title>
<link>http://d.hatena.ne.jp/teppeis/20110827/1314434040</link>

<description><![CDATA[
<div class="section">
<p>先日、<a href="http://d.hatena.ne.jp/teppeis/20110726/1311693402" target="_blank">MacBookでデュアルディスプレイでフルスクリーンにするとフリーズすると書いた</a>のですが、実際にはフルスクリーンにする前に外部ディスプレーを接続した時点でCPU暴走が始まっていてハングしているようでした。</p>
<p>Mac OS X 10.7.1もリリースされたところでもう一度情報収集していると、Appleのフォーラムで解答を見つけました。</p>
<blockquote title="https://discussions.apple.com/message/15752716" cite="https://discussions.apple.com/message/15752716">
<p>Gentlemen! Removing InsomniaT solved it for me. It seems to work just fine now, and the error messages, the high CPU load and the freezes are gone.</p>
<cite><a href="https://discussions.apple.com/message/15752716" target="_blank">https://discussions.apple.com/message/15752716</a></cite></blockquote>
<p>InsomniaTのこのバグが原因だったようです。</p>
<p><a href="https://bugs.launchpad.net/insomniat/+bug/804321" target="_blank">Bug #804321 in InsomniaT: “OSX 10.7 with external display causes CPU spike”</a></p>
<p>以前に使っていたInsomniaXがLionでは使えなかったので、<a href="http://d.hatena.ne.jp/teppeis/20110606/1307371920" target="_blank">ちょうどInsomniaXに乗り換えた</a>ところでした。該当のバグは3.0.2で修正済みとのことで、バージョンアップしたら無事に外部ディスプレーが使えました。古いバージョンの方はアップデートをおすすめします。</p>
<p>もう信用ならん！という人は、最新版のアーカイブにアンインストーラーが入っています。手動で削除したい人は<a href="https://answers.launchpad.net/insomniat/+faq/1707" target="_blank">こちら</a>を参考に。</p>
</div>
]]></description>

<dc:creator>teppeis</dc:creator>

<pubDate>Sat, 27 Aug 2011 08:34:00 GMT</pubDate>



<category>mac</category>


</item>

</channel>
</rss>

