はじめに
特にwebpackなどを使用して、Vue.jsをこれからはじめようという方に多いとは思いますが、以下のようなエラーがコンソールに出力されることがあります。
[Vue warn]: You are using the runtime-only build of Vue where the template compiler is not available. Either pre-compile the templates into render functions, or use the compiler-included build.
翻訳すると以下の通りです。
テンプレートコンパイラが利用できないVueのランタイムのみのビルドを使用しています。 テンプレートをレンダリング関数にプリコンパイルするか、コンパイラに含まれているビルドを使用します。
Vue.jsには「ランタイム + コンパイラ」のパッケージと「ランタイムのみ」のパッケージがあり、上記のエラーは「ランタイムのみ」のパッケージを使用しているときに出力されます。
「ランタイムのみ」のパッケージを使用すると、「ランタイム + コンパイラ」のパッケージを使用する場合に比べて3割程度ファイルサイズが軽くなります。
このエラーの解決方法としては、以下のいずれかの対応が必要です。
- 「ランタイムのみ」の方の使用を続けてrender関数を使う
- 「ランタイム + コンパイラ」の方のVue.jsを使用する
一般的に新規構築の場合は「ランタイムのみ」の方を使用すると思いますし、プロジェクトの途中からVue.jsを導入する場合には「ランタイム + コンパイラ」の方を使用することもあると思います。
エラーが出ているコードの例
例えば以下のようなhtmlとjsを書いてエラーが出ていたとします。
example.html
<!DOCTYPE html> <html> <head> <meta http-equiv="X-UA-Compatible" content="IE=edge"> <meta charset="utf-8"> <title>vue-tutorial</title> </head> <body> <div id="app"></div> <script type="text/javascript" src="packed/javascripts/index.bundle.js"></script> </body> </html>
example.js
以下のようにtemplateオプションを使用していて、ランタイムのみのVue.jsを使用していると表題のエラーメッセージが表示されます。
import Vue from 'vue'; new Vue({ el: '#app', template: `<div>example</div>`, });
解決する
1. render関数を使う
解決方法のひとつめを紹介します。
新規構築する場合はこちらの方法を使用するのが良いと思います。
ランタイムのみのVue.jsパッケージを使用する場合は、render関数を使用して以下のように記述するように公式ドキュメントに記載があります。
import Vue from 'vue'; new Vue({ el: '#app', render (h) { return h('div', 'example') } });
ただ、公式ドキュメントに記述してあるこのままでは、単一Vueコンポーネントを使用して書くにはどうしたら良いかわからない方もいるかもしれません。
単一Vueコンポーネントを使用するには以下のように記述します。
import Vue from 'vue'; import App from './path/to/App.vue'; new Vue({ el: '#app', render (h) { return h(App); }, });
2. 「ランタイム + コンパイラ」の方のVue.jsを使用する
解決方法のふたつめを紹介します。
webpack.config.jsのaliasを設定して、「ランタイム + コンパイラ」の方をimportするようにします。
webpack.config.jsを以下のように設定することで、「ランタイム + コンパイラ」の方をimportできるようになります。
module.exports = { 〜略〜 resolve: { alias: { // import Vue from 'vue'; と記述したときの 'vue' が表すファイルパスを設定 'vue$': 'vue/dist/vue.esm.js' }, }, }
実際にはwebpack.config.jsで他にも色々と設定していると思いますが、省略してaliasの部分だけ記述しています。