Repository: vuejs/vue-loader
Pull request #664 (2017-02-21 09:35:21)

feat: Call custom block loaders with `Component` as argument
I love the idea of single file vue components and of being able to add custom blocks such as `<docs>`. Although it is possible to pass arguments to the loader via attributes on the custom block tag, you cannot access the `Component` from inside the loader. I needed that functionality to achieve the following. 

1. Have a `<docs>` tag in the .vue file 
2. Have the contents of said tag inserted into the resulting Component as `options._docs` so that it would be accessible during runtime. 

A very simple custom loader for this task could, for example, look like this: 

```javascript
module.exports = function (source, map) {
  this.callback(null, 'module.exports = function(Component) {Component.options._docs = ' +
    JSON.stringify(source) +
    '}', map)
}
```

So I changed the call of the customBlock to include `Component`, if the result of the `require` is a function. I'm not sure if this would break any existing workflows. 

If you think this use case is worth considering I'd be happy to supply the corresponding unit tests and docs.

yyx990803: Neat idea, mind adding a test case for this?
hauptbenutzer: Sure thing! I've added some example docs as well.
egoist: /cc @yyx990803 

Patch:
diff --git a/docs/LANGS.md b/docs/LANGS.md
index da850e1..4e23e55 100644
--- a/docs/LANGS.md
+++ b/docs/LANGS.md
@@ -1,4 +1,5 @@
 * [English](en/)
 * [한국어](kr/)
 * [Русский](ru/)
-* [Português](pt_BR/)
\ No newline at end of file
+* [Português](pt_BR/)
+* [日本語](ja/)
diff --git a/docs/en/configurations/advanced.md b/docs/en/configurations/advanced.md
index 5c48d64..17aa63d 100644
--- a/docs/en/configurations/advanced.md
+++ b/docs/en/configurations/advanced.md
@@ -48,7 +48,10 @@ module.exports = {
           //   plugin will be a better option.
           postLoaders: {
             html: 'babel-loader'
-          }
+          },
+          
+          // `excludedPreLoaders` should be regex
+          excludedPreLoaders: /(eslint-loader)/
         }
       }
     ]
diff --git a/docs/en/configurations/custom-blocks.md b/docs/en/configurations/custom-blocks.md
index ce833e0..434f268 100644
--- a/docs/en/configurations/custom-blocks.md
+++ b/docs/en/configurations/custom-blocks.md
@@ -4,9 +4,9 @@
 
 You can define custom language blocks inside `*.vue` files. The content of a custom block will be processed by the loaders specified in the `loaders` object of `vue-loader` options and then required by the component module. The configuration is similar to what is described in [Advanced Loader Configuration](../configurations/advanced.md), except the matching uses the tag name instead of the `lang` attribute.
 
-If a matching loader is found for a custom block, it will be processed; otherwise the custom block will simply be ignored.
+If a matching loader is found for a custom block, it will be processed; otherwise the custom block will simply be ignored. Additionally, if the found loader returns a function, that function will be called with the component of the `*.vue` file as a parameter. 
 
-## Example
+## Single docs file example
 
 Here's an example of extracting all `<docs>` custom blocks into a single docs file:
 
