2019/05/12
現在の所、以下の内容はすでに時代遅れの可能性があるので、実際にコンパイル可能か保証出ません。
tl;dr
vue単一ファイルコンポーネント用の環境を用意しました。
サンプルをgithubにアップしていますので、git cloneなどして中身などを御覧ください。
(個人的には)最低限の構成をしています。
devinoue/webpack-vue-sample
やりたかったこと
Vue.jsでアプリケーションを作っていたところ、あまりにmethodsプロパティに多くを詰め込みすぎたため、そろそろ1ファイルに書き出すのは無理だと判断。フロントエンド界隈では標準ツールと言われるWebpackに手を出してみました。
自分は普段はPHPを中心に仕事をしているため、Webpackのようなファイルバンドラの経験がなく、せいぜいLaravel経由でMixを利用するぐらい。
Laravel使わなきゃバンドラを使えないんじゃダメなので、ひとまず以下のページを参照しながらWebpackをインストールしました。
最新版で学ぶwebpack 4入門 – JavaScriptのモジュールバンドラ
こちらのページであっさりとバンドルできました。便利ですね。
あとはVueもちょっと検索かければ簡単でしょう。
Vue-loaderを使えばいい……というわけではない。
「Vueはドキュメント多いよ」みたいな話をたくさん聞いていたので、あっさりとVueの単一ファイルコンポーネントをバンドルする方法のページが見つかりました。
たしかにドキュメントはたくさんあるのですが、動かない。エラーが出る。
エラー1 プラグインが設定されてない
エラーメッセージは以下の通りです
ERROR in ./src/components/App.vue
Module Error (from ./node_modules/vue-loader/lib/index.js):
vue-loader was used without the corresponding plugin. Make sure to include VueLoaderPlugin in your webpack config.
エラーがでる理由はvue-loader使用するに当たり、新たにプラグインが必要になったから。
過去の記事ではそれが記述されていないので、コピペではダメでした。
これはvue公式ページでも書かれています。
https://vue-loader.vuejs.org/migrating.html#a-plugin-is-now-required
ということで、プラグインの記述を追加
const { VueLoaderPlugin } = require('vue-loader');
//(省略)
plugins: [new VueLoaderPlugin()],
エラー2 Babelが動かない
ERROR in ./src/index.js
Module build failed (from ./node_modules/babel-loader/lib/index.js):
Error: Cannot find module '@babel/core'
babel-loader@8 requires Babel 7.x (the package '@babel/core'). If you'd like to use Babel 6.x ('babel-core'), you should install 'babel-loader@7'.
もう一度npm run
してみるも、またエラーが出ます。
どうもbabel-loaderとBabel coreのパッケージのバージョンが合ってない、と言いたいようです。
babel-loaderのバージョンとBabelのバージョンは揃って開発されているわけではなく、
loader 8 と Babel6では互換性がありません。
一方loader 8とBabel7ならイケると。
Module build failed (from ./node_modules/babel-loader/lib/index.js)
そして、Babel7がリリースしたのは2018年8月になってからなので、去年の記事はもう古くなっているかも、ということになってしまいます。
一番大きな変更点は、パッケージ名が変更されたことで、npmによるインストールも変わったということです。
旧・npm install babel-core babel-preset-es2015 -D
新・npm install @babel/core @babel/preset-env -D
これによりpackage.jsonや.babelrcの表記も変わってしまう。
ちょっとしたまとめ
vueのバンドルは簡単かなぁなどと思っていましたが、色々とバージョンアップのため予想以上に時間がかかりました。
ただ今まで使っては来ませんでしたが、こんな便利なものがあるんだなぁという発見にも繋がりました。
今回インストールしたパッケージをまとめておきます。
■WEBPACK関連
npm i -D webpack webpack-cli webpack-dev-server
■Babel関連
npm i -D @babel/core @babel/preset-env babel-loader
■vue.js関連
npm i -S vue
npm i -D vue-loader vue-template-compiler
■スタイルシート、SASSなど
npm i -D sass-loader node-sass style-loader css-loader
■もし万一すでにBabel関連をインストールしていたら事前にアンインストールしたほうがいいかもしれません。
npm uninstall -D babel-core babel-preset-env babel-loader webpack @babel/polyfill
なお、Babel関連も色々書き換え必須です。
以下重要そうな部分だけ書き出しますが、詳細はgithubからクローンして見た方が早いかもしれません。
{
"presets": [
[
"@babel/preset-env",
{
"useBuiltIns": "usage"
}
]
]
}
module: {
rules: [
{
test: /\.js$/,
exclude: /node_modules/,
use: {
loader: 'babel-loader',
options: {
presets: ['@babel/preset-env']
}
}
},
{
test: /\.vue$/,
loader: 'vue-loader'
},
{
test: /\.(scss|css)/,
use: [
'style-loader',
{
loader: 'css-loader',
options: {
// オプションでCSS内のurl()メソッドの取り込みを禁止する
url: false,
// ソースマップ
sourceMap: true,
// 0 => no loaders (default);
// 1 => postcss-loader;
// 2 => postcss-loader, sass-loader
importLoaders: 2
},
},
{
loader: 'sass-loader',
options: {
// ソースマップ
sourceMap: true,
}
}
]
}
]
},
resolve: {
alias: {
'vue$': 'vue/dist/vue.esm.js'
},
extensions: ['*', '.js', '.vue', '.json']
},
plugins: [new VueLoaderPlugin()],