@ledsun blog

無味の味は佳境に入らざればすなわち知れず

component.js(1.0.0-rc5)を試す

component.js

component.jsはnpmやbowerを使った依存する外部ライブラリ(JavaScript,CSSともを含む)の解決と、 unglifyやcssminで行う自作ファイルを適切に組み合わせるビルドを1つのツールでやってしまおうとする 意欲的なツールです。

Getting Started

使用感はGetting Startedを眺めてもらうのが 分かりやすいです*1

流れ

component jsを試してみた。 - 日頃の行いと大体一緒です。 たまたまバグを踏んだので、その部分を補足します。

  1. npmでinstall
  2. githubの設定
  3. index.html,css,jsとcomponent.jsonの記述
  4. component buildの実行

install

npm install -g component@1.0.0-rc5

1.0.0はstableではありません。バージョンを指定しないと0.19.9が入ります。 結構大きいです。

github APIの設定

component1.0.0github APIを使って依存ライブラリを取得します。 github APIの設定が必要です。

https://github.com/settings/applications#personal-access-tokens にてアクセストークンを作成します。 権限はrepoとuserだけで動きました。もっと減らせるかもしれません。

アクセストークンの動作確認

curl -u <token>:x-oauth-basic https://api.github.com/user

.netrcにトークンを追記

machine api.github.com
  login <token>
  password x-oauth-basic

ファイルを準備

index.html

<!DOCTYPE html>
<html>
  <head>
    <title>Getting Started with Component</title>
    <link rel="stylesheet" href="build/build.css">
  </head>
  <body>
    <h1>Getting Started with Component</h1>
    <p class="blink">Woo!</p>
    <script src="build/build.js"></script>
  </body>
</html>

index.js

var blink = document.querySelector('.blink');

