vue.jsをrails6で動かすためにwebpack.config.jsを設定してたらエラー出過ぎて草


webpack CLIを動かせるようにしてみる

webpack.config.jsを設定しているのでその設定が正しいかの確認ができればと思いやってみた。

このようなファイル構成にしているのでfrontendディレクトリで以下のコマンドを実行してみた。

webpack --config webpack.config.js

すると以下のように表示される。

webpack --config webpack.config.js
CLI for webpack must be installed.
  webpack-cli (https://github.com/webpack/webpack-cli)

We will use "npm" to install the CLI via "npm install -D".
Do you want to install 'webpack-cli' (yes/no): yes

どうやらwebpackをCLIで動かすためのツールが必要そうである。インストールしますか?と聞かれているので素直にyesと回答

Error: Cannot find module 'webpack-cli/package.json'

するとエラーが発生した。おいおいなんでや…

npm install -g webpack-cli

ということでやむなくグローバルインストールを試すことに。

/usr/local/bin/webpack-cli -> /usr/local/lib/node_modules/webpack-cli/bin/cli.js
npm WARN [email protected] requires a peer of [email protected] || 5.x.x but none is installed. You must install peer dependencies yourself.

+ [email protected]
added 46 packages from 31 contributors in 4.209s

お、インストールできたっぽい。

これで

webpack --config webpack.config.js

このコマンドでwebpack.config.jsを読み込むことができるようになった。やった!

次はwebpack.config.jsの設定に移ろう。

一段落したので遭遇したエラーと対処法をまとめた。

webpack --config webpack.config.js

このコマンドを打つとwebpack.config.jsを読み込んでくれるのでそこで出たエラーを紹介。このエラーを解消しないとwebpacl.config.jsが動かないので…

configuration.module has an unknown property 'loaders'.

configuration.module has an unknown property 'loaders'. These properties are valid:
   object { defaultRules?, exprContextCritical?, exprContextRecursive?, exprContextRegExp?, exprContextRequest?, noParse?, rules?, strictExportPresence?, strictThisContextOnImports?, unknownContextCritical?, unknownContextRecursive?, unknownContextRegExp?, unknownContextRequest?, unsafeCache?, wrappedContextCritical?, wrappedContextRecursive?, wrappedContextRegExp? }
   -> Options affecting the normal modules (`NormalModuleFactory`).

vue-loaderを読み込むために以下のように記述したところ上記エラーに遭遇

module: {
    loaders: [ ここ
      {
        loader: 'vue-loader'

おい!なんでや!となったが代替案も出してくれてたのでそれに倣うことにした。

Did you mean module.rules or module.rules.*.use?
module: {
    rules: [
      {
        loader: 'vue-loader'
      }
    ]
  },

loadersをrulesに修正して解決。

TypeError: this._init is not a function at Object.vue

TypeError: this._init is not a function
    at Object.Vue 

vueオブジェクトのコンストラクタが動いていなさそうな感じ。調べたら即解決した。

module: {
    rules: [
      {
        loader: 'vue-loader'
      }
    ]
  },

loaderの部分でvue-loaderを読み込む設定が必要だった。

[vue-loader] vue-template-compiler must be installed as a peer dependency,

なんか設定がたりなさそう。調べたところ指示された通りcompilerをインストールすれば良さそう

npm install vue-template-compiler --save-dev

これで解決

vue-loader was used without the corresponding plugin. Make sure to include VueLoaderPlugin in your webpack config.

なんか今度はpluginが足りませんと出る。

これも調べたらwebpack.config.js内でプラグインを導入すればいいことに気づき、以下のように記述

const { VueLoaderPlugin } = require("vue-loader");
module.exports = {
 (省略)
  plugins: [new VueLoaderPlugin()]
}

requireも記述しないと以下のエラーが出てしまう

ReferenceError: VueLoaderPlugin is not defined

No matching rule for .vue files found.

これも調べたところconfig内にvueを読み込む設定が必要とのことで以下のように記述

module: {
    rules: [
      {
        test: /\.vue$/, #ここ
        exclude: /node_modules/,
        loader: 'vue-loader'
      }
    ]
  },

testの部分で.vueを読み込むようにした。

The output directory as absolute path (required).

output: {
    path: `${__dirname}/../public/javascripts`,
    filename: '[name].js'
  },

config内のoutput.pathが相対パスだと上記エラーになる。とはいえ絶対パスだと後々不便。と思って調べてたらdirnameというのを使うと良いとあったので使用。これは現在いるパスを変数化するものらしく絶対パスで参照してくれるようだ。

で、ここまでエラーを乗り越えるとようやくconfigが動くようになった。

webpack --config webpack.config.js

これをすると

entryのファイルを使ってoutputに書かれたjsを出力してくれる。

今回はpuclicのjavascriptsディレクトリに出力した。

もう少し設定しないとrailsアプリで動かなさそうなので引き続き実装頑張ります…

【参考】

・webpack.config.jsで絶対パス指定を使わずに表記する方法

・VueLoaderPlugin Error] No matching rule for .vue files found - when files have different extension than .vueへの対処法

・【webpack】vue-loader was used without the corresponding plugin. Make sure to include VueLoaderPlugin in your webpack config.への対処法

・【webpack】[vue-loader] vue-template-compiler must be installed as a peer dependency, or a compatible compiler implementation must be passed via options.への対処法

・Module build failed: TypeError: this._init is not a functionと出た

・loadersプロパティが使えない!と言われたときの対処法