Componentによるフロントエンドのパッケージ管理

Component

直近で、新規案件に関わることになりそうなので、ライブラリ選定やタスクランナー、そして今回の依存管理のようにベーシックな話が続いてます。次第に、具体的な実装やコード設計のポストが多くなる・・・はず。

今回はVue.jsでも触れましたが、改めてcomponent - modular javascript frameworkについて。

概要

Componentはパッケージマネージャー兼、依存解決込みのビルドツールです。クライアントサイドについて、JSのパッケージマネージャーやビルダーは既にありますが、Componentは HTML/CSS/JSをセットにして扱うことができます。

npmでいうpackage.jsonと同様に、component.jsonという定義ファイルによって、パッケージの依存関係やリポジトリなどの各種情報を示します。

ごくごく基本

% npm install -g component

bower等と同じく、グローバルにユーティリティをインストールするようにして扱います。

% component create
repo (username/project): ahomu/demo-component
description:
does this component have js? y
does this component have css? y
does this component have html? y

      create : .
      create : index.js
      create : template.html
      create : demo-component.css
      create : Makefile
      create : Readme.md
      create : History.md
      create : .gitignore
      create : component.json

component createでスケルトンを作成します。

% component install yyx990803/vue

     install : yyx990803/vue@master
    complete : yyx990803/vue

ここではyyx990803/vueをインストールしていて、./components 以下にパッケージが展開されます。

% cat component.json
{
  "name": "demo-component",
  "repo": "ahomu/demo-component",
  "description": "",
  "version": "0.0.1",
  "keywords": [],
  "dependencies": {
    "yyx990803/vue": "*"
  },
  "development": {},
  "license": "MIT",
  "main": "index.js",
  "scripts": [
    "index.js",
    "template.js"
  ],
  "styles": [
    "demo-component.css"
  ]
}

skeleton作成時に生成されたcomponent.jsonに、installしたときdependenciesが自動で追加されています。

var Vue = require('vue')

コード内では、インストールされたパッケージとしてCommonJSスタイルな require で呼び出すことができます。

% component build

./components下に展開されているモジュールも含めて build/build.jsbuild/build.css が生成されます。

HTML/CSS/JSをセットでパッケージ化

skeleton作成時の質問からも分かるとおり、componentが扱うパッケージの中にはJSだけでなくCSSやHTMLも含まれて管理されるようになっています。例えば component/tip を見ると、HTML/CSS/JSのセットが1つのパッケージとして管理されていて、これも component install component/tip とすることでまとめてインストールされるイメージになります。

致命的なググらびりてぃ

Component ・・・(;´Д`)

何がしたいかというと

  • HTML/CSS/JSをセットで、1つのパッケージ(コンポーネント)としたい

という気持ちをベースに、それこそが再利用可能なパーツであってほしいと考えています。そのためにはCSSにも依存管理が必要で、またそのコンポーネントが実装されうるHTMLも添付できると理想的。

実際には、Componentは必ずしもCSSやHTMLをセットで管理することを強制はしないので、他と同様にJSだけをコンポーネント化して、パッケージ管理&依存解決ビルドするように使うだけでも有用なツールだと考えています。

現実的には完全にグローバルで、プロジェクトを超えて再利用可能なパーツというのは、そうそう存在しないと考えています。どちらかといえば、localで定義されるようなプロジェクトローカルに再利用可能なパーツを、HTML/CSS/JSをセットにした適切な粒度のコンポーネントとして開発するワークフローにして、それらを管理するためのツールとしてComponentを積極的に利用したい、というイメージです。

実際のプロジェクト利用イメージやサンプルとしては、下記のリポジトリが参考になりそうです。

悔しいことに、AngularのElement Directiveとかこの辺りの発想と相性良さそうな気がしてます。Angular Best Practice for App Structure (Public)みたいなドキュメントを見る限りでも近い。

他のフロントエンドのパッケージ管理と依存管理

フロントエンドのパッケージ・依存の管理ツールはいくつか存在していますが、下記の有名所3つに対しては次のような気持ちを抱いています。

Bower

  • .bowerrc と bower.json のダブル管理つらい
  • 実行時(≒ビルド時)の依存解決をサポートしてくれない
  • bower install してから、また別のツールで解決するのか!

yeoman/bower-requirejs のようなものを挟めば、bowerからrequirejsのconfigに落とし込むのはサポートされるようですが…

RequireJS

  • AMD周りの記法がイマイチ
  • configやらshimやらが結局煩わしい
  • どの規模からRequireJSで管理すべきサイズなのだろうか...

square/es6-module-transpiler とか使うとES6の記法でAMDやCommonJSのsyntaxで出力できたりもしますが...

Browserify

(たまたま見つけたtweetなのですが)

Browserifyにとって、CSSについては関心の外にあるため、HTML/CSS/JSをセットでコンポーネント化したいという自分のニーズからは外れてしまいます。(JSに限って言えばbrowserifyは満足できる気がする)

Client-Side JavaScript Management, Browserify vs Component とかも参考になる話なのかもしれない。Substack vs TJ Holowaychuk って感じだけど。

これからに期待

ちなみによく使うメジャーライブラリのサポート状況は...というと、今の時点でBackboneやUnderscore, Lo-Dashあたりはcomponent.jsonをサポートしています。Vue.jsもそうです。

AngularJSはもちろんサポートしてくれていませんが、componentizrのようなプロジェクトがホストしていたりするので、何とかなるように思います。

一部の諸兄にとっては visionmedia師の持続可能性について懸念が残ることもあるかもしれませんが、Componentは1年以上前からメンテされ続けていますし、OrganizationのMembersも沢山居るので、何となく安心できます。何となく。

総じて、まだまだ国内においてマイナーなツールという扱いではありますが、海外の有名OSSがComponentのことを無視していない、GitHubのStarも2,700超と非常に強い関心が集まっていることが分かります。

そんな流れで、これからワンチャンあるんじゃないかと、期待してやみません。ではでは。