@@ -65,3 +65,69 @@ module.exports = {
   ]
 }
 ```
+
+## Runtime available docs
+
+Here's an example of injecting the `<docs>` custom blocks into the component so that it's available during runtime.
+
+#### docs-loader.js 
+
+In order for the custom block content to be injected, we'll need a custom loader: 
+
+``` js
+module.exports = function (source, map) {
+  this.callback(null, 'module.exports = function(Component) {Component.options.__docs = ' +
+    JSON.stringify(source) +
+    '}', map)
+}
+```
+
+#### webpack.config.js
+
+Now we'll configure webpack to use our custom loader for `<docs>` custom blocks.
+
+``` js
+const docsLoader = require.resolve('./custom-loaders/docs-loader.js')
+
+module.exports = {
+  module: {
+    rules: [
+      {
+        test: /\.vue$/,
+        loader: 'vue',
+        options: {
+          loaders: {
+            'docs': docsLoader
+          }
+        }
+      }
+    ]
+  }
+}
+```
+
+#### component.vue
+
+We are now able to access the `<docs>` block's content of imported components during runtime. 
+
+``` html
+<template>
+  <div>
+    <component-b \>
+    <p>{{ docs }}</p>
+  </div>
+</template>
+
+<script>
+import componentB from 'componentB';
+
+export default = {
+  data () {
+    return {
+      docs: componentB.__docs
+    }
+  },
+  components: {componentB}
+}
+</script>
+```
diff --git a/docs/ja/README.md b/docs/ja/README.md
new file mode 100644
index 0000000..c80aa40
--- /dev/null
+++ b/docs/ja/README.md
@@ -0,0 +1,38 @@
+# はじめに
+
+### `vue-loader` とは ?
+
+`vue-loader` とは以下の形式で記述された Vue コンポーネントをプレーンな JavaScript モジュールに変換する Webpack の loader です。
+
+![screenshot](http://blog.evanyou.me/images/vue-component.png)
+
+`vue-loader` によって多くのクールな機能が提供されます：
+
+- デフォルトで ES2015 が有効；
+- `<style>` には SASS、 `<template>` には Jade など、Vue コンポーネントの各パーツに他の Webpack の loader が使用可能；
+ カスタム loader チェーンを適用できる .vue ファイルのカスタムセクションを追加可能；
+- `<style>` と `<template>` で参照される静的なアセットをモジュールの依存として扱い、Webpack の loader で処理可能；
+- 各コンポーネントで scoped CSS をシミュレートすることが可能；
+- 開発時のコンポーネントのホットリロードをサポート
+
+つまり、Webpack と `vue-loader` の組み合わせは Vue.js アプリケーションを作成するための、現代的で柔軟かつとても強力なフロントエンドワークフローを実現することが可能になります。
+
+### Webpack とは?
+
+すでに Webpack に精通している場合は、次の説明を省略してもかまいません。しかし、Webpack を初めて使う人のために、ここで簡単な紹介を行います。
+
+[Webpack](http://webpack.github.io/) とはモジュールのバンドラーです。それぞれのファイルをモジュールとして扱い、それらの間の依存関係を解決し、デプロイの準備が整った静的アセットにバンドルします。
+
+![webpack](http://webpack.github.io/assets/what-is-webpack.png)
+
+基本的な例として、CommonJS モジュールが多数あるとします。これらはブラウザで直接実行できません。なのでそれらを `<script>` タグを介して読み込むことのできる単一のファイルに "バンドル" する必要があります。Webpack は `require()` での依存性解決と実行を行うことが出来ます。
+
+しかし Webpack はそれ以上のことが出来ます。 "loader" を用いることで、最終的なバンドルしたファイルを出力する前に Webpack に様々な方法で全てのタイプのファイルを変換できるように設定することが出来ます。いくつかの例をあげると：
+
+- ES2015、CoffeeScript、TypeScript のモジュールをプレーンな ES5 の CommonJS モジュールにトランスパイル；
+- オプションでコンパイルを行う前にソースコードを linter に通すことが可能；
+- Jade テンプレートをプレーンな HTML にトランスパイルし、JavaScript の文字列として展開；
+- SASS ファイルをプレーンな CSS にトランスパイルし、`<style>` タグとして挿入する JavaScript スニペットに変換；
+- HTML または CSS で参照されるイメージファイルを処理し、パスの設定に基づいた目的の場所に移動し、md5 ハッシュを使用して名前付け；
+
+Webpack は非常に強力です。どのように動作するか理解すれば、フロントエンド開発のワークフローを劇的に向上させることが出来ます。欠点としては冗長で複雑な構成です。しかし、このガイドでは Vue.js と `vue-loader` での Webpack を使用する際に一般的な問題の解決策を見つけることができるはずです。
diff --git a/docs/ja/SUMMARY.md b/docs/ja/SUMMARY.md
new file mode 100644
index 0000000..f489b56
--- /dev/null
+++ b/docs/ja/SUMMARY.md
@@ -0,0 +1,21 @@
+- 入門
+  - [Vue Component の仕様](start/spec.md)
+  - [プロジェクトのセットアップ](start/setup.md)
+- 機能
+  - [ES2015](features/es2015.md)
+  - [スコープ付き CSS](features/scoped-css.md)
+  - [CSS モジュール](features/css-modules.md)
+  - [PostCSS](features/postcss.md)
+  - [ホットリロード](features/hot-reload.md)
+- 構成
+  - [プリプロセッサの使用](configurations/pre-processors.md)
+  - [アセット URL ハンドリング](configurations/asset-url.md)
+  - [高度な loader の設定](configurations/advanced.md)
+  - [CSS を単一のファイルに抽出する](configurations/extract-css.md)
+  - [カスタムブロック](configurations/custom-blocks.md)
+- ワークフロー
+  - [プロダクションビルド](workflow/production.md)
+  - [Linting](workflow/linting.md)
+  - [テスト](workflow/testing.md)
+  - [モックを使用したテスト](workflow/testing-with-mocks.md)
+- [オプションリファレンス](options.md)
diff --git a/docs/ja/configurations/advanced.md b/docs/ja/configurations/advanced.md
new file mode 100644
index 0000000..6778fcd
--- /dev/null
+++ b/docs/ja/configurations/advanced.md
@@ -0,0 +1,80 @@
+# 高度な loader の設定
+
+時折こうしたくなるかもしれません：
+
+1. `vue-loader` が推測するのではなく、カスタム loader の文字列を言語に適用する。
+2. デフォルトの言語の組み込み loader の設定の上書き。
+3. 特定の言語ブロックをカスタム loader で前処理か後処理をする。
+
+そうするためには、`vue-loader` に `loaders` オプションを指定してください：
+
+> メモ： `preLoaders` と `postLoaders` は 10.3.0 以上でのみサポートされます
+
+### Webpack 2.x
+
+``` js
+module.exports = {
+  // 他のオプション
+  module: {
+    // module.rules は 1.x での module.loaders と同じです
+    rules: [
+      {
+        test: /\.vue$/,
+        loader: 'vue-loader',
+        options: {
+          // `loaders` はデフォルトの loaderを上書きします。
+          // 次の設定では、"lang" 属性のない全ての <script> タグに
+          // coffee-loader が適用されます。
+          loaders: {
+            js: 'coffee-loader'
+          },
+
+          // `preLoaders` はデフォルトの loader の前に付加されます。
+          // これを使用して言語ブロックを前処理することができます。
+          // 一般的な使用例はビルドタイム i18n です。
+          preLoaders: {
+            js: '/path/to/custom/loader'
+          },
+
+          // `postLoaders` はデフォルトの loader の後につけられます。
+          //
+          // - `html` の場合、デフォルトの loader によって返される結果は、
+          //   コンパイルされた JavaScript レンダリング関数コードになります。
+          //
+          // - `css` の場合、結果は vue-style-loader によって返されます。
+          //   しかしこれはほとんどの場合特に有用ではありません。
+          //   postcss プラグインを使用する方が良い選択になります。
+          postLoaders: {
+            html: 'babel-loader'
+          }
+        }
+      }
+    ]
+  }
+}
+```
+
+### Webpack 1.x
+
+``` js
+// webpack.config.js
+module.exports = {
+  // ほかのオプション
+  module: {
+    loaders: [
+      {
+        test: /\.vue$/,
+        loader: 'vue'
+      }
+    ]
+  },
+  // vue-loader の設定
+  vue: {
+    loaders: {
+      // 上記の設定と同じ
+    }
+  }
+}
+```
+
+高度な loader の設定のより実用的な使用方法は、[CSS を単一のファイルに抽出する](./expression-css.md)にあります。
diff --git a/docs/ja/configurations/asset-url.md b/docs/ja/configurations/asset-url.md
new file mode 100644
index 0000000..7a06878
--- /dev/null
+++ b/docs/ja/configurations/asset-url.md
@@ -0,0 +1,22 @@
+# アセット URL ハンドリング
+
+デフォルトで `vue-loader` は [css-loader](https://github.com/webpack/css-loader) と Vue テンプレートコンパイラーでスタイルとテンプレートファイルは自動で処理されます。このコンパイル処理中で全ての `<img src="...">` 、`background: url(...)` や CSS の `@import` のようなアセットの URL は **モジュールの依存関係として処理されます**。
+
+例えば、`url(./image.png)` は `require('./image.png')` に変換され、そして
+
+``` html
+<img src="../image.png">
+```
+
+このようにコンパイルされます：
+
+``` js
+createElement('img', { attrs: { src: require('../image.png') }})
+```
+もちろん `.png` ファイルは JavaScript のファイルではありません。[file-loader](https://github.com/webpack/file-loader) または [url-loader](https://github.com/webpack/url-loader) を使用して Webpack を設定する必要があります。`vue-cli` でスキャフォールドされたプロジェクトでは同じような設定がなされています。
+
+利点の全ては次の通りです：
+
+1. `file-loader` はアセットファイルのコピー先や配置先を制定したり、バージョンハッシュを利用してキャッシングを改善する方法を指定する事が出来ます。さらに、これは、単に**あなたの `* .vue` ファイルの隣にイメージを置くことができ、配備するURLを心配するのではなくフォルダ構造に基づいて相対パスを使用する**ことを意味します。
+
+2. `url-loader` は、指定されたしきい値よりも小さい場合、条件付きでファイルを base-64 データ URL としてインライン化することができます。これにより、単純なファイルに対する HTTP リクエストの量を減らすことができます。 ファイルがしきい値より大きい場合、自動的に `file-loader` にフォールバックします。
diff --git a/docs/ja/configurations/custom-blocks.md b/docs/ja/configurations/custom-blocks.md
new file mode 100644
index 0000000..a9d41d0
--- /dev/null
+++ b/docs/ja/configurations/custom-blocks.md
@@ -0,0 +1,67 @@
+# カスタムブロック
+
+> 10.2.0 以上で動作します
+
+`*.vue` ファイル内にカスタム言語ブロックを定義することが出来ます。カスタムブロックの内容は `vue-loader` のオブジェクトで指定された loader によって処理され、次にコンポーネントモジュールによって要求されます。この設定は `lang` 属性の代わりにタグ名を使用する点をのぞいて[高度な loader の設定](../configurations/advanced.md)に記載されたものと似ています。
+
+もしカスタムブロックにマッチする loader を見つけたら、それは処理されます。でなければそのカスタムブロックは単に無視されます。
+
+## 例
+
+全ての `<docs>` カスタムブロックを一つのドキュメントファイルに展開する例を示します：
+
+#### component.vue
+
+``` html
+<docs>
+## これは example component です
+</docs>
+
+<template>
+  <h2 class="red">{{msg}}</h2>
+</template>
+
+<script>
+export default {
+  data () {
+    return {
+      msg: 'Hello from Component A!'
+    }
+  }
+}
+</script>
+
+<style>
+comp-a h2 {
+  color: #f00;
+}
+</style>
+```
+
+#### webpack.config.js
+
+``` js
+// Webpack 2.x
+var ExtractTextPlugin = require("extract-text-webpack-plugin")
+
+module.exports = {
+  module: {
+    rules: [
+      {
+        test: /\.vue$/,
+        loader: 'vue',
+        options: {
+          loaders: {
+            // 全ての <docs> の内容は raw text として展開されます
+            'docs': ExtractTextPlugin.extract('raw-loader'),
+          }
+        }
+      }
+    ]
+  },
+  plugins: [
+    // 全ての docs は一つのファイルに出力されます
+    new ExtractTextPlugin('docs.md')
+  ]
+}
+```
diff --git a/docs/ja/configurations/extract-css.md b/docs/ja/configurations/extract-css.md
new file mode 100644
index 0000000..3d31155
--- /dev/null
+++ b/docs/ja/configurations/extract-css.md
@@ -0,0 +1,70 @@
+# CSS を単一のファイルに抽出する
+
+すべての Vue コンポーネントで処理されたすべての CSS を1つの CSS ファイルに抽出する例：
+
+### Webpack 2.x
+
+``` bash
+npm install extract-text-webpack-plugin@2.x --save-dev
+```
+
+``` js
+// webpack.config.js
+var ExtractTextPlugin = require("extract-text-webpack-plugin")
+
+module.exports = {
+  // 他の設定
+  module: {
+    rules: [
+      {
+        test: /\.vue$/,
+        loader: 'vue-loader',
+        options: {
+          loaders: {
+            css: ExtractTextPlugin.extract({
+              use: 'css-loader',
+              fallback: 'vue-style-loader' // <- これは vue-loader の依存ですので、npm3 を使用している場合は明示的にインストールする必要はありません
+            })
+          }
+        }
+      }
+    ]
+  },
+  plugins: [
+    new ExtractTextPlugin("style.css")
+  ]
+}
+```
+
+### Webpack 1.x
+
+``` bash
+npm install extract-text-webpack-plugin --save-dev
+```
+
+``` js
+// webpack.config.js
+var ExtractTextPlugin = require("extract-text-webpack-plugin")
+
+module.exports = {
+  // 他の設定
+  module: {
+    loaders: [
+      {
+        test: /\.vue$/,
+        loader: 'vue'
+      },
+    ]
+  },
+  vue: {
+    loaders: {
+      css: ExtractTextPlugin.extract("css"),
+      // <style lang="less">　または他の言語も含めることができます
+      less: ExtractTextPlugin.extract("css!less")
+    }
+  },
+  plugins: [
+    new ExtractTextPlugin("style.css")
+  ]
+}
+```
diff --git a/docs/ja/configurations/pre-processors.md b/docs/ja/configurations/pre-processors.md
new file mode 100644
index 0000000..04576ad
--- /dev/null
+++ b/docs/ja/configurations/pre-processors.md
@@ -0,0 +1,81 @@
+# プリプロセッサの使用
+
+Webpack において、全てのプリプロセッサは対応する loader を適用する必要があります。 `vue-loader` は他の Webpack の loader を使って Vue コンポーネントを処理することが出来ます。言語ブロックの `lang` 属性から適切な loader を自動的に推論します。
+
+### CSS
+
+例えば、SASS で `<style>` タグをコンパイルしましょう：
+
+``` bash
+npm install sass-loader node-sass --save-dev
+```
+
+``` html
+<style lang="sass">
+  /* ここにSASSを書きます */
+</style>
+```
+
+ `<style>` タグ内のテキストコンテンツは、`sass-loader` によって最初にコンパイルされ、その後の処理のために渡されます。
+
+#### sass-loader 使用時の注意
+
+その名前が示すものとは対照的に、[* sass * -loader](https://github.com/jtangelder/sass-loader) はデフォルトで *SCSS* の構文を解析します。インデントされた *SASS* 構文を実際に使用する場合は、それに応じて sass-loader へ vue-loader のオプションを設定する必要があります。
+
+```javascript
+{
+  test: /\.vue$/,
+  loader: 'vue-loader',
+  options: {
+    loaders: {
+      scss: 'vue-style-loader!css-loader!sass-loader' // <style lang="scss">
+      sass: 'vue-style-loader!css-loader!sass-loader?indentedSyntax' // <style lang="sass">
+    }
+  }
+}
+```
+
+vue-loader を構成する方法の詳細については、[高度な loader の設定](./advanced.md)セクションを参照してください。
+
+### JavaScript
+
+全てのVueコンポーネントのJavaScriptはデフォルトで `babel-loader` によって処理されます。しかしもちろんそれは変更することが可能です：
+
+``` bash
+npm install coffee-loader --save-dev
+```
+
+``` html
+<script lang="coffee">
+  # coffeescript を書いてください!
+</script>
+```
+
+### テンプレート
+
+`pug-loader` のようなほとんどのWebpackテンプレート loader は、コンパイルされたHTML文字列の代わりにテンプレート関数を返すので、template の処理は少し異なります。`pug-loader` を使う代わりに、オリジナルの `pug` をインストールをするだけです：
+
+``` bash
+npm install pug --save-dev
+```
+
+``` html
+<template lang="pug">
+div
+  h1 Hello world!
+</template>
+```
+
+> **重要:** もし `vue-loader@<8.2.0` を使うのであれば、`template-html-loader` が必要になります。
+
+### インラインローダーリクエスト
+
+`lang` 属性で [Webpack loader requests](https://webpack.github.io/docs/loaders.html#introduction) を使用することが可能です：
+
+``` html
+<style lang="sass?outputStyle=expanded">
+  /* ここでは拡張出力で sass を使用します */
+</style>
+```
+
+ただこれにより Vue コンポーネントが Webpack 固有となり Browserify および [vueify](https://github.com/vuejs/vueify) と互換性がなくなります。 **Vue コンポーネントを再利用可能なサードパーティコンポーネントとして提供する場合は、この構文を使用しないでください。**
diff --git a/docs/ja/features/css-modules.md b/docs/ja/features/css-modules.md
new file mode 100644
index 0000000..8dd753f
--- /dev/null
+++ b/docs/ja/features/css-modules.md
@@ -0,0 +1,117 @@
+# CSS モジュール
+
+> バージョン ^9.8.0 が必要
+
+[CSS モジュール](https://github.com/css-modules/css-modules) は CSS をモジュール化して構成するための一般的なシステムです。`vue-loader` はシミュレートされたスコープ付き CSS の代わりに CSS モジュールの一流の統合を提供します。
+
+### 使い方
+
+`module` 属性を `<style>` タグに追加します：
+
+``` html
+<style module>
+.red {
+  color: red;
+}
+.bold {
+  font-weight: bold;
+}
+</style>
+```
+
+`css-loader` の CSS モジュールモードを有効にし、その結果クラス識別子オブジェクトは `$style` という名前の算出プロパティとしてコンポーネントに注入されます。ダイナミッククラスバインディングを利用してテンプレートで使用可能になります。
+
+``` html
+<template>
+  <p :class="$style.red">
+    This should be red
+  </p>
+</template>
+```
+
+これは算出プロパティなので、`:class` の オブジェクト/配列 構文でも動作します：
+
+``` html
+<template>
+  <div>
+    <p :class="{ [$style.red]: isRed }">
+      Am I red?
+    </p>
+    <p :class="[$style.red, $style.bold]">
+      Red and bold
+    </p>
+  </div>
+</template>
+```
+
+そして JavaScript からもアクセス可能です：
+
+``` html
+<script>
+export default {
+  created () {
+    console.log(this.$style.red)
+    // -> "_1VyoJ-uZOjlOxP7jWUy19_0"
+    // filename と className に基づいて出力された識別子。
+  }
+}
+</script>
+```
+
+[CSS Modules spec](https://github.com/css-modules/css-modules) を参照してください。モードの詳細については [global exceptions](https://github.com/css-modules/css-modules#exceptions) と [composition](https://github.com/css-modules/css-modules#composition)を参照してください。
+
+### カスタム代入
+
+単一の `*.vue` コンポーネントは複数の `<style>` タグを持つことが出来ます。注入されたスタイルが互いに上書きするのを避けるために、 `module`属性に値を与えることによって、注入された計算されたプロパティの名前をカスタマイズすることができます：
+
+``` html
+<style module="a">
+  /* a として注入された識別子 */
+</style>
+
+<style module="b">
+  /* b として注入された識別子 */
+</style>
+```
+
+### `css-loader` クエリの設定
+
+CSS モジュールは [css-loader](https://github.com/webpack/css-loader) によって処理されます。`<style module>` では `css-loader` に使われるデフォルトのクエリは次のようになります。
+
+``` js
+{
+  modules: true,
+  importLoaders: true,
+  localIdentName: '[hash:base64]'
+}
+```
+
+vue-loader の `cssModules`オプションを使って` css-loader`に追加のクエリオプションを提供することができます：
+
+``` js
+// webpack 1
+vue: {
+  cssModules: {
+    // ローカルID名を上書きする
+    localIdentName: '[path][name]---[local]---[hash:base64:5]',
+    // キャメルケースを有効にする
+    camelCase: true
+  }
+}
+
+// webpack 2
+module: {
+  rules: [
+    {
+      test: '\.vue$',
+      loader: 'vue-loader',
+      options: {
+        cssModules: {
+          localIdentName: '[path][name]---[local]---[hash:base64:5]',
+          camelCase: true
+        }
+      }
+    }
+  ]
+}
+```
diff --git a/docs/ja/features/es2015.md b/docs/ja/features/es2015.md
new file mode 100644
index 0000000..521c24f
--- /dev/null
+++ b/docs/ja/features/es2015.md
@@ -0,0 +1,64 @@
+# ES2015
+
+同一プロジェクト内で `babel-loader` か `buble-loader` を検出したとき、全ての `*.vue` ファイルの `<script>` タグを処理するためにそれらを使用し Vue コンポーネント内で ES2015 を使用できるようにします。もしあなたがまだ新しい言語機能を手に入れていないのであれば、手に入れるべきです。いくつかのよい学習リソースはこちら：
+- [Babel - Learn ES2015](https://babeljs.io/docs/learn-es2015/)
+- [ES6 Features](https://github.com/lukehoban/es6features)
+- [Exploring ES6 (book)](https://leanpub.com/exploring-es6)
+
+他の Vue コンポーネントを読み込む際の典型的なパターンはこちらです。
+
+``` html
+<script>
+import ComponentA from './ComponentA.vue'
+import ComponentB from './ComponentB.vue'
+
+export default {
+  components: {
+    ComponentA,
+    ComponentB
+  }
+}
+</script>
+```
+
+ここでは ES2015 のオブジェクトリテラルを使用して子コンポーネントを定義しています。`{ ComponentA }` は `{ ComponentA: ComponentA }` の簡略形です。 Vue はオートでキーを `component-a` に変換し、インポートされたコンポーネントをテンプレート内で `<component-a>` として使用することが出来ます。
+
+### テンプレート内のES2015
+
+`*.vue` ファイル内の `<template>` は JavaScript の render 関数にコンパイルされ[Buble](https://buble.surge.sh/guide/) のカスタムビルドで処理され ES2015 の機能をサポートします。これにより [Object shorthand properties](https://buble.surge.sh/guide/#object-shorthand-methods-and-properties-transforms-concisemethodproperty-) と[算出プロパティ](https://buble.surge.sh/guide/#computed-properties-transforms-computedproperty-)などの機能が使用できるようになります。
+
+``` html
+<div :class="[{ active: active }, isButton ? prefix + '-button' : null]">
+```
+
+次のように単純化することができます:
+
+``` html
+<div :class="{ active, [`${prefix}-button`]: isButton }">
+```
+
+**vue@^2.1.0 のみ利用可能:** `v-for` かスコープ付きスロットを使用することで、構造化されたパラメータを使用することが出来ます：
+
+``` html
+<li v-for="{ id, text } in items">
+  {{ id }} {{ text }}
+</li>
+```
+
+``` html
+<my-component>
+  <template scope="{ id, text }">
+    <span>{{ id }} {{ text }}</span>
+  </template>
+</my-component>
+```
+
+[buble オプション](../options.md#buble)を使用してテンプレートでサポートされた機能をカスタマイズすることが出来ます。
+
+### `.js` ファイルのトランスパイル
+
+`vue-loader` は `*.vue` ファイルのみ処理するので、Webpack の設定ファイルに `babel-loader` または `buble-loader` を使って `*.js` ファイルを処理するように Webapck に指示する必要があります。 `vue-cli` でプロジェクトを作成しているとすでにそれは用意されています。
+
+### `.babelrc` による Babel の設定
+
+`babel-loader` は [`.babelrc`](https://babeljs.io/docs/usage/babelrc/)を遵守しているので、Babel のプリセットとプラグインで設定することが推奨されています。
diff --git a/docs/ja/features/hot-reload.md b/docs/ja/features/hot-reload.md
new file mode 100644
index 0000000..5959c7c
--- /dev/null
+++ b/docs/ja/features/hot-reload.md
@@ -0,0 +1,7 @@
+# ホットリロード
+
+"ホットリロード"はファイルを編集するときに単にページをリロードするだけではありません。ホットリロードを有効にすると、`*.vue` ファイルを編集するとき、すべてのコンポーネントのインスタンスは **ページのリロードをせずに** 取り替えられます。アプリの現在の状態を保持し、コンポーネントを取り替えることが出来ます！これはコンポーネントのテンプレートやスタイリングを微調整するときの開発体験を劇的に改善します。
+
+![hot-reload](http://blog.evanyou.me/images/vue-hot.gif)
+
+`vue-cli` を使ってプロジェクトをスキャホールドすると、ホットリロードはすぐに使えるようになります。
diff --git a/docs/ja/features/postcss.md b/docs/ja/features/postcss.md
new file mode 100644
index 0000000..d8a54ee
--- /dev/null
+++ b/docs/ja/features/postcss.md
@@ -0,0 +1,68 @@
+# PostCSS
+
+`vue-loader`により処理されたCSSのアウトプットはスコープされたCSSにに書き換えるために[PostCSS](https://github.com/postcss/postcss) を通します。カスタムされた PostCSSプラグインをプロセスに追加することが出来ます。例えば、[autoprefixer](https://github.com/postcss/autoprefixer) や [CSSNext](http://cssnext.io/)があります。
+
+## 設定ファイルの使用
+
+バージョン 11.0 以降、 `vue-loader` は [`postcss-loader`](https://github.com/postcss/postcss-loader#usage) でサポートされているものと同じ PostCss の設定ファイルのオートロードをサポートします：
+
+- `postcss.config.js`
+- `.postcssrc`
+- `package.json` 内の `postcss`
+
+設定ファイルを使用すると `postcss-loader` で処理された通常の CSS ファイルと `*.vue` ファイル内の CSS で同じ設定を共有することができます。
+
+## インラインオプション
+
+あるいは、 `vue-loader` の `postcss` オプションを使用して `*.vue` ファイル用の postcss の設定を指定することが出来ます。
+
+Webpack 1.x の例：
+
+``` js
+// webpack.config.js
+module.exports = {
+  // 他の設定
+  vue: {
+    // カスタムされた postcss プラグインを使用します
+    postcss: [require('postcss-cssnext')()]
+  }
+}
+```
+
+Webpack 2.x の例:
+
+``` js
+// webpack.config.js
+module.exports = {
+  // 他の設定
+  module: {
+    // module.rules は 1.x の module.loaders と同じです
+    rules: [
+      {
+        test: /\.vue$/,
+        loader: 'vue-loader',
+        // vue-loader のオプションはここです
+        options: {
+          // ...
+          postcss: [require('postcss-cssnext')()]
+        }
+      }
+    ]
+  }
+}
+```
+
+加えてpluginの配列を提供し、`postcss` オプションは以下も受け入れます：
+
+- プラグインの配列を返す関数；
+
+- PostCSSプロセッサに渡すオプションを含むオブジェクト。これは、カスタム parser/stringifiers に依存するPostCSSプロジェクトを使用している場合に便利です。
+
+  ``` js
+  postcss: {
+    plugins: [...], // プラグインのリスト
+    options: {
+      parser: sugarss // sugarss パーサーを使用します
+    }
+  }
+  ```
diff --git a/docs/ja/features/scoped-css.md b/docs/ja/features/scoped-css.md
new file mode 100644
index 0000000..75997cc
--- /dev/null
+++ b/docs/ja/features/scoped-css.md
@@ -0,0 +1,51 @@
+# スコープ付き CSS
+
+`scoped` 属性をもつ `<style>` タグを利用するとき、その CSS は現在のコンポーネントの要素にのみ適用されます。これは Shadow DOM のスタイルのカプセル化に似ています。いくつか注意点がありますが、polyfill は必要ありません。PostCSS を使用して以下を変換することによって実現しています。
+
+``` html
+<style scoped>
+.example {
+  color: red;
+}
+</style>
+
+<template>
+  <div class="example">hi</div>
+</template>
+```
+
+以下の通りになります:
+
+``` html
+<style>
+.example[_v-f3f3eg9] {
+  color: red;
+}
+</style>
+
+<template>
+  <div class="example" _v-f3f3eg9>hi</div>
+</template>
+```
+
+#### 注意
+
+1. 同じコンポーネント内にスコープで区切られてものとそうでないスタイルを含むことが出来ます：
+
+  ``` html
+  <style>
+  /* グローバルスタイル */
+  </style>
+
+  <style scoped>
+  /* ローカルスタイル */
+  </style>
+  ```
+
+2. 子コンポーネントのルートノードは親のスコープの CSS と子のスコープの CSS の両方の影響をうけます。
+
+3. パーシャルはスコープ付きスタイルの影響をうけません。
+
+4. **スコープされたスタイルは class の必要性を排除しません**。ブラウザが様々な CSS セレクタをレンダリングするため、`p { color: red }` はスコープされているとき何倍も遅くなります（すなわち属性セレクタと組み合わせた場合）。もし `.example { color: red }` のように class か id を使用するなら、パフォーマンスヒットは事実上なくなります。[この例](http://stevesouders.com/efws/css-selectors/csscreate.php)で違いをテストすることが出来ます。
+
+5. **再帰されたコンポーネントの子孫セレクタには気をつけてください！** セレクタ `.a .b` を持つ CSS ルールの場合、`.a` にマッチする要素に再帰的な子コンポーネントが含まれている場合、その子コンポーネントのすべての `.b` はルールにマッチします。
diff --git a/docs/ja/options.md b/docs/ja/options.md
new file mode 100644
index 0000000..413551d
--- /dev/null
+++ b/docs/ja/options.md
@@ -0,0 +1,187 @@
+# オプションリファレンス
+
+## Webpack 1と2の使い方の違い
+
+Webpack 2 の場合：オプションを loader ルールに直接渡します。
+
+``` js
+module.exports = {
+  // ...
+  module: {
+    rules: [
+      {
+        test: /\.vue$/,
+        loader: 'vue-loader',
+        options: {
+          // vue-loader オプション
+        }
+      }
+    ]
+  }
+}
+```
+
+Webpack 1.x の場合： Webpack の設定のルートに `vue` ブロックを追加します。
+
+``` js
+module.exports = {
+  // ...
+  vue: {
+    // vue-loader オプション
+  }
+}
+```
+
+### loaders
+
+- 型： `{ [lang: string]: string }`
+
+  `* .vue` ファイル内の言語ブロックに使用されるデフォルトの loader を上書きする Webpack loader を指定するオブジェクト。キーは指定されている場合、言語ブロックの `lang` 属性に対応します。各タイプのデフォルトの `lang` は次のとおりです：
+
+  - `<template>`: `html`
+  - `<script>`: `js`
+  - `<style>`: `css`
+
+  たとえば、`babel-loader` と `eslint-loader` を使ってすべての `<script>` ブロックを処理するには：
+
+  ``` js
+  // Webpack 2.x config
+  module: {
+    rules: [
+      {
+        test: /\.vue$/,
+        loader: 'vue-loader',
+        options: {
+          loaders: {
+            js: 'babel-loader!eslint-loader'
+          }
+        }
+      }
+    ]
+  }
+  ```
+
+### preLoaders
+
+- 型： `{ [lang: string]: string }`
+- 10.3.0 以上でサポートされます。
+
+  config 形式は `loaders` と同じですが、`preLoaders` はデフォルト loader の前に対応する言語ブロックに適用されます。これを使用して言語ブロックを前処理することができます。一般的な使用例としては、i18n のビルド時です。
+
+### postLoaders
+
+- 型：`{ [lang: string]: string }`
+- 10.3.0 以上でサポートされます。
+
+  config 形式は `loaders` と同じですが、` postLoaders` はデフォルト loader の後に適用されます。これを使用して言語ブロックを後処理することができます。ただしこれは少し複雑になります：
+
+  - `html` の場合、デフォルトの loader によって返される結果は、コンパイルされた JavaScript レンダリング関数コードになります。
+
+  - `css` の場合、結果は` vue-style-loader` によって返されます。これはほとんどの場合特に有用ではありません。postcss プラグインを使用する方が良いでしょう。
+
+### postcss
+
+  > メモ: 11.0.0 以上では代わりにPostCSSの設定ファイル推奨されています。[使用法は `postcss-loader` と同じです](https://github.com/postcss/postcss-loader#usage)。
+
+- 型： `Array` もしくは `Function` か `Object`
+
+  カスタムした PostCSS プラグインを `*.vue` ファイル内の CSS に適用するよう指定します。もし関数を使用しているなら、この関数は同じ loader のコンテキストを使用して呼び出され、プラグインの配列を返す必要があります。
+
+  ``` js
+  // ...
+  {
+    loader: 'vue-loader',
+    options: {
+      // 注意： `loaders` 以下に `postcss` のオプションをネストさせてはいけません
+      postcss: [require('postcss-cssnext')()],
+      loaders: {
+        // ...
+      }
+    }
+  }
+  ```
+
+  そのオプションは PostCSS プロセッサーに渡すオプションを含むオブジェクトにすることもできます。これは カスタムされたパーサー/文字列化に依存した PostCSS プロジェクトを使用しているとき便利です:
+
+  ``` js
+  postcss: {
+    plugins: [...], // pluginsのリスト
+    options: {
+      parser: sugarss // sugarss パーサを使用
+    }
+  }
+  ```
+
+### cssSourceMap
+
+- 型： `Boolean`
+- デフォルト: `true`
+
+  CSS のソースマップを有効にするかどうか。これを無効にすると、`css-loader` の相対パス関連のバグを避けることができ、ビルドを少し早くすることができます。
+
+  注意： もしメインの Webpack の設定に `devtool` オプションが存在しないければオートで `false` にセットされます。
+
+### esModule
+
+- 型： `Boolean`
+- デフォルト： `undefined`
+
+  esModule 互換コードを発行するかどうか。デフォルトの vue-loader のデフォルトの出力は `module.exports = ....` のような commonjs 形式で発行します。 `esModule` が true にセットされているとき、デフォルトの出力は `exports.__esModule = true; exports = ...` にトランスパイルされます。TypeScript のような Babel 以外の transpiler との相互運用に役立ちます。
+
+### preserveWhitespace
+
+- 型： `Boolean`
+- デフォルト： `true`
+
+  もし `false` に設定されていたら、テンプレート内の HTML タグ間の空白は無視されます。
+
+### transformToRequire
+
+- 型： `{ [tag: string]: string | Array<string> }`
+- デフォルト： `{ img: 'src', image: 'xlink:href' }`
+
+  テンプレートのコンパイル中、コンパイラは `src` の URL のような特定の属性を `require` 呼び出しに変換することができます。これによりターゲットの asset を Webpack が処理できるようになります。デフォルトの設定は `<img>` タグの `src` 属性と SVG の `<image>` タグの `xlink：href` 属性を変換します。
+
+### buble
+
+  型： `Object`
+  デフォルト： `{}`
+
+  `bubble-loader`（存在する場合）のオプションとテンプレートレンダリング関数のための buble のコンパイルパスを設定します。
+
+  > バージョンメモ： 9.x では、テンプレート式は削除された `templateBuble` オプションによって別々に設定されます。
+
+  このテンプレートレンダリング関数のコンパイルでは、特別な変換 `stripWidth` （デフォルトで有効）がサポートされ、生成されたレンダリング関数で `with` の使用法が削除され、strict-mode に準拠します。
+
+  設定の例：
+
+  ``` js
+  // webpack 1
+  vue: {
+    buble: {
+      // オブジェクトスプレッド演算子を有効にする
+      // メモ: Object.assign polyfillを自分で提供する必要があります！
+      objectAssign: 'Object.assign',
+
+      // `with` の除去をオフにする
+      transforms: {
+        stripWith: false
+      }
+    }
+  }
+
+  // webpack 2
+  module: {
+    rules: [
+      {
+        test: /\.vue$/,
+        loader: 'vue-loader',
+        options: {
+          buble: {
+            // 同じオプション
+          }
+        }
+      }
+    ]
+  }
+  ```
diff --git a/docs/ja/start/setup.md b/docs/ja/start/setup.md
new file mode 100644
index 0000000..786b228
--- /dev/null
+++ b/docs/ja/start/setup.md
@@ -0,0 +1,13 @@
+# プロジェクトのセットアップ
+
+### `vue-cli` の使用
+
+`vue-loader` を使用するプロジェクトの足場作りは `vue-cli` を使用することをお薦めします：
+
+``` bash
+npm install -g vue-cli
+vue init webpack-simple hello-vue
+cd hello-vue
+npm install
+npm run dev # ready to go!
+```
diff --git a/docs/ja/start/spec.md b/docs/ja/start/spec.md
new file mode 100644
index 0000000..cc27296
--- /dev/null
+++ b/docs/ja/start/spec.md
@@ -0,0 +1,103 @@
+# Vue Component の仕様
+
+`*.vue` ファイルは HTML ライクな構文を使用して Vue コンポーネントを記述するカスタムファイルフォーマットです。各 `*.vue` ファイルは `<template>`、`<script>`、`<style>` の三つのトップレベル言語のブロックで構成されています。
+
+``` html
+<template>
+  <div class="example">{{ msg }}</div>
+</template>
+
+<script>
+export default {
+  data () {
+    return {
+      msg: 'Hello world!'
+    }
+  }
+}
+</script>
+
+<style>
+.example {
+  color: red;
+}
+</style>
+
+<custom1>
+  例えばコンポーネントのドキュメントを書くことが出来ます
+</custom1>
+```
+
+`vue-loader` はファイルを解析し、それぞれの言語ブロックを必要に応じて他の loader を通し、最終的に `module.exports` が Vue.js のコンポーネントオプションオブジェクトの CommonJS モジュールに変換します。
+
+`vue-loader` は CSS プリプロセッサや HTML にコンパイルするテンプレート言語といった、デフォルトでない言語を言語ブロックの `lang` 属性を使用することでサポートします。例えばコンポーネントのスタイルに SASS を使用することが出来ます。
+
+``` html
+<style lang="sass">
+  /* write SASS! */
+</style>
+```
+詳細は [プリプロセッサの仕様](../configurations/pre-processors.md) で確認することが出来ます。
+
+### 言語ブロック
+
+#### `<template>`
+
+- デフォルトの言語は `html`
+
+- それぞれの `*.vue` ファイルは最大で一つの `<template>` ブロックを含みます。
+
+- 内容は文字列に展開され、コンパイルされた Vue コンポーネントの `template` オプションで使用されます。
+
+#### `<script>`
+
+- デフォルトの言語は `js`（`babel-loader` や `buble-loader` が検出される場合、自動的にES2015がサポートされる）
+
+- それぞれの `*.vue` ファイルは最大で一つの `<script>` ブロックを含みます。
+
+- スクリプトは CommonJS のように処理されます（ Webpack 経由でバンドルされた通常の `.js` モジュールと同じです）。つまり他の依存関係を `recuire()` することができます。そして ES2015 がサポートされ、`import` と `export` 構文を使用することが出来ます。
+
+- スクリプトは Vue.js コンポーネントのオプションオブジェクトをエクスポートする必要があります。 'Vue.extend()' によって拡張されたコンストラクタもエクスポートすることが可能ですが、プレーンなオブジェクトが好ましいです。
+
+#### `<style>`
+
+- デフォルトの言語は `css`。
+
+- 複数の `<style>` タグは単一の `*.vue` ファイルでサポートされます。
+
+- `<style>` タグは `scoped` か `module` （詳しくは [Scoped CSS](../features/scoped-css.md) と [CSS Modules](../features/css-modules.md) をみてください）を使用してコンポーネントにスタイルをカプセル化する事が出来ます。異なるカプセルモードをもつ複数の `<style>` タグは同じコンポーネント内で混在させることが出来ます。
+
+- デフォルトではコンテンツは `style-loader` を使用して実際の `<style>` タグとして抽出され、ドキュメントの `<head>` に動的に挿入されます。また、[すべてのコンポーネントのすべてのスタイルが単一のCSSファイルに抽出されるようにWebpackを設定する](../configurations/extract-css.md)こともできます。
+
+### カスタムブロック
+
+> vue-loader 10.2.0+ でのみサポートされます
+
+例えば `<docs>` ブロックのように、プロジェクトの特別な必用に応じて `*.vue` ファイルに カスタムブロックを追加することが出来ます。 `vue-loader`はタグ名を使用してセクションの内容に適用されるべき webpack loader を検索します。webpack loader は、`vue-loader` オプションの `loaders` セクションで指定する必要があります。
+
+このモードの詳細については、[カスタムブロック](../configurations/custom-blocks.md)を参照してください。
+
+### ソースのインポート
+
+もし `*.vue` コンポーネントを複数のファイルに分割したい場合は、`src` 属性を使って言語ブロック用の外部ファイルをインポートすることが出来ます。
+
+``` html
+<template src="./template.html"></template>
+<style src="./style.css"></style>
+<script src="./script.js"></script>
+```
+
+`src` のインポートは CommonJS の `require()` 呼び出しと同じパス解決規則に従うことに注意してください。相対パスは `./` で始める必要があり、インストールされた NPM パッケージから直接リソースをインポートすることができます。
+
+``` html
+<!-- インストールされた "todomvc-app-css" npm パッケージ からファイルをインポートします-->
+<style src="todomvc-app-css/index.css">
+```
+
+### シンタックスハイライト
+
+現在それらはシンタクスハイライトをサポートしているのは、[Sublime Text](https://github.com/vuejs/vue-syntax-highlight), [Atom](https://atom.io/packages/language-vue), [Vim](https://github.com/posva/vim-vue), [Visual Studio Code](https://marketplace.visualstudio.com/items/liuji-jim.vue), [Brackets](https://github.com/pandao/brackets-vue), [JetBrains products](https://plugins.jetbrains.com/plugin/8057) (WebStorm, PhpStorm, etc). 他のエディタ/IDEへのコントリビュートは高く評価されます！もし Vue コンポーネント内でプリプロセッサを使用していない場合は、エディタで `*.vue` ファイルを HTML として扱うことが出来ます。
+
+### コメント
+
+それぞれのブロック内でそれぞれの言語のコメントシンタックスを使用することが出来る（HTML、CSS、JavaScript、Jade、etc）。最上部のコメントは HTML コメントシンタックスを使用してください： `<!-- コメントはこちら -->`
diff --git a/docs/ja/workflow/linting.md b/docs/ja/workflow/linting.md
new file mode 100644
index 0000000..b2aee59
--- /dev/null
+++ b/docs/ja/workflow/linting.md
@@ -0,0 +1,92 @@
+# Linting
+
+あなたはJavaScriptでない `*.vue` の中のコードをどうやって lint するのか疑問に思っているかも知れません。[ESLint](http://eslint.org/)を使用していると仮定します（もし使っていないのならばすべきです！）
+
+`* .vue`ファイル内のJavaScriptの抽出と埋め込みをサポートする[eslint-plugin-html](https://github.com/BenoitZugmeyer/eslint-plugin-html)も同様に必要です。
+
+あなたの ESLint の設定にプラグインを含めてください：
+
+``` json
+"plugins": [
+  "html"
+]
+```
+
+コマンドラインで次を実行してください：
+
+``` bash
+eslint --ext js,vue MyComponent.vue
+```
+
+別のオプションは `*.vue` ファイルが開発中に保存時されたとき、自動的に lint されるように[eslint-loader](https://github.com/MoOx/eslint-loader)を使用しています：
+
+``` bash
+npm install eslint eslint-loader --save-dev
+```
+
+``` js
+// webpack.config.js
+module.exports = {
+  // 他のオプション
+  module: {
+    loaders: [
+      {
+        test: /.vue$/,
+        loader: 'vue!eslint'
+      }
+    ]
+  }
+}
+```
+Webpack ローダーチェーンは**まずはじめに**に適用されることをご了承ください。`vue` の前に `eslint` を適用して、コンパイル前のソースコードを lint してください。
+
+一つ私たちが考慮する必要があるのは、NPM パッケージでリリースされているサードパーティの* .vueコンポーネントを使用することです。そのような場合には、サードパーティー製のコンポーネントを処理するために  `vue-loader` を使用したいと思いますが、それを lint したくはありません。そういうときは lint を Webpack の [preLoaders](https://webpack.github.io/docs/loaders.html#loader-order) に分けることが可能です：
+
+``` js
+// webpack.config.js
+module.exports = {
+  // 他のオプション
+  module: {
+    // lint対象はローカルの *.vue ファイルのみ
+    preLoaders: [
+      {
+        test: /.vue$/,
+        loader: 'eslint',
+        exclude: /node_modules/
+      }
+    ],
+    // しかし全ての *.vue ファイルで vue-loader を使用します
+    loaders: [
+      {
+        test: /.vue$/,
+        loader: 'vue'
+      }
+    ]
+  }
+}
+```
+
+Webpack 2.x:
+
+``` js
+// webpack.config.js
+module.exports = {
+  // 他のオプション
+  module: {
+    rules: [
+      // *.vue のみを検査します
+      {
+        enforce: 'pre',
+        test: /.vue$/,
+        loader: 'eslint-loader',
+        exclude: /node_modules/
+      },
+      // しかし全ての *.vue ファイルで vue-loader は使用します
+      {
+        test: /.vue$/,
+        loader: 'vue-loader'
+      }
+    ]
+  }
+}
+```
diff --git a/docs/ja/workflow/production.md b/docs/ja/workflow/production.md
new file mode 100644
index 0000000..e92a5b9
--- /dev/null
+++ b/docs/ja/workflow/production.md
@@ -0,0 +1,39 @@
+# プロダクションビルド
+
+プロダクション用にバンドルを構築するときは二つのことを行います：
+
+1. アプリケーションコードを縮小します：
+2. [Vue.jsガイドに記載されているセットアップの説明](https://vuejs.org/guide/deployment.html) を使用して Vue.js のソースコードから全ての警告を削除します
+
+設定例を以下に示します：
+
+``` js
+// webpack.config.js
+module.exports = {
+  // 他のオプション
+  plugins: [
+    // すべての Vue.js 警告コードを短絡します
+    new webpack.DefinePlugin({
+      'process.env': {
+        NODE_ENV: '"production"'
+      }
+    }),
+    // デッドコード除去で縮小します
+    new webpack.optimize.UglifyJsPlugin({
+      compress: {
+        warnings: false
+      }
+    }),
+    // 発生回数別にモジュールIDを最適化します
+    new webpack.optimize.OccurenceOrderPlugin()
+  ]
+}
+```
+
+明らかに開発中にこの設定を使いたくないので、これにはいくつかの方法をとります：
+
+1. 環境変数に基づいて構成オブジェクトを動的に構築します；
+
+2. または、開発用と運用用の2つの Webpack 設定ファイルを使用します。[vue-hackernews-2.0](https://github.com/vuejs/vue-hackernews-2.0)に示すように、3つ目のファイルに共通のオプションをいくつか共有することもできます。
+
+目標を達成している限り、それはあなた次第です。
diff --git a/lib/component-normalizer.js b/lib/component-normalizer.js
index d1b8a19..2a72a28 100644
--- a/lib/component-normalizer.js
+++ b/lib/component-normalizer.js
@@ -1,3 +1,6 @@
+// this module is a runtime utility for cleaner component module output and will
+// be included in the final webpack user bundle
+
 module.exports = function normalizeComponent (
   rawScriptExports,
   compiledTemplate,
diff --git a/lib/loader.js b/lib/loader.js
index 7778a38..45a0bef 100644
--- a/lib/loader.js
+++ b/lib/loader.js
@@ -1,15 +1,15 @@
 var path = require('path')
 var parse = require('./parser')
-var genId = require('./gen-id')
-var normalize = require('./normalize')
+var genId = require('./utils/gen-id')
+var normalize = require('./utils/normalize')
 var loaderUtils = require('loader-utils')
 var querystring = require('querystring')
 
 // internal lib loaders
 var selectorPath = normalize.lib('selector')
-var styleRewriterPath = normalize.lib('style-rewriter')
-var templateLoaderPath = normalize.lib('template-loader')
-var templateCompilerPath = normalize.lib('template-compiler')
+var styleCompilerPath = normalize.lib('style-compiler/index')
+var templateCompilerPath = normalize.lib('template-compiler/index')
+var templatePreprocessorPath = normalize.lib('template-compiler/preprocessor')
 var componentNormalizerPath = normalize.lib('component-normalizer')
 
 // dep loaders
@@ -36,15 +36,13 @@ var defaultLang = {
 
 // When extracting parts from the source vue file, we want to apply the
 // loaders chained before vue-loader, but exclude some loaders that simply
-// produces side effects such as linting. This is a hard-coded list and
-// hopefully eslint-loader is the only one.
-var excludedPreLoadersRE = /eslint-loader/
-
-function getRawRequest (context) {
+// produces side effects such as linting.
+function getRawRequest (context, excludedPreLoaders) {
+  excludedPreLoaders = excludedPreLoaders || /eslint-loader/
   return loaderUtils.getRemainingRequest({
     resource: context.resource,
     loaderIndex: context.loaderIndex,
-    loaders: context.loaders.filter(loader => !excludedPreLoadersRE.test(loader.path))
+    loaders: context.loaders.filter(loader => !excludedPreLoaders.test(loader.path))
   })
 }
 
@@ -55,8 +53,8 @@ module.exports = function (content) {
 
   var loaderContext = this
   var query = loaderUtils.getOptions(this) || {}
-  var rawRequest = getRawRequest(this)
   var options = this.options.__vueOptions__ = Object.assign({}, this.options.vue, this.vue, query)
+  var rawRequest = getRawRequest(this, options.excludedPreLoaders)
 
   var filePath = this.resourcePath
   var fileName = path.basename(filePath)
@@ -80,7 +78,11 @@ module.exports = function (content) {
     id: moduleId,
     transformToRequire: options.transformToRequire,
     preserveWhitespace: options.preserveWhitespace,
-    buble: options.buble
+    buble: options.buble,
+    // only pass compilerModules if it's a path string
+    compilerModules: typeof options.compilerModules === 'string'
+      ? options.compilerModules
+      : undefined
   })
 
   var defaultLoaders = {
@@ -186,9 +188,9 @@ module.exports = function (content) {
     var lang = part.lang || defaultLang[type]
     var loader = loaders[lang]
 
-    var styleRewriter = ''
+    var styleCompiler = ''
     if (type === 'styles') {
-      styleRewriter = styleRewriterPath + '?' + JSON.stringify({
+      styleCompiler = styleCompilerPath + '?' + JSON.stringify({
         id: moduleId,
         scoped: !!scoped,
         hasInlineConfig: !!query.postcss
@@ -211,10 +213,10 @@ module.exports = function (content) {
         // inject rewriter before css loader for extractTextPlugin use cases
         if (rewriterInjectRE.test(loader)) {
           loader = loader.replace(rewriterInjectRE, function (m, $1) {
-            return ensureBang($1) + styleRewriter
+            return ensureBang($1) + styleCompiler
           })
         } else {
-          loader = ensureBang(loader) + styleRewriter
+          loader = ensureBang(loader) + styleCompiler
         }
       }
       // if user defines custom loaders for html, add template compiler to it
@@ -226,10 +228,10 @@ module.exports = function (content) {
       // unknown lang, infer the loader to be used
       switch (type) {
         case 'template':
-          return defaultLoaders.html + '!' + templateLoaderPath + '?raw&engine=' + lang + '!'
+          return defaultLoaders.html + '!' + templatePreprocessorPath + '?raw&engine=' + lang + '!'
         case 'styles':
           loader = addCssModulesToLoader(defaultLoaders.css, part, index)
-          return loader + '!' + styleRewriter + ensureBang(ensureLoader(lang))
+          return loader + '!' + styleCompiler + ensureBang(ensureLoader(lang))
         case 'script':
           return injectString + ensureBang(ensureLoader(lang))
         default:
@@ -411,7 +413,11 @@ module.exports = function (content) {
           addedPrefix = true
         }
 
-        output += requireString + '\n'
+        output +=
+          'var customBlock = ' + requireString + '\n' +
+          'if (typeof customBlock === "function") {' +
+            'customBlock(Component)' +
+          '}\n'
       }
     })
 
diff --git a/lib/selector.js b/lib/selector.js
index 7779b8d..e2f8751 100644
--- a/lib/selector.js
+++ b/lib/selector.js
@@ -1,3 +1,7 @@
+// this is a utility loader that takes a *.vue file, parses it and returns
+// the requested language block, e.g. the content inside <template>, for
+// further processing.
+
 var path = require('path')
 var parse = require('./parser')
 var loaderUtils = require('loader-utils')
diff --git a/lib/style-compiler/index.js b/lib/style-compiler/index.js
new file mode 100644
index 0000000..a3d14b9
--- /dev/null
+++ b/lib/style-compiler/index.js
@@ -0,0 +1,68 @@
+var postcss = require('postcss')
+var loaderUtils = require('loader-utils')
+var loadPostcssConfig = require('./load-postcss-config')
+
+var trim = require('./plugins/trim')
+var scopeId = require('./plugins/scope-id')
+
+module.exports = function (css, map) {
+  this.cacheable()
+  var cb = this.async()
+
+  var query = loaderUtils.getOptions(this) || {}
+  var vueOptions = this.options.__vueOptions__
+
+  if (!vueOptions) {
+    if (query.hasInlineConfig) {
+      this.emitError(
+        `\n  [vue-loader] It seems you are using HappyPack with inline postcss ` +
+        `options for vue-loader. This is not supported because loaders running ` +
+        `in different threads cannot share non-serializable options. ` +
+        `It is recommended to use a postcss config file instead.\n` +
+        `\n  See http://vue-loader.vuejs.org/en/features/postcss.html#using-a-config-file for more details.\n`
+      )
+    }
+    vueOptions = Object.assign({}, this.options.vue, this.vue)
+  }
+
+  // use the same config loading interface as postcss-loader
+  loadPostcssConfig(vueOptions.postcss).then(({ plugins, options }) => {
+    plugins = [trim].concat(plugins)
+    options = Object.assign({
+      to: this.resourcePath,
+      from: this.resourcePath,
+      map: false
+    }, options)
+
+    // add plugin for vue-loader scoped css rewrite
+    if (query.scoped) {
+      plugins.push(scopeId({ id: query.id }))
+    }
+
+    // source map
+    if (
+      this.sourceMap &&
+      !this.minimize &&
+      vueOptions.cssSourceMap !== false &&
+      process.env.NODE_ENV !== 'production' &&
+      !options.map
+    ) {
+      options.map = {
+        inline: false,
+        annotation: false,
+        prev: map
+      }
+    }
+
+    return postcss(plugins)
+      .process(css, options)
+      .then(function (result) {
+        var map = result.map && result.map.toJSON()
+        cb(null, result.css, map)
+        return null // silence bluebird warning
+      })
+  }).catch(e => {
+    console.log(e)
+    cb(e)
+  })
+}
diff --git a/lib/style-compiler/load-postcss-config.js b/lib/style-compiler/load-postcss-config.js
new file mode 100644
index 0000000..95bac6a
--- /dev/null
+++ b/lib/style-compiler/load-postcss-config.js
@@ -0,0 +1,45 @@
+var load = require('postcss-load-config')
+
+let loaded
+
+function isObject (val) {
+  return val && typeof val === 'object'
+}
+
+module.exports = function loadPostcssConfig (inlineConfig) {
+  if (process.env.VUE_LOADER_TEST || !loaded) {
+    loaded = load({}, null, { argv: false }).catch(() => {
+      // postcss-load-config throws error when no config file is found,
+      // but for us it's optional.
+    })
+  }
+
+  return loaded.then(config => {
+    var plugins = []
+    var options = {}
+
+    // inline postcss options for vue-loader
+    if (typeof inlineConfig === 'function') {
+      inlineConfig = inlineConfig.call(this, this)
+    }
+    if (Array.isArray(inlineConfig)) {
+      plugins = inlineConfig
+    } else if (isObject(inlineConfig)) {
+      plugins = inlineConfig.plugins || []
+      options = inlineConfig.options || {}
+    }
+
+    // merge postcss config file
+    if (config && config.plugins) {
+      plugins = plugins.concat(config.plugins)
+    }
+    if (config && config.options) {
+      options = Object.assign({}, config.options, options)
+    }
+
+    return {
+      plugins,
+      options
+    }
+  })
+}
diff --git a/lib/style-compiler/plugins/scope-id.js b/lib/style-compiler/plugins/scope-id.js
new file mode 100644
index 0000000..dbcad9f
--- /dev/null
+++ b/lib/style-compiler/plugins/scope-id.js
@@ -0,0 +1,27 @@
+var postcss = require('postcss')
+var selectorParser = require('postcss-selector-parser')
+
+module.exports = postcss.plugin('add-id', function (opts) {
+  return function (root) {
+    root.each(function rewriteSelector (node) {
+      if (!node.selector) {
+        // handle media queries
+        if (node.type === 'atrule' && node.name === 'media') {
+          node.each(rewriteSelector)
+        }
+        return
+      }
+      node.selector = selectorParser(function (selectors) {
+        selectors.each(function (selector) {
+          var node = null
+          selector.each(function (n) {
+            if (n.type !== 'pseudo') node = n
+          })
+          selector.insertAfter(node, selectorParser.attribute({
+            attribute: opts.id
+          }))
+        })
+      }).process(node.selector).result
+    })
+  }
+})
diff --git a/lib/style-compiler/plugins/trim.js b/lib/style-compiler/plugins/trim.js
new file mode 100644
index 0000000..57163d8
--- /dev/null
+++ b/lib/style-compiler/plugins/trim.js
@@ -0,0 +1,11 @@
+var postcss = require('postcss')
+
+module.exports = postcss.plugin('trim', function (opts) {
+  return function (css) {
+    css.walk(function (node) {
+      if (node.type === 'rule' || node.type === 'atrule') {
+        node.raws.before = node.raws.after = '\n'
+      }
+    })
+  }
+})
diff --git a/lib/style-rewriter.js b/lib/style-rewriter.js
deleted file mode 100644
index 964ff85..0000000
--- a/lib/style-rewriter.js
+++ /dev/null
@@ -1,132 +0,0 @@
-var postcss = require('postcss')
-var loaderUtils = require('loader-utils')
-var loadPostcssConfig = require('postcss-load-config')
-var selectorParser = require('postcss-selector-parser')
-
-var addId = postcss.plugin('add-id', function (opts) {
-  return function (root) {
-    root.each(function rewriteSelector (node) {
-      if (!node.selector) {
-        // handle media queries
-        if (node.type === 'atrule' && node.name === 'media') {
-          node.each(rewriteSelector)
-        }
-        return
-      }
-      node.selector = selectorParser(function (selectors) {
-        selectors.each(function (selector) {
-          var node = null
-          selector.each(function (n) {
-            if (n.type !== 'pseudo') node = n
-          })
-          selector.insertAfter(node, selectorParser.attribute({
-            attribute: opts.id
-          }))
-        })
-      }).process(node.selector).result
-    })
-  }
-})
-
-var trim = postcss.plugin('trim', function (opts) {
-  return function (css) {
-    css.walk(function (node) {
-      if (node.type === 'rule' || node.type === 'atrule') {
-        node.raws.before = node.raws.after = '\n'
-      }
-    })
-  }
-})
-
-module.exports = function (css, map) {
-  this.cacheable()
-  var cb = this.async()
-
-  var query = loaderUtils.getOptions(this) || {}
-  var vueOptions = this.options.__vueOptions__
-
-  if (!vueOptions) {
-    if (query.hasInlineConfig) {
-      this.emitError(
-        `\n  [vue-loader] It seems you are using HappyPack with inline postcss ` +
-        `options for vue-loader. This is not supported because loaders running ` +
-        `in different threads cannot share non-serializable options. ` +
-        `It is recommended to use a postcss config file instead.\n` +
-        `\n  See http://vue-loader.vuejs.org/en/features/postcss.html#using-a-config-file for more details.\n`
-      )
-    }
-    vueOptions = Object.assign({}, this.options.vue, this.vue)
-  }
-
-  // use the same config loading interface as postcss-loader
-  loadPostcssConfig({ webpack: this }, null, { argv: false }).catch(() => {
-    // postcss-load-config throws error when no config file is found,
-    // but for us it's optional.
-  }).then(config => {
-    var plugins
-    var options
-
-    // inline postcss options for vue-loader
-    var rawInlineOptions = vueOptions.postcss
-    if (typeof rawInlineOptions === 'function') {
-      rawInlineOptions = rawInlineOptions.call(this, this)
-    }
-    if (Array.isArray(rawInlineOptions)) {
-      plugins = rawInlineOptions
-    } else if (isObject(rawInlineOptions)) {
-      plugins = rawInlineOptions.plugins
-      options = rawInlineOptions.options
-    }
-
-    plugins = [trim].concat(plugins || [])
-    options = Object.assign({
-      to: this.resourcePath,
-      from: this.resourcePath,
-      map: false
-    }, options)
-
-    // merge postcss config file
-    if (config && config.plugins) {
-      plugins = plugins.concat(config.plugins)
-    }
-    if (config && config.options) {
-      options = Object.assign({}, config.options, options)
-    }
-
-    // add plugin for vue-loader scoped css rewrite
-    if (query.scoped) {
-      plugins.push(addId({ id: query.id }))
-    }
-
-    // source map
-    if (
-      this.sourceMap &&
-      !this.minimize &&
-      vueOptions.cssSourceMap !== false &&
-      process.env.NODE_ENV !== 'production' &&
-      !options.map
-    ) {
-      options.map = {
-        inline: false,
-        annotation: false,
-        prev: map
-      }
-    }
-
-    postcss(plugins)
-      .process(css, options)
-      .then(function (result) {
-        var map = result.map && result.map.toJSON()
-        cb(null, result.css, map)
-        return null // silence bluebird warning
-      })
-      .catch(function (e) {
-        console.log(e)
-        cb(e)
-      })
-  })
-}
-
-function isObject (val) {
-  return val && typeof val === 'object'
-}
diff --git a/lib/template-compiler.js b/lib/template-compiler/index.js
similarity index 57%
rename from lib/template-compiler.js
rename to lib/template-compiler/index.js
index b9d0d92..e3b3092 100644
--- a/lib/template-compiler.js
+++ b/lib/template-compiler/index.js
@@ -1,67 +1,31 @@
-var compiler = require('vue-template-compiler')
-var transpile = require('vue-template-es2015-compiler')
 var loaderUtils = require('loader-utils')
