🎄teratailクリスマスプレゼントキャンペーン2024🎄』開催中!

\teratail特別グッズやAmazonギフトカード最大2,000円分が当たる!/

詳細はこちら
Vue.js

Vue.jsは、Webアプリケーションのインターフェースを構築するためのオープンソースJavaScriptフレームワークです。

Ruby on Rails

Ruby on Railsは、オープンソースのWebアプリケーションフレームワークです。「同じことを繰り返さない」というRailsの基本理念のもと、他のフレームワークより少ないコードで簡単に開発できるよう設計されています。

Q&A

解決済

1回答

1204閲覧

デプロイ時にwebpackのエントリ部分が読み込まれない

tsueken

総合スコア8

Vue.js

Vue.jsは、Webアプリケーションのインターフェースを構築するためのオープンソースJavaScriptフレームワークです。

Ruby on Rails

Ruby on Railsは、オープンソースのWebアプリケーションフレームワークです。「同じことを繰り返さない」というRailsの基本理念のもと、他のフレームワークより少ないコードで簡単に開発できるよう設計されています。

0グッド

0クリップ

投稿2021/01/25 19:08

編集2021/01/27 04:45

デプロイ時のwebpackのエントリ部分のみブラウザに表示されない状況を改善する方法について

現在、Railsアプリを開発しています。
また、フロントでVue.jsを用いるため、webpackを導入しています。

その際に参考にしたサイトが以下になります。
Rails に Webpack と Vue を導入しました!

ローカルではエラーもなく、ページは問題なく表示されています。
ですが、いざデプロイしてブラウザで確認するとエラーはないもののページの一部が正しく表示されません。
その表示されない箇所というのは、webpackで設定しているentryの部分です。

該当のソースコード

haml

1app/views/tops/index.html.haml 2 3#main-page-vue 4= javascript_include_tag webpack_asset_path('main.js') 5

=>現状のブラウザ上での表示

html

1 2<div id="main-page-vue"></div> 3<script src="/assets/js/main-520406f918935f7b68b0.js"></script>

vue

1import Vue from 'vue/dist/vue.esm' 2import router from '../router/router' 3import store from '../store/index' 4import Wrapper from '../Wrapper' 5 6document.addEventListener('DOMContentLoaded', () => { 7 const topPage = new Vue({ 8 router, 9 store, 10 el: '#main-page-vue', 11 beforeCreate () { 12 if (!this.$store.getters.userInfo.signedIn) { 13 this.$store.dispatch('asyncUserInfo') 14 } 15 }, 16 render: (h) => h(Wrapper) 17 }) 18 return topPage 19}) 20

その他のソースコード

ruby

1app/helper/application_helper.rb 2 3module ApplicationHelper 4 def webpack_asset_path(path) 5 return "http://localhost:8080/#{path}" if Rails.env.development? 6 host = Rails.application.config.action_controller.asset_host 7 manifest = Rails.application.config.assets.webpack_manifest 8 path = manifest[path] if manifest && manifest[path].present? 9 "#{host}/assets/js/#{path}" 10 end 11end

ruby

1config/initializers/assets.rb 2 3Rails.application.config.assets.version = '1.0' 4Rails.application.config.assets.paths << Rails.root.join('node_modules') 5webpack_manifest_path = Rails.root.join('public', 'assets', 'js', 'manifest.json') 6Rails.application.config.assets.webpack_manifest = 7 if File.exist?(webpack_manifest_path) 8 JSON.parse(File.read(webpack_manifest_path)) 9 end 10

ruby

1config/production.rb 2 3Rails.application.configure do 4 config.cache_classes = true 5 config.eager_load = true 6 config.consider_all_requests_local = false 7 config.action_controller.perform_caching = true 8 config.public_file_server.enabled = ENV['RAILS_SERVE_STATIC_FILES'].present? 9 config.assets.js_compressor = :uglifier 10 config.assets.compile = true 11 config.active_storage.service = :local 12 config.log_level = :debug 13 config.log_tags = [ :request_id ] 14 config.i18n.fallbacks = true 15 config.active_support.deprecation = :notify 16 config.log_formatter = ::Logger::Formatter.new 17 config.require_master_key = true 18 if ENV["RAILS_LOG_TO_STDOUT"].present? 19 logger = ActiveSupport::Logger.new(STDOUT) 20 logger.formatter = config.log_formatter 21 config.logger = ActiveSupport::TaggedLogging.new(logger) 22 end 23 config.active_record.dump_schema_after_migration = false 24end

