karma+webpack+babel+mocha+power-assert の設定

テストランナーとして [karma](http://karma-runner.github.io/0.13/index.html)（実行環境は [Chrome](https://github.com/karma-runner/karma-chrome-launcher)）、モジュール管理は [webpack](https://webpack.github.io/)、トランスパイラは [Babel](https://babeljs.io/)、テストフレームワークに [mocha](https://mochajs.org/)、アサーションライブラリは [power-assert](https://github.com/power-assert-js/power-assert) を使った設定になります。

webpackの代わりにbrowserifyを使った[設定例](https://gist.github.com/koba04/7a18677b583e1ec43fca)や、karma以外のテストランナーの設定例、power-assertの代わりにchaiを使った[設定例](http://qiita.com/sabakaido/items/f6b03f66cfb37f9b79a6)は見つかったのですが、上記組み合わせがなかったので参考になれば幸いです。

## 最終的な設定はこちら

```karma.conf.js
module.exports = function(config) {
  config.set({
    basePath: '',
    frameworks: ['mocha'],
    files: [
      'path/to/tests/**/*.js'
    ],
    exclude: [],
    plugins: [
      'karma-chrome-launcher',
      'karma-mocha',
      'karma-webpack'
    ],
    preprocessors: {
      'path/to/tests/**/*.js': ['webpack']
    },
    webpack: {
      devtool: 'inline-source-map',
      module: {
        loaders: [
          {
            test: /\.js$/,
            loader: 'babel',
            exclude: /node_modules/,
            query: {
              presets: ['react', 'es2015', 'stage-2'],
              plugins: ['babel-plugin-espower']
            }
          },
          {
            test: /\.json$/,
            loader: 'json'
          }
        ]
      },
      node: {
        fs: 'empty'
      }
    },
    browsers: ['Chrome'],
    singleRun: false
  });
};
```

一部設定を削ったりしているので `package.json` を含めた全体の設定を見たい人は[こちらのリポジトリ](https://github.com/kuy/redux-tooltip)をのぞいてみてください。
以下、実際に表示されたエラーと経緯です。

## 最初の設定

```karma.conf.js
module.exports = function(config) {
  config.set({
    basePath: '',
    frameworks: ['mocha'],
    files: [
      'path/to/tests/**/*.js'
    ],
    exclude: [],
    plugins: [
      'karma-chrome-launcher',
      'karma-mocha',
      'karma-webpack'
    ],
    preprocessors: {
      'path/to/tests/**/*.js': ['webpack']
    },
    webpack: {
      devtool: 'inline-source-map',
      module: {
        loaders: [
          {
            test: /\.js$/,
            loader: 'babel',
            exclude: /node_modules/,
            query: {
              presets: ['react', 'es2015', 'stage-2'],
              plugins: ['babel-plugin-espower']
            }
          }
        ]
      }
    },
    browsers: ['Chrome'],
    singleRun: false
  });
};
```

## 謎のエラー

以下のようなエラーが出てきて意味不明で困りました。

```
  [684] ./~/redux-actions/lib/ownKeys.js 453 bytes {0} [built]
  [685] ./~/redux-actions/~/reduce-reducers/lib/index.js 419 bytes {0} [built]
  [686] ./src/reducer.js 2.67 kB {0} [built]
  [687] ./src/middleware.js 1.1 kB {0} [built]

WARNING in ./~/power-assert/~/power-assert-formatter/lib/create.js
Critical dependencies:
35:28-49 the request of a dependency is an expression
 @ ./~/power-assert/~/power-assert-formatter/lib/create.js 35:28-49

WARNING in ./~/power-assert/~/power-assert-formatter/~/acorn/dist/acorn.js
Critical dependencies:
1:478-485 This seems to be a pre-built javascript file. Though this is possible, it's not recommended. Try to require the original source to get better results.
 @ ./~/power-assert/~/power-assert-formatter/~/acorn/dist/acorn.js 1:478-485

ERROR in ./~/cssstyle/lib/CSSStyleDeclaration.js
Module not found: Error: Cannot resolve module 'fs' in /Users/kodama/Work/redux-tooltip/node_modules/cssstyle/lib
 @ ./~/cssstyle/lib/CSSStyleDeclaration.js 7:9-22

ERROR in ./~/power-assert/~/power-assert-formatter/~/estraverse/estraverse.js
Module not found: Error: Cannot resolve module 'json' in /Users/kodama/Work/redux-tooltip/node_modules/power-assert/node_modules/power-assert-formatter/node_modules/estraverse
 @ ./~/power-assert/~/power-assert-formatter/~/estraverse/estraverse.js 831:22-47

ERROR in ./~/power-assert/~/empower/~/escallmatch/~/estraverse/estraverse.js
Module not found: Error: Cannot resolve module 'json' in /Users/kodama/Work/redux-tooltip/node_modules/power-assert/node_modules/empower/node_modules/escallmatch/node_modules/estraverse
 @ ./~/power-assert/~/empower/~/escallmatch/~/estraverse/estraverse.js 831:22-47
webpack: bundle is now VALID.
05 01 2016 14:14:26.656:WARN [karma]: No captured browser, open http://localhost:9876/
05 01 2016 14:14:26.664:INFO [karma]: Karma v0.13.18 server started at http://localhost:9876/
05 01 2016 14:14:26.703:INFO [launcher]: Starting browser Chrome
05 01 2016 14:14:28.181:INFO [Chrome 47.0.2526 (Mac OS X 10.11.2)]: Connected on socket yHM_-NlQUabzaxrZAAAA with id 97862818
Chrome 47.0.2526 (Mac OS X 10.11.2) ERROR
  Uncaught Error: Cannot find module "./package.json"
  at /Users/kodama/Work/redux-tooltip/test/features/tooltip.js:8426
```

## ヒントをもらう

あきらめてbrowserifyを使った構成にしてしのいだのですが、リプライをいただきました。

<blockquote class="twitter-tweet" data-partner="tweetdeck"><p lang="ja" dir="ltr"><a href="https://twitter.com/kuy">@kuy</a> この問題かもしれません <a href="https://t.co/ir0mZmgRbR">https://t.co/ir0mZmgRbR</a></p>&mdash; Takuto Wada (@t_wada) <a href="https://twitter.com/t_wada/status/684228193281150977">January 5, 2016</a></blockquote>
<script async src="//platform.twitter.com/widgets.js" charset="utf-8"></script>

@t_wada さんありがとうございます！

## 教えに従ってJSONローダーを追加

karmaの設定を変更して、`json-loader`を`package.json`に追加しました。
これでJSON関連のエラーは消えました。が、`fs`モジュールがないというエラーが出ています。

```
  [686] ./~/redux-actions/lib/ownKeys.js 453 bytes {0} [built]
  [687] ./~/redux-actions/~/reduce-reducers/lib/index.js 419 bytes {0} [built]
  [688] ./src/reducer.js 2.67 kB {0} [built]
  [689] ./src/middleware.js 1.1 kB {0} [built]

WARNING in ./~/power-assert/~/power-assert-formatter/lib/create.js
Critical dependencies:
35:28-49 the request of a dependency is an expression
 @ ./~/power-assert/~/power-assert-formatter/lib/create.js 35:28-49

WARNING in ./~/power-assert/~/power-assert-formatter/~/acorn/dist/acorn.js
Critical dependencies:
1:478-485 This seems to be a pre-built javascript file. Though this is possible, it's not recommended. Try to require the original source to get better results.
 @ ./~/power-assert/~/power-assert-formatter/~/acorn/dist/acorn.js 1:478-485

ERROR in ./~/cssstyle/lib/CSSStyleDeclaration.js
Module not found: Error: Cannot resolve module 'fs' in /Users/kodama/Work/redux-tooltip/node_modules/cssstyle/lib
 @ ./~/cssstyle/lib/CSSStyleDeclaration.js 7:9-22
webpack: bundle is now VALID.
05 01 2016 14:26:29.688:WARN [karma]: No captured browser, open http://localhost:9876/
05 01 2016 14:26:29.697:INFO [karma]: Karma v0.13.18 server started at http://localhost:9876/
05 01 2016 14:26:29.735:INFO [launcher]: Starting browser Chrome
05 01 2016 14:26:30.895:INFO [Chrome 47.0.2526 (Mac OS X 10.11.2)]: Connected on socket D3hhFiMr_HoktVxDAAAA with id 82912336
Chrome 47.0.2526 (Mac OS X 10.11.2) ERROR
  Uncaught Error: Cannot find module "fs"
  at /Users/kodama/Work/redux-tooltip/test/features/tooltip.js:19229
```


## 似たような症状を発見

[Cannot resolve module 'fs' #8](https://github.com/webpack/jade-loader/issues/8#issuecomment-55568520)

![Screen Shot 0028-01-05 at 15.11.07.png](https://qiita-image-store.s3.amazonaws.com/0/69860/8f11f96c-3440-f095-c850-19d56683a48e.png)

なぜだかよくわからないけど以下を追加すると直りました。

```webpack.config.js
node: {
  fs: 'empty'
}
```