setInterval(function () {
  blink.style.visibility = getComputedStyle(blink).visibility === 'hidden'
    ? 'visible'
    : 'hidden';
}, 30

index.css

* {
  box-sizing: border-box;
}

component.json

{
  "name": "getting-started-with-component",
  "dependencies": {
    "necolas/normalize.css": "^3.0.0"
  },
  "scripts": ["index.js"],
  "styles": ["index.css"]
}

実行

component buildコマンドで依存ライブラリの取得とビルドが走るはずですが・・・

component build
   installed : necolas/normalize.css@3.0.1 in 1148ms
       build : resolved in 4903ms
       build : files in 7ms
       build : build/build.js in 9ms - 1kb

       error : Cannot call method 'process' of undefined

期待しないエラーが表示されます*2。 しかしエラーの詳細が分かりません。

こういう場合は、component guideにあたります。 Trouble shooting に従いDEBUG変数を指定して再度実行します。

DEBUG=component* component build
  component-resolver remote not set - defaulting to remotes's defaults +0ms
  component-resolver:locals resolving local at "/Users/ledsun/SandBox/JavaScript/component" +6ms
  component-resolver resolving "getting-started-with-component" +4ms
  component-resolver remaining dependencies: 1 +4ms
  component-resolver remaining semver: 0 +0ms
  component-resolver finished resolving locals +0ms
  component-resolver finished resolving dependencies (1) +0ms
  component-resolver:semver resolving semver necolas/normalize.css@^3.0.0 +1ms
  component-resolver:dependencies resolving dependency necolas/normalize.css@3.0.1 +2ms
  component-resolver:dependencies searching ["local","github","bitbucket"] for necolas/normalize.css@3.0.1 +1ms
  component-resolver:dependencies found necolas/normalize.css@3.0.1 from remote "local" +1ms
  component-resolver resolving "necolas/normalize.css" +0ms
  component-resolver remaining dependencies: 0 +0ms
  component-resolver remaining semver: 1 +1ms
  component-resolver:semver resolved semver necolas/normalize.css@^3.0.0 -> necolas/normalize.css@3.0.1 +0ms
  component-resolver finished resolving semver +0ms
  component-resolver finished resolving dependencies(2) +1ms
  component-downloader "/Users/shigerunakajima/SandBox/JavaScript/component/components/necolas/normalize.css/3.0.1" exists, skipping downloading. +0ms
  component-resolver finished installing dependencies +0ms
       build : resolved in 22ms
       build : files in 6ms
       build : build/build.js in 9ms - 1kb
  component-consoler TypeError: Cannot call method 'process' of undefined
    at /usr/local/lib/node_modules/component/node_modules/component-build/node_modules/builder-autoprefixer/index.js:21:49
    at Object.read (/usr/local/lib/node_modules/component/node_modules/component-build/node_modules/component-builder/node_modules/component-manifest/build/index.js:436:49)
    at Styles.autoprefixer (/usr/local/lib/node_modules/component/node_modules/component-build/node_modules/builder-autoprefixer/index.js:16:10)
    at next (/usr/local/lib/node_modules/component/node_modules/co/index.js:99:21)
    at /usr/local/lib/node_modules/component/node_modules/co/index.js:102:18
    at /usr/local/lib/node_modules/component/node_modules/component-build/node_modules/component-builder/build/plugins/url-rewriter.js:438:7
    at /usr/local/lib/node_modules/component/node_modules/component-build/node_modules/component-builder/node_modules/component-manifest/build/index.js:446:7
    at fs.js:266:14
    at /usr/local/lib/node_modules/component/node_modules/component-build/node_modules/component-builder/node_modules/graceful-fs/graceful-fs.js:104:5
    at /usr/local/lib/node_modules/component/node_modules/component-resolver/node_modules/graceful-fs/graceful-fs.js:104:5 +12ms

       error : Cannot call method 'process' of undefined

/usr/local/lib/node_modules/component/node_modules/component-build/node_modules/builder-autoprefixer/index.js:21:49 で、例外が起きているのが分かります。

このファイルを見るとauto変数が初期化されていないのが原因ぽい。 builder-autoprefixerコミットログを見るとそれっぽい修正が入っています。 直すと・・・

component build                                                                                              (git)-[master]
       build : resolved in 17ms
       build : files in 66ms
       build : build/build.js in 69ms - 1kb
       build : build/build.css in 69ms - 7kb

無事ビルドが通りました。パチパチ。

結果

build.js

/**
 * Require the module at `name`.
 *
 * @param {String} name
 * @return {Object} exports
 * @api public
 */

function require(name) {
  var module = require.modules[name];
  if (!module) throw new Error('failed to require "' + name + '"');

  if (!('exports' in module) && typeof module.definition === 'function') {
    module.client = module.component = true;
    module.definition.call(this, module.exports = {}, module);
    delete module.definition;
  }

  return module.exports;
}

/**
 * Registered modules.
 */

require.modules = {};

/**
 * Register module at `name` with callback `definition`.
 *
 * @param {String} name
 * @param {Function} definition
 * @api private
 */

require.register = function (name, definition) {
  require.modules[name] = {
    definition: definition
  };
};

/**
 * Define a module's exports immediately with `exports`.
 *
 * @param {String} name
 * @param {Generic} exports
 * @api private
 */

require.define = function (name, exports) {
  require.modules[name] = {
    exports: exports
  };
};
require.register("getting-started-with-component", function (exports, module) {
var blink = document.querySelector('.blink');

setInterval(function () {
  blink.style.visibility = getComputedStyle(blink).visibility === 'hidden'    ? 'visible'
    : 'hidden';
}, 300);

});

require("getting-started-with-component")

require関数の定義が追加されています。

build.css

抜粋。外部ライブラリのcssファイルと結合された上で、こんな感じでベンダープレフィックスが追加されます。

/**
 * Address differences between Firefox and other browsers.
 */

hr {
  -moz-box-sizing: content-box;
  -webkit-box-sizing: content-box;
  box-sizing: content-box;
  height: 0;
}

元のファイル

/**
 * Address differences between Firefox and other browsers.
 */

hr {
  -moz-box-sizing: content-box;
  box-sizing: content-box;
  height: 0;
}

*1:このリポジトリには他にも参考になる文章がたくさんあるので困ったときに見ると解決策が見つかります

*2:修正済みのbuilder-autoprefixer 1.0.2がリリースされています。今はこのエラーは起きません