js

1config/webpack/webpack.common.js 2 3const { VueLoaderPlugin } = require('vue-loader'); 4const { WebpackManifestPlugin } = require('webpack-manifest-plugin'); 5const { CleanWebpackPlugin } = require('clean-webpack-plugin'); 6const path = require('path'); 7const webpack = require('webpack') 8 9 10module.exports = { 11 context: path.resolve(__dirname, './../../app/src/entries'), 12 entry: { 13 article_bottoms: './articleBottoms.js', 14 article_leftside_menus: './articleLeftsideMenus.js', 15 main: './main.js', 16 }, 17 module: { 18 rules: [ 19 { 20 test: /.(sa|sc|c)ss$/, 21 use: ['style-loader', 22 { 23 loader: 'css-loader', 24 options: { url: false } 25 }, 26 ], 27 }, 28 { 29 test: /.(png|jpe?g)$/i, 30 use: [{ 31 loader: 'url-loader', 32 }] 33 }, 34 { 35 test: /.vue$/, 36 use: [ 37 { 38 loader: 'vue-loader', 39 options: { 40 postcss: [require('autoprefixer')({ grid: true })], 41 loaders: { 42 js: { 43 loader: 'babel-loader', 44 options: { presets: ['@babel/preset-env'] }, 45 }, 46 }, 47 }, 48 }, 49 { 50 loader: 'eslint-loader', 51 options: { 52 fix: true, 53 }, 54 }, 55 ] 56 }, 57 { 58 test: /.js$/, 59 exclude: /node_modules/, 60 use: [ 61 { 62 loader: 'babel-loader', 63 options: { 64 presets: [ 65 [ 66 '@babel/preset-env', 67 ], 68 ], 69 }, 70 }, 71 { 72 loader: 'eslint-loader', 73 options: { 74 fix: true, 75 failOnError: true, 76 }, 77 }, 78 ], 79 }, 80 ], 81 }, 82 plugins: [ 83 require('postcss-flexbugs-fixes'), 84 new VueLoaderPlugin(), 85 new CleanWebpackPlugin(), 86 new WebpackManifestPlugin({ 87 writeToFileEmit: true, 88 }), 89 new webpack.ProvidePlugin({ 90 'window.Quill': 'quill/dist/quill.js', 91 'Quill': 'quill/dist/quill.js' 92 }), 93 ], 94 resolve: { 95 extensions: ['.js', '.json', '.vue', '.ts'], 96 }, 97}; 98

js

1config/webpack/webpack.dev.js 2 3const path = require('path'); 4const { merge } = require('webpack-merge'); 5const common = require('./webpack.common'); 6 7module.exports = merge(common, { 8 mode: 'development', 9 output: { 10 path: path.resolve(__dirname, './../../public/assets/js'), 11 filename: '[name].js', 12 }, 13 watch: true, 14 devtool: 'inline-source-map', 15 devServer: { 16 contentBase: path.resolve(__dirname, './../../public/assets/js'), 17 watchContentBase: true, 18 inline: true, 19 hot: true, 20 }, 21 22});

js

1config/webpack/webpack.prod.js 2const { merge } = require('webpack-merge'); 3const common = require('./webpack.common'); 4const path = require('path'); 5const TerserPlugin = require('terser-webpack-plugin'); 6 7module.exports = merge(common, { 8 mode: 'production', 9 output: { 10 path: path.resolve(__dirname, './../../public/assets/js'), 11 filename: '[name]-[contenthash].js', 12 chunkFilename: '[name]-[contenthash].js' 13 }, 14 optimization: { 15 minimize: true, 16 minimizer: [ 17 new TerserPlugin({ 18 extractComments: 'all', 19 terserOptions: { 20 extractComments: false, 21 parallel: true, 22 compress: { 23 drop_console: true 24 }, 25 }, 26 }), 27 ], 28 splitChunks: { 29 chunks: 'initial', 30 cacheGroups: { 31 vendor: { 32 test: /node_modules/, 33 name: 'vendor', 34 }, 35 vendorsModules: { 36 test: /src[\/](modules|mixins|components|plugins|store|stylesheets)[\/]/, 37 name: 'vendor-modules', 38 minChunks: 2, 39 } 40 } 41 } 42 }, 43 performance: { 44 maxEntrypointSize: 800000 45 } 46})

