Rails 6 Strategy To Use Vue Components And Dynamically Load Webpacker Assets

rails new demo --git --skip-sprockets --webpack=vue --database=postgresql
rails webpacker:install:erb
yarn add webpack webpack-cli pnp-webpack-plugin
yarn add turbolinks vue-turbolinks
yarn add rails-ujs activestorage css-loader
yarn add jquery bootstrap popper.js
yarn add axios vue-axios
const { environment } = require('@rails/webpacker')
const { VueLoaderPlugin } = require('vue-loader')
const vue = require('./loaders/vue')
const erb = require('./loaders/erb')
const webpack = require('webpack')
environment.plugins.append('Provide', new webpack.ProvidePlugin({
$: 'jquery',
jquery: 'jquery',
jQuery: 'jquery',
'window.jQuery': 'jquery',
Popper: ['popper.js', 'default'],
moment: 'moment'
}))
environment.plugins.prepend('VueLoaderPlugin', new VueLoaderPlugin())
environment.loaders.prepend('vue', vue)
environment.loaders.prepend('erb', erb)
module.exports = environment
import Vue from 'vue/dist/vue.esm';
<% components = Rails.application.root.join('app', 'javascript', 'components', '**', '*.vue') %>
<% Dir.glob(components).each do |path| %>
<% component = File.basename(path, ".vue") %>
import <%= component.underscore.camelize %> from "<%= path %>";
Vue.component("<%= component.underscore.dasherize %>", <%= component.underscore.camelize %>);
<% end %>
import Vue from 'vue/dist/vue.esm';
<% filters = Rails.application.root.join('app', 'javascript', 'filters', '**', '*.js') %>
<% Dir.glob(filters).each do |path| %>
<% filter = File.basename(path, ".js") %>
import <%= filter.underscore.camelize %> from "<%= path %>";
<% end %>
<% javascripts = Rails.application.root.join('app', 'javascript', 'javascripts', '**', '*.js') %>
<% Dir.glob(javascripts).each do |file| %>
import '<%= file %>';
<% end %>
<% images = Rails.application.root.join('app', 'javascript', 'images', '**', '*.{png,svg,jpg}') %>
<% Dir.glob(images).each do |image| %>
import '<%= image %>';
<% end %>
<% stylesheets = Rails.application.root.join('app', 'javascript', 'stylesheets', '**', '*.{css,scss}') %>
<% Dir.glob(stylesheets).each do |file| %>
import '<%= file %>';
<% end %>
import Rails from 'rails-ujs';
import Channels from 'channels';
import Turbolinks from 'turbolinks';
import * as ActiveStorage from 'activestorage';
import 'jquery';
import 'popper.js';
import 'bootstrap';
import 'bootstrap/dist/js/bootstrap';
Rails.start();
Turbolinks.start();
ActiveStorage.start();
import '../images/index.js.erb';
import '../stylesheets/index.js.erb';
import '../javascripts/index.js.erb';
console.log('Loaded Application');
import Vue from 'vue/dist/vue.esm';
import TurbolinksAdapter from 'vue-turbolinks';
import Axios from 'axios';
import VueAxios from 'vue-axios';

Vue.use(VueAxios, Axios);
Vue.use(TurbolinksAdapter);
import '../filters/index.js.erb';
import '../components/index.js.erb';
document.addEventListener('turbolinks:load', () => {
const element = document.getElementById('app');
if (element != null) {
const app = new Vue({}).$mount(element);
console.log("Loaded Vue", app);
}
});
<body>
<div id="app">
<%= yield %>
</div>
</body>
<%= stylesheet_pack_tag 'application', preload: true, media: 'all', 'data-turbolinks-track': 'reload' %>
<%= javascript_pack_tag 'application', 'data-turbolinks-track': 'reload' %>
<%= javascript_pack_tag 'vue_pack', 'data-turbolinks-track': 'reload' %>
<%= javascript_pack_tag 'erb_pack', 'data-turbolinks-track': 'reload' %>
web: bundle exec puma -C config/puma.rb
web: bundle exec rails s -p 3000 
webpack: ./bin/webpack-dev-server
foreman start -f Procfile.dev

--

--

Get the Medium app

A button that says 'Download on the App Store', and if clicked it will lead you to the iOS App store
A button that says 'Get it on, Google Play', and if clicked it will lead you to the Google Play store