whiskers
UI/UX Design、フロントエンド系について学習した内容をメモしています。
UI/UX Design、フロントエンド系について学習した内容をメモしています。
https://whiskers.nukos.kitchen/
2017-03-29T02:00:00Z
Ryuichi Nonaka
[yarn][nodejs] bower-rails から yarn への移行
https://whiskers.nukos.kitchen/2017/03/29/bower-rails-to-yarn.html
2017-03-29T02:00:00Z
2017-03-29T03:20:11+00:00
nukos
<h2>はじめに</h2>
<p>プライベートプロジェクトで Atomic Design の世界を彷徨っていて久しぶりの記事になってしまいました。
業務で bower-rails を使っているけれど、Node.js 環境を整備する次いでに bower-rails から yarn に移行した際のメモを残しておきます。
将来的に browserify や webpack も活用してみたいですが、現時点でそこまでやりきれる状態にないので、パッケージマネージャを yarn に移行して Sprockets は引き続き利用...</p>
<h2>はじめに</h2>
<p>プライベートプロジェクトで Atomic Design の世界を彷徨っていて久しぶりの記事になってしまいました。
業務で bower-rails を使っているけれど、Node.js 環境を整備する次いでに bower-rails から yarn に移行した際のメモを残しておきます。
将来的に browserify や webpack も活用してみたいですが、現時点でそこまでやりきれる状態にないので、パッケージマネージャを yarn に移行して Sprockets は引き続き利用する前提です。</p>
<h3>yarn とは</h3>
<p>詳しい説明は省きますが、<a href="https://yarnpkg.com/">yarn</a> は npm 互換のパッケージマネージャです。
npm と違い、ディレクトリ配置の制御、賢いローカルキャッシュ、lock ファイルでバージョン固定、が yarn の特徴です。
詳しくはこちらの記事 <a href="http://qiita.com/mizchi/items/1002fde0de10e7c54fb2">Yarnファーストインプレッション</a> にまとめられています。</p>
<h3>yarn のインストール</h3>
<p><a href="https://yarnpkg.com/en/docs/getting-started">Getting Started - yarn</a> を見ながらインストールを進めます。Node.js の環境が準備できれば特に難しいことはありません。
注意点としては、yarn を使うために Node.js 4.0 以上が必要です。</p>
<p>bower-rails を使っていたのであれば package.json がすでにあると思うので <code>$ yarn init</code> は不要です。</p>
<h2>パッケージのインストール</h2>
<p>使っているパッケージを yarn を使ってインストールします。
インストールが完了すると root に <code>yarn.lock</code> というファイルができるはずです。</p>
<pre class="highlight shell"><code><span class="gp">$ </span>yarn add <package>
</code></pre>
<p>パッケージのインストールディレクトリを変更したい場合は <code>--modules-folder <path></code> オプションを加えます。今回は <code>vendor/assets/components</code> にパッケージを置きたいので <code>yarn add <package> --modules-folder ./vendor/assets/components/</code> としてインストールしました。毎回指定するのは面倒くさいのですが、残念ながらコンフィグファイル等でデフォルトを指定することは現時点ではできません。</p>
<ul>
<li><a href="https://yarnpkg.com/en/docs/cli/">CLI Introduction</a></li>
<li><a href="https://yarnpkg.com/lang/en/docs/migrating-from-npm/#toc-cli-commands-comparison">CLI commands comparison - Migrating from npm</a> ( npm コマンドとの違いはここがわかりやすい)</li>
</ul>
<h2>assets の path を設定</h2>
<p>Rails で使えるようにするために <code>config/initializers/assets.rb</code> で assets.paths を設定します。</p>
<pre class="highlight ruby"><code><span class="no">Rails</span><span class="p">.</span><span class="nf">application</span><span class="p">.</span><span class="nf">config</span><span class="p">.</span><span class="nf">assets</span><span class="p">.</span><span class="nf">paths</span> <span class="o"><<</span> <span class="no">Rails</span><span class="p">.</span><span class="nf">root</span><span class="p">.</span><span class="nf">join</span><span class="p">(</span><span class="s2">"vendor"</span><span class="p">,</span> <span class="s2">"assets"</span><span class="p">,</span> <span class="s2">"components"</span><span class="p">)</span>
</code></pre>
<h2>Sprockets の パスを書き換える</h2>
<p>パッケージ名のルールの違いによって、一部のパッケージのパスの書き換えが必要です。ものによってはパッケージ名自体が変わっていることもあります。</p>
<pre class="highlight plaintext"><code>-//= require jquery.lazyload/jquery.lazyload
+//= require jquery-lazyload/jquery.lazyload
</code></pre>
<h2>single version install</h2>
<p>1つのバージョンのみをインストールしたい場合、<code>$ yarn install</code> に <code>--flat</code> オプションを加えます。このオプションは <code>package.json</code> でも指定できます。
バージョンを指定したい場合は <code>package.json</code> に resolutions を指定します。</p>
<pre class="highlight json"><code><span class="p">{</span><span class="w">
</span><span class="s2">"resolutions"</span><span class="p">:</span><span class="w"> </span><span class="p">{</span><span class="w">
</span><span class="s2">"jquery"</span><span class="p">:</span><span class="w"> </span><span class="s2">"2.2.4"</span><span class="p">,</span><span class="w">
</span><span class="s2">"source-map"</span><span class="p">:</span><span class="w"> </span><span class="s2">"0.4.4"</span><span class="w">
</span><span class="p">}</span><span class="w">
</span><span class="p">}</span><span class="w">
</span></code></pre>
<ul>
<li><a href="https://yarnpkg.com/en/docs/package-json">package.json - config</a></li>
</ul>
<h2>bower-rails の削除</h2>
<p>あとは bower-rails の削除から gem 本体とプロジェクト内のファイルを削除します。</p>
<ul>
<li>Bowerfile</li>
<li>bower.json</li>
<li>config/initializers/bower_rails.rb</li>
<li>vendor/assets/bowerrc</li>
<li>vendor/assets/bower.json</li>
</ul>
<h2>install コマンドを用意する</h2>
<p><code>$ yarn install</code> の実行時にインストールディレクトリを明示的に指定しないと意図した場所にインストールできないのですが、 <code>run</code> コマンドを使って簡略化できます。
<code>package.json</code> に以下の scripts を追加することで <code>$ yarn run frontend_install</code> でインストールできるようになります。</p>
<pre class="highlight json"><code><span class="p">{</span><span class="w">
</span><span class="s2">"scripts"</span><span class="p">:</span><span class="w"> </span><span class="p">{</span><span class="w">
</span><span class="s2">"test"</span><span class="p">:</span><span class="w"> </span><span class="s2">"echo </span><span class="se">\"</span><span class="s2">Error: no test specified</span><span class="se">\"</span><span class="s2"> && exit 1"</span><span class="p">,</span><span class="w">
</span><span class="s2">"frontend_install"</span><span class="p">:</span><span class="w"> </span><span class="s2">"yarn install --modules-folder ./vendor/assets/components/"</span><span class="w">
</span><span class="p">}</span><span class="w">
</span><span class="p">}</span><span class="w">
</span></code></pre>
<p>他に良い方法をご存じの方がいたらアドバイスいただけると幸いです。
これで bower-rails から yarn に移行することができました。</p>
<h2>参考記事</h2>
<ul>
<li><a href="https://sheerdevelopment.com/posts/using-yarn-with-rails">Using Yarn with Rails</a></li>
</ul>
[CSS][SCSS][JavaScript][jQuery] CSS の状態管理にカスタムデータ属性を使う
https://whiskers.nukos.kitchen/2016/11/19/data-attr-style.html
2016-11-19T08:00:00Z
2017-03-29T03:20:11+00:00
nukos
<h2>はじめに</h2>
<p>少し前に何かで見かけて試してみたいなと思っていた CSS の状態管理にカスタムデータ属性を使う方法について調べてまとめてみました。</p>
<h3>カスタムデータ属性とは</h3>
<blockquote>
<p>data-* グローバル属性はカスタムデータ属性と呼ばれる属性の組を作り、HTML と、スクリプトによって使用されるであろう DOM 表現との間で、固有の情報を交換できるようにします。すべてのカスタムデータは、属性を設定した要素の HTMLElement インターフェイスを通して使用できます。HTMLElement.dataset...</p>
</blockquote>
<h2>はじめに</h2>
<p>少し前に何かで見かけて試してみたいなと思っていた CSS の状態管理にカスタムデータ属性を使う方法について調べてまとめてみました。</p>
<h3>カスタムデータ属性とは</h3>
<blockquote>
<p>data-* グローバル属性はカスタムデータ属性と呼ばれる属性の組を作り、HTML と、スクリプトによって使用されるであろう DOM 表現との間で、固有の情報を交換できるようにします。すべてのカスタムデータは、属性を設定した要素の HTMLElement インターフェイスを通して使用できます。HTMLElement.dataset プロパティがそれらへのアクセス手段を提供します。</p>
</blockquote>
<p><a href="https://developer.mozilla.org/ja/docs/Web/HTML/Global_attributes/data-*">Mozilla Developer Network - data-*</a></p>
<p>簡単に言えば HTML Element に対して <code><div data-hoge="fuga"></code> のような独自に属性を設定できる機能です。</p>
<h3>サンプル</h3>
<p>カスタムデータ属性でボタンの文字色を toggle するサンプルがこちら。</p>
<p data-height="194" data-theme-id="light" data-slug-hash="mOPegv" data-default-tab="result" data-user="nukos" data-embed-version="2" data-pen-title="Custom Data Selector" data-preview="true" class="codepen">See the Pen <a href="http://codepen.io/nukos/pen/mOPegv/">Custom Data Selector</a> by nuko’s kitchen (<a href="http://codepen.io/nukos">@nukos</a>) on <a href="http://codepen.io">CodePen</a>.</p>
<script async src="https://production-assets.codepen.io/assets/embed/ei.js"></script>
<h2>カスタムデータ属性の使い方</h2>
<p>カスタムデータ属性を HTML に設定し、CSS/JavaScript(jQuery) から参照する方法をお復習いします。</p>
<h3>HTML</h3>
<pre class="highlight html"><code><span class="nt"><button</span> <span class="na">class=</span><span class="s">"button"</span> <span class="na">data-is-active=</span><span class="s">"true"</span><span class="nt">></button></span>
</code></pre>
<h3>CSS</h3>
<p>CSS は属性セレクタを使って柔軟に制御できます。</p>
<pre class="highlight css"><code><span class="nc">.button</span><span class="o">[</span><span class="nt">data-is-active</span><span class="o">=</span><span class="nt">true</span><span class="o">]</span> <span class="p">{</span>
<span class="nl">color</span><span class="p">:</span> <span class="no">red</span><span class="p">;</span>
<span class="p">}</span>
</code></pre>
<h3>javaScript</h3>
<p>素の JavaScript では <code>getAttribute</code> と <code>setAttribute</code> が使えます。また <code>dataset</code> を使うことでより簡単にカスタムデータ属性を操作できますが <strong>Internet Explorer 11 以上</strong> でないと使えません。<code>dataset</code> の場合、ハイフン <code>-</code> で繋がれたカスタムデータ属性 <code>is-active</code> はローワーキャメルケース <code>isActive</code> で取得することができます。</p>
<pre class="highlight javascript"><code><span class="kd">var</span> <span class="nx">element</span> <span class="o">=</span> <span class="nb">document</span><span class="p">.</span><span class="nx">querySelector</span><span class="p">(</span><span class="s2">".button"</span><span class="p">);</span>
<span class="c1">//get</span>
<span class="kd">var</span> <span class="nx">attr</span> <span class="o">=</span> <span class="nx">element</span><span class="p">.</span><span class="nx">getAttribute</span><span class="p">(</span><span class="s1">'data-is-active'</span><span class="p">);</span>
<span class="kd">var</span> <span class="nx">attrCamel</span> <span class="o">=</span> <span class="nx">element</span><span class="p">.</span><span class="nx">dataset</span><span class="p">.</span><span class="nx">isActive</span><span class="p">;</span>
<span class="c1">//set</span>
<span class="nx">element</span><span class="p">.</span><span class="nx">setAttribute</span><span class="p">(</span><span class="s1">'data-is-active'</span><span class="p">,</span> <span class="kc">true</span><span class="p">);</span>
<span class="nx">element</span><span class="p">.</span><span class="nx">dataset</span><span class="p">.</span><span class="nx">isActive</span> <span class="o">=</span> <span class="kc">true</span><span class="p">;</span>
</code></pre>
<h3>jQuery</h3>
<p>jQuery の場合は <code>data()</code> と <code>attr()</code> の2つの方法があり、それぞれ挙動が違うので注意が必要です。<code>attr()</code> は DOM のカスタムデータ属性を直接書き換えますが <code>data()</code> は jQuery オブジェクト内のキャッシュを優先的に使用し、キャッシュが存在しないときのみカスタムデータ属性から値を取得します。</p>
<pre class="highlight javascript"><code><span class="c1">//get</span>
<span class="kd">var</span> <span class="nx">data</span> <span class="o">=</span> <span class="nx">$</span><span class="p">(</span><span class="s1">'.button'</span><span class="p">).</span><span class="nx">data</span><span class="p">(</span><span class="s2">"is-active"</span><span class="p">);</span>
<span class="kd">var</span> <span class="nx">attr</span> <span class="o">=</span> <span class="nx">$</span><span class="p">(</span><span class="s1">'.button'</span><span class="p">).</span><span class="nx">attr</span><span class="p">(</span><span class="s2">"data-is-active"</span><span class="p">);</span>
<span class="c1">//set</span>
<span class="nx">$</span><span class="p">(</span><span class="s1">'.button'</span><span class="p">).</span><span class="nx">data</span><span class="p">(</span><span class="s2">"is-active"</span><span class="p">,</span> <span class="kc">true</span><span class="p">);</span>
<span class="nx">$</span><span class="p">(</span><span class="s1">'.button'</span><span class="p">).</span><span class="nx">attr</span><span class="p">(</span><span class="s2">"data-is-active"</span><span class="p">,</span> <span class="kc">true</span><span class="p">);</span>
</code></pre>
<p>カスタムデータ属性を JavaScript だけで使う場合は <code>data()</code> を使えば良いですが、 CSS からも使う場合、DOM の カスタムデータを書き換えないと変更を検知してもらえないので <code>attr()</code> を使うことが必須となります。 jQuery オブジェクトからも参照したい場合は状態を変更するときに <code>data()</code> と <code>attr()</code> どちらも行わなければなりません。</p>
<pre class="highlight javascript"><code><span class="nx">$</span><span class="p">(</span><span class="s1">'.button'</span><span class="p">)</span>
<span class="p">.</span><span class="nx">data</span><span class="p">(</span><span class="s2">"is-active"</span><span class="p">,</span> <span class="kc">true</span><span class="p">)</span>
<span class="p">.</span><span class="nx">attr</span><span class="p">(</span><span class="s2">"data-is-active"</span><span class="p">,</span> <span class="kc">true</span><span class="p">);</span>
</code></pre>
<p>冗長ではありますが jQuery の場合は独自に拡張を作らない限りこうするしかありません。蛇足ですが、プロパティを制御する <code>prop()</code> は JavaScript のプロパティを制御するものなのでカスタムデータ属性には使えません。</p>
<h2>セレクタを定義する Mixin</h2>
<p>CSS のカスタムデータ属性セレクタの指定を簡略化するために Mixin を作ってみました。</p>
<script src="https://gist.github.com/nukos/5c83bb61d4903f01ff77a414786e1334.js"></script>
<p>状態の有効・無効にした際のスタイルを以下のように指定します。</p>
<pre class="highlight scss"><code><span class="nc">.example</span> <span class="p">{</span>
<span class="k">@include</span> <span class="nd">data-state</span><span class="p">(</span><span class="s1">'active'</span><span class="p">)</span> <span class="p">{</span>
<span class="nl">color</span><span class="p">:</span> <span class="no">red</span><span class="p">;</span>
<span class="p">}</span>
<span class="k">@include</span> <span class="nd">data-state</span><span class="p">(</span><span class="s1">'active'</span><span class="o">,</span> <span class="bp">false</span><span class="p">)</span> <span class="p">{</span>
<span class="nl">color</span><span class="p">:</span> <span class="no">black</span><span class="p">;</span>
<span class="p">}</span>
<span class="p">}</span>
</code></pre>
<p>プリコンパイルされた CSS はこのようになります。</p>
<pre class="highlight css"><code><span class="nc">.example</span><span class="o">[</span><span class="nt">data-is-active</span><span class="o">=</span><span class="nt">true</span><span class="o">]</span> <span class="p">{</span>
<span class="nl">color</span><span class="p">:</span> <span class="no">red</span><span class="p">;</span>
<span class="p">}</span>
</code></pre>
<h2>終わりに</h2>
<p>jQuery の場合、data属性の変更方法が冗長なところはありますが、カスタムデータ属性を使うことで状態を class 以外のところで管理できるので class が汚れにくく、JavaScript からの制御もし易くなりますね。</p>
<h3>参考サイト</h3>
<ul>
<li><a href="https://developer.mozilla.org/ja/docs/Web/CSS/Attribute_selectors">属性セレクタ</a></li>
<li><a href="https://developer.mozilla.org/ja/docs/Web/API/HTMLElement/dataset">HTMLElement.dataset</a></li>
<li><a href="http://qiita.com/trkbt10/items/ae33dfd579c9cea7f056">CSS設計の類はもっとカスタムデータ属性を活用するべきでは</a></li>
</ul>
[Wercker][Amazon S3] Wercker の step-s3sync で起こった 「Parameter problem: Invalid source/destination」エラーの直し方(小ネタ)
https://whiskers.nukos.kitchen/2016/11/12/wercker-step-s3sync.html
2016-11-11T15:30:00Z
2017-03-29T03:20:11+00:00
nukos
<h2>はじめに</h2>
<p>Wercker の <a href="https://github.com/wercker/step-s3sync">step-s3sync</a> を使っていて突然 Sync できないと思ったら step-s3sync のところでエラーが出ていた。</p>
<pre class="highlight shell"><code>/pipeline/.../s3cmd sync --encoding<span class="o">=</span>utf-8 --delete-removed --verbose ./ whiskers.nukos.kitchen
ERROR: Parameter problem: Invalid <span class="nb">source</span>/destination: <span class="s1">'./'</span> <span class="s1">'whiskers.nukos...</span></code></pre>
<h2>はじめに</h2>
<p>Wercker の <a href="https://github.com/wercker/step-s3sync">step-s3sync</a> を使っていて突然 Sync できないと思ったら step-s3sync のところでエラーが出ていた。</p>
<pre class="highlight shell"><code>/pipeline/.../s3cmd sync --encoding<span class="o">=</span>utf-8 --delete-removed --verbose ./ whiskers.nukos.kitchen
ERROR: Parameter problem: Invalid <span class="nb">source</span>/destination: <span class="s1">'./'</span> <span class="s1">'whiskers.nukos.kitchen'</span>
</code></pre>
<p>どうやら <code>s3cmd sync</code> で S3 のバケット指定が上手くいっていないらしい。実際の指定はこれ。</p>
<pre class="highlight yaml"><code><span class="pi">-</span> <span class="na">s3sync</span><span class="pi">:</span>
<span class="na">key_id</span><span class="pi">:</span> <span class="s">$AWS_ACCESS_KEY_ID</span>
<span class="na">key_secret</span><span class="pi">:</span> <span class="s">$AWS_SECRET_ACCESS_KEY</span>
<span class="na">bucket_url</span><span class="pi">:</span> <span class="s">$AWS_BUCKET_URL</span>
<span class="na">source_dir</span><span class="pi">:</span> <span class="s">build/</span>
<span class="na">delete-removed</span><span class="pi">:</span> <span class="s">true</span>
<span class="na">opts</span><span class="pi">:</span> <span class="s">--encoding=utf-8</span>
</code></pre>
<p><code>$AWS_BUCKET_URL</code> には <code>s3://whiskers.nukos.kitchen</code> が入っているのになぜか <code>whiskers.nukos.kitchen</code> になってしまっている。</p>
<h2>修正方法</h2>
<p>以前、バケット URL をはじめて設定したときに <code>whiskers.nukos.kitchen</code> で設定したことがあったのを思い出して、キャッシュかなにかが残っている可能性があったので Wercker のキャッシュを削除してみたところ無事に動くことを確認できた。</p>
<h2>その他に試したこと</h2>
<p>step-s3sync の設定で明示的に <code>delete-removed: true</code> を指定していたが、これを削除した。step-s3sync のオプションでは明示的に指定しない場合、デフォルトでは <code>true</code> になっているし不要な設定だった。</p>
<p>もう一つ <code>--acl-public</code> オプションを追加した。</p>
<pre class="highlight yaml"><code><span class="pi">-</span> <span class="na">s3sync</span><span class="pi">:</span>
<span class="na">key_id</span><span class="pi">:</span> <span class="s">$AWS_ACCESS_KEY_ID</span>
<span class="na">key_secret</span><span class="pi">:</span> <span class="s">$AWS_SECRET_ACCESS_KEY</span>
<span class="na">bucket_url</span><span class="pi">:</span> <span class="s">$AWS_BUCKET_URL</span>
<span class="na">source_dir</span><span class="pi">:</span> <span class="s">build/</span>
<span class="na">opts</span><span class="pi">:</span> <span class="s">--encoding=utf-8 --acl-public</span>
</code></pre>
<p>このオプションを追加したことによって、何らかの理由でキャッシュがクリアされ正常に動作するようになったが再発したので根本的な解決案ではない。</p>
<ul>
<li><a href="http://qiita.com/kentokento/items/7881efe1717fbe5fdfba">AWS CLIを使ってS3のバケット内オブジェクトのpermission(ACL)を一括変更する</a></li>
</ul>
[Browserify][Gulp] Browserify と browserify-shim でグローバルオブジェクトを扱う
https://whiskers.nukos.kitchen/2016/11/08/browserify-shim.html
2016-11-07T18:00:00Z
2017-03-29T03:20:11+00:00
nukos
<h2>はじめに</h2>
<p>script タグや <a href="https://github.com/rails/sprockets">Sprockets</a> で依存関係を管理していたところから <a href="http://browserify.org/">Browserify</a> や <a href="http://webpack.github.io/">webpack</a> などの CommonJS ベースのモジュール管理に移行する過渡期に jQuery や jQuery Plugins などのグローバルオブジェクトを Browserify ではどのように扱うのかについて覚えたことをメモしておきます。</p>
<p>CommonJS ベースのモジュール管理については末尾の参考サイトを読んでみてください。</p>
<h3>環境</h3>
<p>以前に書いた Browserify...</p>
<h2>はじめに</h2>
<p>script タグや <a href="https://github.com/rails/sprockets">Sprockets</a> で依存関係を管理していたところから <a href="http://browserify.org/">Browserify</a> や <a href="http://webpack.github.io/">webpack</a> などの CommonJS ベースのモジュール管理に移行する過渡期に jQuery や jQuery Plugins などのグローバルオブジェクトを Browserify ではどのように扱うのかについて覚えたことをメモしておきます。</p>
<p>CommonJS ベースのモジュール管理については末尾の参考サイトを読んでみてください。</p>
<h3>環境</h3>
<p>以前に書いた Browserify の記事 <a href="/2016/10/06/gulp-watchify.html">Gulp から Watchify と Browserify を使う</a> を参考に、 Gulp と Browserify の環境を用意します。また、グローバルオブジェクトの扱い方については jQuery を使って試します。</p>
<h2>npm の jQuery を require する</h2>
<p>まずは、シンプルに jQuery を require してみます。これだけであれば特に難しいことはなく、<code>$ npm install --save jquery</code> をして require するだけです。jQuery プラグイン等も基本的には npm にあるものを使っていくのが良さそうです。</p>
<pre class="highlight javascript"><code><span class="kd">var</span> <span class="nx">$</span> <span class="o">=</span> <span class="nx">require</span><span class="p">(</span><span class="s1">'jquery'</span><span class="p">);</span>
<span class="nx">$</span><span class="p">(</span><span class="kd">function</span><span class="p">(){</span>
<span class="nx">console</span><span class="p">.</span><span class="nx">log</span><span class="p">(</span><span class="nx">$</span><span class="p">(</span><span class="s1">'body'</span><span class="p">));</span>
<span class="p">});</span>
</code></pre>
<p>ただ、この手法だと <code>bundle.js</code> に jQuery 本体も含むことになるためファイルサイズが大きくなってしまいます。できればCDNを活用したいところです。</p>
<h2>browserify-shim を使ってグローバルオブジェクトを require する</h2>
<p>jQuery 本体は別ファイル(CDNを含む)で読み込ませ、グローバルオブジェクト(<code>$</code>)を require できればファイルサイズの問題は少しだけマシになるかもしれません。それを実現するのが <a href="https://github.com/thlorenz/browserify-shim">browserify-shim</a> です。</p>
<p>browserify-shim は グローバルオブジェクトを require できるモジュールにしてくれます(Shimとは詰め木のこと)。</p>
<h3>browserify-shim のインストールと設定</h3>
<p>npm から browserify-shim をインストール <code>$ npm install --save-dev browserify-shim</code> します。インストールしたら <code>package.json</code> に browserify-shim を使うためのおまじないを追加します。<a href="https://github.com/substack/node-browserify#browserifytransform">transform</a> というのは 様々なものを Browserify で扱えるように変換するためのモジュールのことです。これで準備ができました。</p>
<pre class="highlight javascript"><code> <span class="s2">"browserify"</span><span class="p">:</span> <span class="p">{</span>
<span class="s2">"transform"</span><span class="p">:</span> <span class="p">[</span> <span class="s2">"browserify-shim"</span> <span class="p">]</span>
<span class="p">},</span>
</code></pre>
<h3>グローバルオブジェクトをモジュール化する</h3>
<p>適当に JavaScript を作成し、<code>hoge</code> というグローバルオブジェクトを用意します。私の場合は面倒なので slim ファイルに script タグを定義しました。</p>
<pre class="highlight plaintext"><code>javascript:
var hoge = "HelloWorld!";
</code></pre>
<p><code>package.json</code> に browserify-shim を定義します。グローバルにある <code>hoge</code> オブジェクト(<code>global:hoge</code>)を <code>hoge</code> という名前でモジュールに変換します。</p>
<pre class="highlight javascript"><code> <span class="s2">"browserify-shim"</span><span class="p">:</span> <span class="p">{</span>
<span class="s2">"hoge"</span><span class="p">:</span> <span class="s2">"global:hoge"</span>
<span class="p">},</span>
</code></pre>
<p>あとは <code>hoge</code> モジュールを <code>require('hoge')</code> して コンソールに出力してみます。コンソールに <code>HelloWorld!</code> と出力されていれば成功です。</p>
<pre class="highlight javascript"><code><span class="kd">var</span> <span class="nx">hoge</span> <span class="o">=</span> <span class="nx">require</span><span class="p">(</span><span class="s1">'hoge'</span><span class="p">);</span>
<span class="nx">console</span><span class="p">.</span><span class="nx">log</span><span class="p">(</span><span class="nx">hoge</span><span class="p">);</span>
</code></pre>
<h3>CDN の jQuery を使う</h3>
<p>グローバルオブジェクトをモジュール化することで script タグで読み込んだ CDN の jQuery などをモジュールとして require できるようになります。browserify-shim は CDN の JavaScript が グローバルオブジェクトにできるのを待って処理してくれるようになっているのでその点も安心です。</p>
<pre class="highlight javascript"><code> <span class="s2">"browserify"</span><span class="p">:</span> <span class="p">{</span>
<span class="s2">"transform"</span><span class="p">:</span> <span class="p">[</span> <span class="s2">"browserify-shim"</span> <span class="p">]</span>
<span class="p">},</span>
<span class="s2">"browserify-shim"</span><span class="p">:</span> <span class="p">{</span>
<span class="s2">"jquery"</span><span class="p">:</span> <span class="s2">"$"</span>
<span class="p">},</span>
</code></pre><pre class="highlight javascript"><code><span class="nx">require</span><span class="p">(</span><span class="s1">'jquery'</span><span class="p">);</span>
<span class="nx">$</span><span class="p">(</span><span class="kd">function</span><span class="p">(){</span>
<span class="nx">console</span><span class="p">.</span><span class="nx">log</span><span class="p">(</span><span class="nx">$</span><span class="p">(</span><span class="s1">'body'</span><span class="p">));</span>
<span class="p">});</span>
</code></pre>
<h3>カスタムした jQuery を require したい</h3>
<p>カスタムした jQuery (不要な機能を省いたりしたもの)を require したいときは <strong>Browser field</strong> (差し替え)を使います。
Browser field を利用するには <code>package.json</code> に <code>browser field</code> を追加し、差し替える対象ファイルを指定します。</p>
<pre class="highlight javascript"><code> <span class="s2">"browserify"</span><span class="p">:</span> <span class="p">{</span>
<span class="s2">"transform"</span><span class="p">:</span> <span class="p">[</span> <span class="s2">"browserify-shim"</span> <span class="p">]</span>
<span class="p">},</span>
<span class="s2">"browser"</span><span class="p">:</span> <span class="p">{</span>
<span class="s2">"jquery"</span><span class="p">:</span> <span class="s2">"./hoge/jquery.js"</span>
<span class="p">},</span>
<span class="s2">"browserify-shim"</span><span class="p">:</span> <span class="p">{</span>
<span class="s2">"jquery"</span><span class="p">:</span> <span class="s2">"$"</span>
<span class="p">},</span>
</code></pre>
<h2>終わりに</h2>
<p>Browserify は CommonJS ベースのモジュール管理に慣れるのにちょうど良いツールな気がしました。比較的小規模なプロジェクトで使いつつ、大規模なプロジェクト向けに webpack を勉強していこうと思います。</p>
<h3>参考サイト</h3>
<ul>
<li><a href="https://tsuchikazu.net/javascript-module/">JavaScriptのモジュール管理(CommonJSとかAMDとかBrowserifyとかwebpack)</a></li>
<li><a href="http://qiita.com/shinout/items/4c9854b00977883e0668">package.json の browser field 入門編</a></li>
<li><a href="http://mae.chab.in/archives/2737">browserify-shimを使って、CDN経由で外部JSライブラリをrequireする</a></li>
<li><a href="http://qiita.com/tkdn/items/dd9cd9b6d4094f3b7f48">browserify - jqueryと依存するプラグインをどうにかしたい</a></li>
<li><a href="https://blog.kazu69.net/2015/04/18/browserify-uses-jquery-plugin-with-jquery-cdn/">browserifyでjQuery(CDN)とjQueryプラグインを使う</a></li>
</ul>
[Middleman 4][Gulp] Middleman 4 の External Pipeline に対応した Skeleten(テンプレート)「middleman-tail」 を作った
https://whiskers.nukos.kitchen/2016/11/01/middleman-tail.html
2016-11-01T10:30:00Z
2017-03-29T03:20:11+00:00
nukos
<h2>はじめに</h2>
<p>Middleman 4 の新機能を試しながらある程度知見がたまったので、それらを詰め合わせた ブログ向けの Middleman Skeleton 「<a href="https://github.com/nukos/middleman-tail">middleman-tail</a>」を作ってみました。名前と機能は全く関係無く、気分で「ねこのしっぽ」です。ドキュメントや README が不親切なのは大目に見てください。</p>
<h3>どんな Skeleton なのか</h3>
<p>JavaScript や Sass のコンパイルを Sprokets から External Pipeline を使って Gulp...</p>
<h2>はじめに</h2>
<p>Middleman 4 の新機能を試しながらある程度知見がたまったので、それらを詰め合わせた ブログ向けの Middleman Skeleton 「<a href="https://github.com/nukos/middleman-tail">middleman-tail</a>」を作ってみました。名前と機能は全く関係無く、気分で「ねこのしっぽ」です。ドキュメントや README が不親切なのは大目に見てください。</p>
<h3>どんな Skeleton なのか</h3>
<p>JavaScript や Sass のコンパイルを Sprokets から External Pipeline を使って Gulp に移行しつつ、ブログに必要な Middleman 拡張をプリインストールし、必要な設定を済ませてある<strong>「すぐにブログを作り始められる Skeleton」</strong>です。Skeleton として使うまでいかなくとも、各プラグインの使い方や External Pipeline の参考例ぐらいにはなるんじゃないかなと思っています。</p>
<ul>
<li>Github: <a href="https://github.com/nukos/middleman-tail">middleman-tail</a></li>
</ul>
<h3>主な特徴</h3>
<p>主な特徴は以下の通りです。<br>
HTMLやCSSは最低限のものしか用意していないので、フロント側は自由に作ることができます。</p>
<ul>
<li>拡張機能のプリインストールと設定
<ul>
<li><a href="https://github.com/middleman/middleman-blog">middleman-blog</a></li>
<li><a href="https://github.com/middleman/middleman-syntax">middleman-syntax</a></li>
<li><a href="https://github.com/ngs/middleman-ogp">middleman-ogp</a></li>
<li><a href="https://github.com/fredjean/middleman-s3_sync">middleman-s3_sync</a></li>
<li><a href="https://github.com/middleman/middleman-minify-html">middleman-minify-html</a></li>
</ul></li>
<li>外部パイプライン(Gulp)
<ul>
<li><a href="http://browserify.org/">Blowserify</a></li>
<li><a href="http://sass-lang.com/">Sass</a></li>
<li><a href="http://bourbon.io/">Bourbon</a></li>
<li><a href="http://neat.bourbon.io/">Neat</a></li>
<li><a href="http://fontawesome.io/">Font-Awesome</a></li>
</ul></li>
<li>Slim テンプレート</li>
<li>日本時間に対応 Asia/Tokyo (UTC+9)</li>
</ul>
<h3>環境</h3>
<p>この Skeleton を使うには以下の環境が必要です。</p>
<ul>
<li><a href="https://github.com/sstephenson/rbenv">rbenv</a> (Ruby: 2.3.1)</li>
<li><a href="https://github.com/riywo/ndenv">ndenv</a> (node.js: 6.6.0)</li>
<li><a href="http://bundler.io/">Bundler</a> (1.13.5)</li>
<li><a href="https://middlemanapp.com/jp/">Middleman</a> (4.1.10)</li>
<li><a href="https://github.com/gulpjs/gulp">Gulp</a></li>
</ul>
<h2>Skeleton のインストール</h2>
<p>Skeleton は github のリポジトリ名を指定してインストールできます(Middleman がインストールされていることが前提となります)。</p>
<pre class="highlight shell"><code><span class="gp">$ </span>middleman init PROJECTNAME -T nukos/middleman-tail
</code></pre>
<ul>
<li><a href="https://middlemanapp.com/jp/advanced/project_templates/">Middleman: プロジェクトテンプレート</a></li>
</ul>
<h3>npm のインストール</h3>
<p>Skeleton の インストール時に npm のインストールは行われないので手動でインストールします。</p>
<pre class="highlight shell"><code><span class="gp">$ </span>npm install
</code></pre>
<p>あとは <code>$ bundle exec middleman server</code> でサーバーを起動します。</p>
<h3>画面イメージ</h3>
<p><img alt="画面イメージ" src="http://cdn.whiskers.nukos.kitchen/uploads/2016/11/1/middleman-tail.png" /></p>
<h2>middleman-s3_sync について</h2>
<p>middleman-s3_sync をプリインストールしていますが、設定自体はオフになっています。AWS のアクセスキー・シークレット ID を直書きすることもできますが、AWS SDK for Ruby の Credential を使えるようになっています。</p>
<ul>
<li><a href="http://docs.aws.amazon.com/sdk-for-ruby/v2/developer-guide/">AWS SDK for Ruby</a></li>
</ul>
<h2>終わりに</h2>
<p>とりあえず、公開してみましたが荒削りなところも多いので今後はドキュメントを整えたりHTML, CSSテンプレートを追加したりと改善していこうと思います。何か問題があれば issue やコメントで指摘してもらえると幸いです。</p>
[Font Awesome][Gulp][Sass] gulp-sass で Font Awesome を導入する方法(Bourbon, Neat 対応)
https://whiskers.nukos.kitchen/2016/11/01/middleman-external-pipeline-font-awesome.html
2016-11-01T03:00:00Z
2017-03-29T03:20:11+00:00
nukos
<h2>はじめに</h2>
<p>Middleman 4 の External Pipeline で Gulp を使い、 gulp-sass で Sass をプリコンパイルしている場合の Font Awesome の導入方法についてメモを残しておきます。</p>
<h2>node-font-awesome を使う</h2>
<p>npm の <a href="https://www.npmjs.com/package/font-awesome">font-awesome</a> パッケージを単体で使おうと思うと <code>includePath</code> の指定が面倒だったりするので、そこを補ってくれる <a href="https://www.npmjs.com/package/node-font-awesome">node-font-awesome</a> を使います。</p>
<h3>node-bourbon...</h3>
<h2>はじめに</h2>
<p>Middleman 4 の External Pipeline で Gulp を使い、 gulp-sass で Sass をプリコンパイルしている場合の Font Awesome の導入方法についてメモを残しておきます。</p>
<h2>node-font-awesome を使う</h2>
<p>npm の <a href="https://www.npmjs.com/package/font-awesome">font-awesome</a> パッケージを単体で使おうと思うと <code>includePath</code> の指定が面倒だったりするので、そこを補ってくれる <a href="https://www.npmjs.com/package/node-font-awesome">node-font-awesome</a> を使います。</p>
<h3>node-bourbon や node-neat を使っている場合</h3>
<p>node-bourbon や node-neat を併用している場合、各パッケージが返すパスを予め連結してやる必要があります。各パッケージが返すパスは以下の通りです。</p>
<pre class="highlight javascript"><code><span class="kd">var</span> <span class="nx">bourbon</span> <span class="o">=</span> <span class="nx">require</span><span class="p">(</span><span class="s1">'node-bourbon'</span><span class="p">);</span>
<span class="nx">console</span><span class="p">.</span><span class="nx">log</span><span class="p">(</span><span class="nx">bourbon</span><span class="p">.</span><span class="nx">includePaths</span><span class="p">);</span>
<span class="c1">//[ '/Users/rin/Projects/middleman-tail/node_modules/bourbon/app/assets/stylesheets' ]</span>
</code></pre><pre class="highlight javascript"><code><span class="kd">var</span> <span class="nx">neat</span> <span class="o">=</span> <span class="nx">require</span><span class="p">(</span><span class="s1">'node-neat'</span><span class="p">);</span>
<span class="nx">console</span><span class="p">.</span><span class="nx">log</span><span class="p">(</span><span class="nx">neat</span><span class="p">.</span><span class="nx">includePaths</span><span class="p">);</span>
<span class="c1">//[ [ '/Users/rin/Projects/middleman-tail/node_modules/bourbon/app/assets/stylesheets' ],</span>
<span class="c1">// '/Users/rin/Projects/middleman-tail/node_modules/bourbon-neat/app/assets/stylesheets' ]</span>
</code></pre>
<p>見て分かる通り、<code>neat.includePaths</code> には bourbon のパスも含まれています。gulp-sass の <code>includePaths</code> に配列を指定することはできますが、<code>neat.includePaths</code> はすでに配列のため、<code>neat.includePaths</code> と node-font-awesome のパス(<code>fontAwesome.scssPath</code>)を連結してやる必要があります。</p>
<pre class="highlight javascript"><code><span class="kd">var</span> <span class="nx">cssConf</span> <span class="o">=</span> <span class="p">{</span>
<span class="na">includePaths</span><span class="p">:</span> <span class="nb">Array</span><span class="p">.</span><span class="nx">prototype</span><span class="p">.</span><span class="nx">concat</span><span class="p">(</span> <span class="nx">neat</span><span class="p">.</span><span class="nx">includePaths</span><span class="p">,</span> <span class="nx">fontAwesome</span><span class="p">.</span><span class="nx">scssPath</span> <span class="p">)</span>
<span class="p">}</span>
</code></pre>
<h3>フォントファイルをコピーする</h3>
<p>node-font-awesome はフォントファイルのパスを返してくれるのでそれを使ってコピーするタスクを用意します。</p>
<pre class="highlight javascript"><code><span class="kd">var</span> <span class="nx">fontConf</span> <span class="o">=</span> <span class="p">{</span>
<span class="na">destPath</span><span class="p">:</span> <span class="s1">'.tmp/dest/assets/fonts'</span>
<span class="p">}</span>
<span class="nx">gulp</span><span class="p">.</span><span class="nx">task</span><span class="p">(</span><span class="s1">'fonts'</span><span class="p">,</span> <span class="nx">copyFontAwesomeFonts</span><span class="p">);</span>
<span class="kd">function</span> <span class="nx">copyFontAwesomeFonts</span><span class="p">(){</span>
<span class="nx">gulp</span><span class="p">.</span><span class="nx">src</span><span class="p">(</span><span class="nx">fontAwesome</span><span class="p">.</span><span class="nx">fonts</span><span class="p">)</span>
<span class="p">.</span><span class="nx">pipe</span><span class="p">(</span><span class="nx">gulp</span><span class="p">.</span><span class="nx">dest</span><span class="p">(</span><span class="nx">fontConf</span><span class="p">.</span><span class="nx">destPath</span><span class="p">));</span>
<span class="p">}</span>
</code></pre>
<h3>作成したタスク</h3>
<pre class="highlight javascript"><code><span class="kd">var</span> <span class="nx">gulp</span> <span class="o">=</span> <span class="nx">require</span><span class="p">(</span><span class="s1">'gulp'</span><span class="p">);</span>
<span class="kd">var</span> <span class="nx">sass</span> <span class="o">=</span> <span class="nx">require</span><span class="p">(</span><span class="s1">'gulp-sass'</span><span class="p">);</span>
<span class="kd">var</span> <span class="nx">bourbon</span> <span class="o">=</span> <span class="nx">require</span><span class="p">(</span><span class="s1">'node-bourbon'</span><span class="p">);</span>
<span class="kd">var</span> <span class="nx">neat</span> <span class="o">=</span> <span class="nx">require</span><span class="p">(</span><span class="s1">'node-neat'</span><span class="p">);</span>
<span class="kd">var</span> <span class="nx">fontAwesome</span> <span class="o">=</span> <span class="nx">require</span><span class="p">(</span><span class="s1">'node-font-awesome'</span><span class="p">);</span>
<span class="kd">var</span> <span class="nx">cssConf</span> <span class="o">=</span> <span class="p">{</span>
<span class="na">srcPath</span><span class="p">:</span> <span class="s1">'source/assets/stylesheets/**/*.scss'</span><span class="p">,</span>
<span class="na">destPath</span><span class="p">:</span> <span class="s1">'.tmp/dest/assets/stylesheets'</span><span class="p">,</span>
<span class="na">includePaths</span><span class="p">:</span> <span class="nb">Array</span><span class="p">.</span><span class="nx">prototype</span><span class="p">.</span><span class="nx">concat</span><span class="p">(</span> <span class="nx">neat</span><span class="p">.</span><span class="nx">includePaths</span><span class="p">,</span> <span class="nx">fontAwesome</span><span class="p">.</span><span class="nx">scssPath</span> <span class="p">)</span>
<span class="p">}</span>
<span class="kd">var</span> <span class="nx">fontConf</span> <span class="o">=</span> <span class="p">{</span>
<span class="na">destPath</span><span class="p">:</span> <span class="s1">'.tmp/dest/assets/fonts'</span>
<span class="p">}</span>
<span class="nx">gulp</span><span class="p">.</span><span class="nx">task</span><span class="p">(</span><span class="s1">'fonts'</span><span class="p">,</span> <span class="nx">copyFontAwesomeFonts</span><span class="p">);</span>
<span class="nx">gulp</span><span class="p">.</span><span class="nx">task</span><span class="p">(</span><span class="s1">'sass'</span><span class="p">,</span> <span class="p">[</span><span class="s1">'fonts'</span><span class="p">],</span> <span class="nx">sassPreCompile</span><span class="p">);</span>
<span class="kd">function</span> <span class="nx">sassPreCompile</span><span class="p">(){</span>
<span class="nx">gulp</span><span class="p">.</span><span class="nx">src</span><span class="p">(</span><span class="nx">cssConf</span><span class="p">.</span><span class="nx">srcPath</span><span class="p">)</span>
<span class="p">.</span><span class="nx">pipe</span><span class="p">(</span><span class="nx">sass</span><span class="p">({</span>
<span class="na">includePaths</span><span class="p">:</span> <span class="nx">cssConf</span><span class="p">.</span><span class="nx">includePaths</span>
<span class="p">}))</span>
<span class="p">.</span><span class="nx">pipe</span><span class="p">(</span><span class="nx">gulp</span><span class="p">.</span><span class="nx">dest</span><span class="p">(</span><span class="nx">cssConf</span><span class="p">.</span><span class="nx">destPath</span><span class="p">));</span>
<span class="p">}</span>
<span class="kd">function</span> <span class="nx">copyFontAwesomeFonts</span><span class="p">(){</span>
<span class="nx">gulp</span><span class="p">.</span><span class="nx">src</span><span class="p">(</span><span class="nx">fontAwesome</span><span class="p">.</span><span class="nx">fonts</span><span class="p">)</span>
<span class="p">.</span><span class="nx">pipe</span><span class="p">(</span><span class="nx">gulp</span><span class="p">.</span><span class="nx">dest</span><span class="p">(</span><span class="nx">fontConf</span><span class="p">.</span><span class="nx">destPath</span><span class="p">));</span>
<span class="p">}</span>
</code></pre>
<h3>SCSS へのインポート</h3>
<p>あとは SCSS ファイルに <code>@import</code> するだけです。コピー先のディレクトリ名を <code>fonts</code> にしているので <code>$fa-font-path</code> だけ書き換えてやります。</p>
<pre class="highlight scss"><code><span class="c1">// font awesome
</span><span class="nv">$fa-font-path</span><span class="p">:</span> <span class="s2">"../fonts"</span><span class="p">;</span>
<span class="k">@import</span> <span class="s1">'font-awesome'</span><span class="p">;</span>
</code></pre>
<h2>終わりに</h2>
<p>これで Font Awesome が使えるようになりました。Middleman 4 の External Pipeline でも問題無く利用でき、フォントファイルに対しても asset_hash を使ったキャッシュコントロールが可能です。</p>