+var normalize = require('../utils/normalize')
+var compiler = require('vue-template-compiler')
 var beautify = require('js-beautify').js_beautify
-var normalize = require('./normalize')
+var transpile = require('vue-template-es2015-compiler')
 var hotReloadAPIPath = normalize.dep('vue-hot-reload-api')
-
-// vue compiler module for using transforming `<tag>:<attribute>` to `require`
-var defaultTransformToRequire = {
-  img: 'src',
-  image: 'xlink:href'
-}
-var transformToRequire = defaultTransformToRequire
-var defaultCompileOptions = {
-  modules: [{
-    postTransformNode (el) {
-      for (var tag in transformToRequire) {
-        if (el.tag === tag && el.attrs) {
-          var attributes = transformToRequire[tag]
-          if (typeof attributes === 'string') {
-            el.attrs.some(attr => rewrite(attr, attributes))
-          } else if (Array.isArray(attributes)) {
-            attributes.forEach(item => el.attrs.some(attr => rewrite(attr, item)))
-          }
-        }
-      }
-    }
-  }]
-}
-
-function rewrite (attr, name) {
-  if (attr.name === name) {
-    var value = attr.value
-    var isStatic = value.charAt(0) === '"' && value.charAt(value.length - 1) === '"'
-    if (!isStatic) {
-      return
-    }
-    var firstChar = value.charAt(1)
-    if (firstChar === '.' || firstChar === '~') {
-      if (firstChar === '~') {
-        value = '"' + value.slice(2)
-      }
-      attr.value = `require(${value})`
-    }
-    return true
-  }
-}
+var transformRequire = require('./modules/transform-require')
 
 module.exports = function (html) {
   this.cacheable()
   var isServer = this.target === 'node'
   var isProduction = this.minimize || process.env.NODE_ENV === 'production'
+  var vueOptions = this.options.__vueOptions__ || {}
   var options = loaderUtils.getOptions(this) || {}
-  if (options.transformToRequire) {
-    transformToRequire = Object.assign(
-      {},
-      defaultTransformToRequire,
-      options.transformToRequire
-    )
+
+  var defaultModules = [transformRequire(options.transformToRequire)]
+  var userModules = vueOptions.compilerModules || options.compilerModules
+  // for HappyPack cross-process use cases
+  if (typeof userModules === 'string') {
+    userModules = require(userModules)
+  }
+
+  var compilerOptions = {
+    preserveWhitespace: options.preserveWhitespace,
+    modules: defaultModules.concat(userModules || [])
   }
 
-  var compiled = compiler.compile(html, Object.assign({
-    preserveWhitespace: options.preserveWhitespace
-  }, defaultCompileOptions))
+  var compiled = compiler.compile(html, compilerOptions)
 
   // tips
   if (compiled.tips && compiled.tips.length) {
@@ -102,6 +66,7 @@ module.exports = function (html) {
       '  }\n' +
       '}'
   }
+
   return code
 }
 
diff --git a/lib/template-compiler/modules/transform-require.js b/lib/template-compiler/modules/transform-require.js
new file mode 100644
index 0000000..d347670
--- /dev/null
+++ b/lib/template-compiler/modules/transform-require.js
@@ -0,0 +1,49 @@
+// vue compiler module for transforming `<tag>:<attribute>` to `require`
+
+var defaultOptions = {
+  img: 'src',
+  image: 'xlink:href'
+}
+
+module.exports = userOptions => {
+  var options = userOptions
+    ? Object.assign({}, defaultOptions, userOptions)
+    : defaultOptions
+
+  return {
+    postTransformNode: node => {
+      transform(node, options)
+    }
+  }
+}
+
+function transform (node, options) {
+  for (var tag in options) {
+    if (node.tag === tag && node.attrs) {
+      var attributes = options[tag]
+      if (typeof attributes === 'string') {
+        node.attrs.some(attr => rewrite(attr, attributes))
+      } else if (Array.isArray(attributes)) {
+        attributes.forEach(item => node.attrs.some(attr => rewrite(attr, item)))
+      }
+    }
+  }
+}
+
+function rewrite (attr, name) {
+  if (attr.name === name) {
+    var value = attr.value
+    var isStatic = value.charAt(0) === '"' && value.charAt(value.length - 1) === '"'
+    if (!isStatic) {
+      return
+    }
+    var firstChar = value.charAt(1)
+    if (firstChar === '.' || firstChar === '~') {
+      if (firstChar === '~') {
+        value = '"' + value.slice(2)
+      }
+      attr.value = `require(${value})`
+    }
+    return true
+  }
+}
diff --git a/lib/template-loader.js b/lib/template-compiler/preprocessor.js
similarity index 95%
rename from lib/template-loader.js
rename to lib/template-compiler/preprocessor.js
index e0690c8..860b099 100644
--- a/lib/template-loader.js
+++ b/lib/template-compiler/preprocessor.js
@@ -1,3 +1,5 @@
+// loader for pre-processing templates with e.g. pug
+
 var cons = require('consolidate')
 var loaderUtils = require('loader-utils')
 var extname = require('path').extname
diff --git a/lib/gen-id.js b/lib/utils/gen-id.js
similarity index 100%
rename from lib/gen-id.js
rename to lib/utils/gen-id.js
diff --git a/lib/normalize.js b/lib/utils/normalize.js
similarity index 70%
rename from lib/normalize.js
rename to lib/utils/normalize.js
index 4664486..dda06ce 100644
--- a/lib/normalize.js
+++ b/lib/utils/normalize.js
@@ -3,13 +3,13 @@ var fs = require('fs')
 var path = require('path')
 
 exports.lib = function (file) {
-  return path.resolve(__dirname, file)
+  return path.resolve(__dirname, '../', file)
 }
 
 exports.dep = function (dep) {
   if (IS_TEST) {
     return dep
-  } else if (fs.existsSync(path.resolve(__dirname, '../node_modules', dep))) {
+  } else if (fs.existsSync(path.resolve(__dirname, '../../node_modules', dep))) {
     // npm 2 or npm linked
     return 'vue-loader/node_modules/' + dep
   } else {
diff --git a/package.json b/package.json
index b09702a..71da958 100644
--- a/package.json
+++ b/package.json
@@ -1,6 +1,6 @@
 {
   "name": "vue-loader",
-  "version": "11.1.4",
+  "version": "11.2.0",
   "description": "Vue single-file component loader for Webpack",
   "main": "index.js",
   "repository": {
@@ -34,7 +34,7 @@
     "js-beautify": "^1.6.3",
     "loader-utils": "^1.0.2",
     "lru-cache": "^4.0.1",
-    "postcss": "^5.0.10",
+    "postcss": "^5.0.21",
     "postcss-load-config": "^1.1.0",
     "postcss-selector-parser": "^2.0.0",
     "source-map": "^0.5.6",
@@ -69,7 +69,6 @@
     "node-libs-browser": "^2.0.0",
     "normalize-newline": "^3.0.0",
     "null-loader": "^0.1.1",
-    "postcss": "^5.0.21",
     "pug": "^2.0.0-beta6",
     "raw-loader": "^0.5.1",
     "skeleton-loader": "0.0.5",


Test patch:
diff --git a/docs/ja/workflow/testing-with-mocks.md b/docs/ja/workflow/testing-with-mocks.md
new file mode 100644
index 0000000..7776fbe
--- /dev/null
+++ b/docs/ja/workflow/testing-with-mocks.md
@@ -0,0 +1,70 @@
+# モックを使用したテスト
+
+現実のアプリケーションでは、私たちのコンポーネントは外部依存関係を持つ可能性が高いです。コンポーネントの単体テストを記述するときは、外部依存関係をモックにし、テストはテスト対象のコンポーネントの動作に依存するだけになるのが理想です。
+
+`vue-loader` は、[inject-loader](https://github.com/plasticine/inject-loader)を使って任意の依存関係を `*.vue` コンポーネントに注入する機能を提供します。一般的な考え方としては、コンポーネントモジュールを直接インポートするのではなく、`inject-loader` を使用して、そのモジュール用の「モジュールファクトリ」関数を作成するというものです。この関数がモックのオブジェクトで呼び出されると、モックが注入されたモジュールのインスタンスが返されます。
+
+次のようなコンポーネントがあるとします：
+
+``` html
+<!-- example.vue -->
+<template>
+  <div class="msg">{{ msg }}</div>
+</template>
+
+<script>
+// この依存はモックを必要としています
+import SomeService from '../service'
+
+export default {
+  data () {
+    return {
+      msg: SomeService.msg
+    }
+  }
+}
+</script>
+```
+
+モックをインポートする方法は次のとおりです：
+
+> 注意: inject-loader@3.x は現在不安定です。
+
+``` bash
+npm install inject-loader@^2.0.0 --save-dev
+```
+
+``` js
+// example.spec.js
+const ExampleInjector = require('!!vue?inject!./example.vue')
+```
+
+注意。狂気じみた文字列を必要とします - ここではいくつかのインライン [webpack loader](https://webpack.github.io/docs/loaders.html）を使用しています。簡単な説明としては：
+
+- `!!`は "グローバル設定からすべてのローダを無効にする"ことを意味します；
+- `vue？inject！` は  "`vue` loader を使い、`？inject` クエリを渡す"ことを意味します。 これは `vue-loader` に、依存性注入モードでコンポーネントをコンパイルするように指示します。
+
+返される `ExampleInjector` は、`example.vue` モジュールのインスタンスを生成するために呼び出すことができるファクトリ関数です：
+
+``` js
+const ExampleWithMocks = ExampleInjector({
+  // モック
+  '../service': {
+    msg: 'Hello from a mocked service!'
+  }
+})
+```
+
+最後に、コンポーネントを通常どおりテストすることができます：
+
+``` js
+it('should render', () => {
+  const vm = new Vue({
+    template: '<div><test></test></div>',
+    components: {
+      'test': ExampleWithMocks
+    }
+  }).$mount()
+  expect(vm.$el.querySelector('.msg').textContent).toBe('Hello from a mocked service!')
+})
+```
diff --git a/docs/ja/workflow/testing.md b/docs/ja/workflow/testing.md
new file mode 100644
index 0000000..f060077
--- /dev/null
+++ b/docs/ja/workflow/testing.md
@@ -0,0 +1,101 @@
+# テスト
+
+> [webpack vue-cliテンプレート](https://github.com/vuejs-templates/webpack)には、事前に設定されたユニットテストとe2eテストの設定が用意されています。
+
+`* .vue`ファイルをテストするときには、普通の CommonJS ベースのテストランナーを使うことができません。なぜならそのテストランナーは `*.vue` ファイルの扱い方を知らないからです。代わりに、Webpack + vue-loader を使用してテストファイルをバンドルします。推奨設定は [Karma](http://karma-runner.github.io/0.13/index.html) と [karma-webpack](https://github.com/webpack/karma-webpack) です。
+
+Karma はブラウザを起動してテストを実行するテストランナーです。テストするブラウザと、使用するテストフレームワーク（たとえば、MochaやJasmineなど）を選択できます。[PhantomJS](http://phantomjs.org/) のテストを[Jasmine](http://jasmine.github.io/edge/introduction.html) テストフレームワークで実行する Karma の設定例を次に示します:
+
+``` bash
+npm install\
+  karma karma-webpack\
+  karma-jasmine jasmine-core\
+  karma-phantomjs-launcher phantomjs\
+  --save-dev
+```
+
+``` js
+// 要求があれば同じWebpackの設定を使用することが可能です
+// ただし、テスト中に元のエントリが不要なので、
+// 元のエントリを削除することを忘れないでください
+var webpackConfig = require('./webpack.config.js')
+delete webpackConfig.entry
+
+// karma.conf.js
+module.exports = function (config) {
+  config.set({
+    browsers: ['PhantomJS'],
+    frameworks: ['jasmine'],
+    // これはすべてのテストのエントリーファイルです。
+    files: ['test/index.js'],
+    // バンドルのためにエントリーファイルをwebpackに渡します。
+    preprocessors: {
+      'test/index.js': ['webpack']
+    },
+    // webpackの設定を使用します
+    webpack: webpackConfig,
+    // 不要なテキスト出力を回避します
+    webpackMiddleware: {
+      noInfo: true
+    },
+    singleRun: true
+  })
+}
+```
+
+そして`test/index.js`ファイルのエントリの場合：
+
+``` js
+// test/index.js
+// 特別なWebpackの機能を使用してすべてのテストファイルを必要とさせます
+// https://webpack.github.io/docs/context.html#require-context
+var testsContext = require.context('.', true, /\.spec$/)
+testsContext.keys().forEach(testsContext)
+```
+
+このエントリファイルは、単に同じフォルダ内の `.spec.js` で終わる他のすべてのファイルを必要とします。これで実際にいくつかのテストを書くことができます：
+
+``` js
+// test/component-a.spec.js
+var Vue = require('vue')
+var ComponentA = require('../../src/components/a.vue')
+
+describe('a.vue', function () {
+
+  // JavaScriptのオプションのアサーション
+  it('should have correct message', function () {
+    expect(ComponentA.data().msg).toBe('Hello from Component A!')
+  })
+
+  // 実際にコンポーネントをレンダリングしてレンダリングされた結果をアサートします
+  it('should render correct message', function () {
+    var vm = new Vue({
+      template: '<div><test></test></div>',
+      components: {
+        'test': ComponentA
+      }
+    }).$mount()
+    expect(vm.$el.querySelector('h2.red').textContent).toBe('Hello from Component A!')
+  })
+})
+```
+
+テストを実行するには、次の NPM スクリプトを追加します：
+
+``` js
+// package.json
+...
+"scripts": {
+  ...
+  "test": "karma start karma.conf.js"
+}
+...
+```
+
+最後に実行します：
+
+``` bash
+npm test
+```
+
+最後にもう一度、[こちらを参照してください](https://github.com/vuejs-templates/webpack)。テストに関する完全な実例が含まれています。
diff --git a/test/fixtures/custom-module.js b/test/fixtures/custom-module.js
new file mode 100644
index 0000000..ff11834
--- /dev/null
+++ b/test/fixtures/custom-module.js
@@ -0,0 +1,9 @@
+module.exports = [
+  {
+    postTransformNode: el => {
+      if (el.staticClass) {
+        el.staticClass = '"red blue"'
+      }
+    }
+  }
+]
diff --git a/test/fixtures/custom-module.vue b/test/fixtures/custom-module.vue
new file mode 100644
index 0000000..fd9dbe5
--- /dev/null
+++ b/test/fixtures/custom-module.vue
@@ -0,0 +1,5 @@
+<template>
+  <div style="flex-direction: row">
+    <span :style="{ transform }"></span>
+  </div>
+</template>
diff --git a/test/mock-loaders/docs.js b/test/mock-loaders/docs.js
new file mode 100644
index 0000000..5dc582a
--- /dev/null
+++ b/test/mock-loaders/docs.js
@@ -0,0 +1,5 @@
+module.exports = function (source, map) {
+  this.callback(null, 'module.exports = function(Component) {Component.options.__docs = ' +
+    JSON.stringify(source) +
+    '}', map)
+}
diff --git a/test/test.js b/test/test.js
index 6153927..8e49f28 100644
--- a/test/test.js
+++ b/test/test.js
@@ -634,6 +634,21 @@ describe('vue-loader', function () {
     })
   })
 
+  it('passes Component to custom block loaders', done => {
+    const mockLoaderPath = require.resolve('./mock-loaders/docs')
+    test({
+      entry: './test/fixtures/custom-language.vue',
+      vue: {
+        loaders: {
+          'documentation': mockLoaderPath
+        }
+      }
+    }, (window, module) => {
+      expect(module.__docs).to.contain('This is example documentation for a component.')
+      done()
+    })
+  })
+
   it('custom blocks can be ignored', done => {
     bundle({
       entry: './test/fixtures/custom-language.vue'
@@ -700,4 +715,50 @@ describe('vue-loader', function () {
       done()
     })
   })
+
+  it('custom compiler modules', done => {
+    test({
+      entry: './test/fixtures/custom-module.vue',
+      vue: {
+        compilerModules: [
+          {
+            postTransformNode: el => {
+              if (el.staticStyle) {
+                el.staticStyle = `$processStyle(${el.staticStyle})`
+              }
+              if (el.styleBinding) {
+                el.styleBinding = `$processStyle(${el.styleBinding})`
+              }
+            }
+          }
+        ]
+      }
+    }, (window, module) => {
+      var results = []
+      var vnode = mockRender(module, {
+        $processStyle: style => results.push(style),
+        transform: 'translateX(10px)'
+      })
+      expect(results).to.deep.equal([
+        { 'flex-direction': 'row' },
+        { 'transform': 'translateX(10px)' }
+      ])
+      done()
+    })
+  })
+
+  it('custom compiler modules (string)', done => {
+    test({
+      entry: './test/fixtures/basic.vue',
+      vue: {
+        compilerModules: require.resolve('./fixtures/custom-module')
+      }
+    }, (window, module) => {
+      var vnode = mockRender(module, {
+        msg: 'hi'
+      })
+      expect(vnode.data.staticClass).to.equal('red blue')
+      done()
+    })
+  })
 })