試したこと

rails側で用意しているviewsは表示されている状況ということもあり、webpackの設定が正しくないのかと考え、記述に誤りがないかと思い、publicPathを指定するなど試してみたのですが、改善されませんでした。
また、デプロイ環境はEC2 + nginx + unicorn + capistranoで構築しており、
それぞれのログも確認しましたが、エラーが表示されいてる様子もありませんでした。

その他の可能性として、SprocketsやActionCable周辺も影響しているのかとも考えましたが、
解決に結びつくサイトも見つけることができず行き詰まっております。
何か、お気づきの点があれば、ご指摘いただけると幸いです。

参考サイト:
Rails に Webpack と Vue を導入しました!
RailsにWebpack+Vue.jsを、出来るだけ気楽に導入してみる
Ruby on Rails で sprockets から Webpacker へ移行し、移行できないものは共存させる方法

補足情報(FW/ツールのバージョンなど)

  • Ruby: 2.6.3

  • Ruby on Rails: 5.2.4.1

  • webpack: ^4.44.1

  • vue: ^2.6.12

  • unicorn: 5.8.0

  • capistrano: 3.15.0

気になる質問をクリップする

クリップした質問は、後からいつでもMYページで確認できます。

またクリップした質問に回答があった際、通知やメールを受け取ることができます。

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

guest

回答1

0

自己解決

自己解決しました。

SplitChunksPluginを使用していると
ビルドした際にwebpackの設定ファイルでcacheGroupsのブロック内で設定しているように
エントリーポイント間で共通したmodulesをバンドルしたファイルが作成されます。

js

1config/webpack/webpack.prod.js 2 3 optimization: { 4 splitChunks: { 5 chunks: 'initial', 6 cacheGroups: { 7 vendor: { 8 test: /node_modules/, 9 name: 'vendor', 10 }, 11 vendorsModules: { 12 test: /src[\/](modules|mixins|components|plugins|store|stylesheets)[\/]/, 13 name: 'vendor-modules', 14 minChunks: 2, 15 } 16 } 17 } 18 },

json

1manifest.json 2{ 3 "0.js": "0.js", # vue routerの 遅延ローディングを利用している場合にChunksされたファイル 4 "article_bottoms.js": "article_bottoms.js", # entry 1 5 "article_leftside_menus.js": "article_leftside_menus.js", # entry 2 6 "main.js": "main.js", # entry 3 7 "vendor.js": "vendor.js", # SplitChunksPluginでバンドルされたファイル => 今回の設定だとvendorブロック内で指定している node_modules 8 "vendor-modules.js": "vendor-modules.js" # SplitChunksPluginでバンドルされたファイル => 今回の設定だとvendorsModulesブロック内で指定している modules 9}

元々、import文でファイル間の紐付けができているからSplitChunksPluginで分割しても
てっきり、バンドルされたファイルの間での関連付けがされているものと
勝手な思い込みをしていたこともあって
なかなか解決に結びつかなかったのですが、
以下のようにviewでentry以外のバンドルファイルを呼び出してやる必要があったみたいです。

###修正前

haml

1index.html.haml # entry3 2 3#main-page-vue 4= javascript_include_tag webpack_asset_path('main.js')

###修正後

haml

1index.html.haml 2 3#main-page-vue 4= javascript_include_tag webpack_asset_path('main.js') 5= javascript_include_tag webpack_asset_path('vendor.js') 6= javascript_include_tag webpack_asset_path('vendor-modules.js') 7= javascript_include_tag webpack_asset_path('0.js')

こんなケースに出会す人はあまりいないでしょうが、情報共有しておきます。

投稿2021/02/06 11:15

tsueken

総合スコア8

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

15分調べてもわからないことは
teratailで質問しよう!

ただいまの回答率
85.36%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問