webpackを使って手動でコンパイルしたjsをrails6で読み込むことに成功

# 方針
railsでデフォルトで入っているgem webpackerを使わずにwebpackを使って手動でjsをコンパイルする。
entryファイル内でvue.jsを読み込み、componentを使ってアプリの見た目を作っていく。
webpackを使ってbuildされたjsをrailsアプリで読み込み、componentをアプリに読み込む。

# 現状の実装内容
画像の通りindex.html.erbにcomponentで定義したh1要素を表示させることに成功
![ChatVueApp.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/652172/bac35bb4-27d0-4f28-1dc5-d7ca5eff8ec2.png)


# 本日の実装の詳細

### ※最初にgitignoreが反映されていなかったので以下の手順にて修正

1.gitignoreを編集

2.以下のコマンドでcasheを削除

```
git rm -r --cached . //ファイル全体キャッシュ削除
```

3.commit & push

### いろいろろ設定をいじったらちゃんとwebpackでコンパイルしたjsを読み込めた

結論以下のことを行った

application.rbでassetsのコンパイル対象を変更

```ruby
config.assets.paths << Rails.root.join("public/javascripts")
```

assets.rbでjsとcssのコンパイル対象を増やす(application.rb書いても良さそう)

```ruby
Rails.application.config.assets.precompile += %w(*.js *.css)
Rails.application.config.assets.precompile << /(^[^_\/]|\/[^_])[^\/]*(\.js|\.css)$/
```

manifest.jsでpublick/javascripts以下のファイルを読み込むようにする

```js
//= link_directory ../../../public/javascripts .js
```

application.rbに記述しただけではpublic以下のファイルは読み込んでくれなさそう？な感じなので無理やりmanifest.jsで読み込むようにした。他にもやり方はありそうで、例えばwebpackを使ってコンパイルしたファイルをassets/javascritps内にbuildする方法とかもあるようだ。

で、これでrails sをすると…

**無事にブラウザ表示できた。**

しかし

## Failed to mount component: template or render function not definedと出た

ファッ！？

見た感じVue.jsで作ったcomponentが読み込めていなさそう。ちょっと調べてみるか…



こんな記事にヒット

http://howdy.hatenablog.com/entry/2016/11/08/230439

どうやらresolveの設定が必要らしい。

ということでwebpack.config.jsに以下の記述を追加

```js
resolve: {
    alias: {
      'vue$': 'vue/dist/vue.esm.js' // 'vue/dist/vue.common.js' for webpack 1
    }
  },
```



これで無事解決！！！！componentで設定したHello!を読み込んでくれました！

Sidebar.vue

```vue
<template>
  <h1>Hello!</h1>
</template>

<script>
</script>
```

App.vue

```vue
<template>
  <div>
    <sidebar></sidebar>
    <chat-container></chat-container>
  </div>
</template>

<script>
import Sidebar from './components/Sidebar.vue'
import ChatContainer from './components/ChatContainer.vue'

  export default {
    components:{
      Sidebar,
      ChatContainer
    }
  }
</script>
```

main.js

```js
import Vue from 'vue';
import App from './App.vue';

// App.vueをエントリとしてレンダリング
new Vue({
  el: '#app',
  render: h => h(App)
})
```

index.html.erb

```erb
<div id="app"></div>
```

![ChatVueApp.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/652172/b3e5e174-318f-557b-4c17-9ac16d32ea02.png)




いまいちなぜ解決したのか自分でも理解できていないので整理

```
When using vue-loader or vueify, templates inside *.vue files are pre-compiled into JavaScript at build time. You don’t really need the compiler in the final bundle, and can therefore use the runtime-only build.

Since the runtime-only builds are roughly 30% lighter-weight than their full-build counterparts, you should use it whenever you can. If you still wish to use the full build instead, you need to configure an alias in your bundler:
```

(参考：https://vuejs.org/v2/guide/installation.html#Runtime-Compiler-vs-Runtime-only)

この文章を見る限りvue-loaderを使っているときはruntime状態のファイルを使うことができるので完全にcompileしたファイルを使う必要がない。しかしそれでも完全にコンパイルされたファイルを使いたいのであればresolveの設定をする必要があります



と言っているように思う。そして今回私はvue-loaderを使っている。つまりvueファイルの読み込みの仕方が良くないのかもしれない？いまいちよくわからないが読み込めたのでOK。パフォーマンスの良し悪しとかはまた調べてみよう。