4 | Test
5 | <%= csrf_meta_tags %>
6 |
7 | <%= stylesheet_link_tag 'application', media: 'all', 'data-turbolinks-track': 'reload' %>
8 | <%= javascript_include_tag 'application', 'data-turbolinks-track': 'reload' %>
9 |
10 |
11 |
12 | <%= yield %>
13 |
14 |
15 |
--------------------------------------------------------------------------------
/Rakefile:
--------------------------------------------------------------------------------
1 | begin
2 | require 'bundler/setup'
3 | rescue LoadError
4 | puts 'You must `gem install bundler` and `bundle install` to run rake tasks'
5 | end
6 |
7 | require 'rdoc/task'
8 |
9 | RDoc::Task.new(:rdoc) do |rdoc|
10 | rdoc.rdoc_dir = 'rdoc'
11 | rdoc.title = 'RailsVueMelt'
12 | rdoc.options << '--line-numbers'
13 | rdoc.rdoc_files.include('README.md')
14 | rdoc.rdoc_files.include('lib/**/*.rb')
15 | end
16 |
17 |
18 |
19 |
20 |
21 |
22 | require 'bundler/gem_tasks'
23 |
24 | require 'rspec/core/rake_task'
25 |
26 | RSpec::Core::RakeTask.new(:spec)
27 |
28 | task default: :spec
29 |
--------------------------------------------------------------------------------
/Gemfile:
--------------------------------------------------------------------------------
1 | source 'https://rubygems.org'
2 |
3 | # Declare your gem's dependencies in rails_vue_melt.gemspec.
4 | # Bundler will treat runtime dependencies like base dependencies, and
5 | # development dependencies will be added by default to the :development group.
6 | gemspec
7 |
8 | # Declare any dependencies that are still in development here instead of in
9 | # your gemspec. These might include edge Rails or gems from your path or
10 | # Git. Remember to move these dependencies to your gemspec before releasing
11 | # your gem to rubygems.org.
12 |
13 | # To use a debugger
14 | # gem 'byebug', group: [:development, :test]
15 |
--------------------------------------------------------------------------------
/lib/generators/vue_melt/vue_melt_generator.rb:
--------------------------------------------------------------------------------
1 | class VueMeltGenerator < Rails::Generators::Base
2 | source_root File.expand_path('../source', __FILE__)
3 |
4 | def create
5 | directory '.', 'app/javascript/packs/vue_melt'
6 | end
7 |
8 | def edit
9 | inject_into_file 'app/views/layouts/application.html.erb', before: /^\s*<\/head>/ do
10 | <<-EOS
11 | <%= javascript_pack_tag 'vue_melt/application' %>
12 |
13 | EOS
14 | end
15 |
16 | inject_into_file 'config/webpack/environment.js', before: /^module\.exports = environment$/ do
17 | <<-EOS
18 | environment.loaders.get('vue').options.extractCSS = false
19 | EOS
20 | end
21 | end
22 |
23 | def yarn
24 | run 'yarn add vuex vue-assign-model lodash.clonedeep'
25 | end
26 | end
27 |
--------------------------------------------------------------------------------
/rails_vue_melt.gemspec:
--------------------------------------------------------------------------------
1 | $:.push File.expand_path("../lib", __FILE__)
2 |
3 | # Maintain your gem's version:
4 | require "rails_vue_melt/version"
5 |
6 | # Describe your gem and declare its dependencies:
7 | Gem::Specification.new do |s|
8 | s.name = "rails_vue_melt"
9 | s.version = RailsVueMelt::VERSION
10 | s.authors = ["midnightSuyama"]
11 | s.email = ["midnightSuyama@gmail.com"]
12 | s.homepage = "https://github.com/midnightSuyama/rails_vue_melt"
13 | s.summary = "Rails view with webpack=vue optimizer"
14 | s.description = "Rails view with webpack=vue optimizer"
15 | s.license = "MIT"
16 |
17 | s.files = Dir["{app,config,db,lib}/**/*", "MIT-LICENSE", "Rakefile", "README.md"]
18 |
19 | s.add_dependency "rails", "~> 5.1"
20 | s.add_dependency "webpacker", "~> 3.0"
21 |
22 | s.add_development_dependency "rspec"
23 | s.add_development_dependency "generator_spec"
24 | end
25 |
--------------------------------------------------------------------------------
/lib/generators/vue_melt/source/application.js:
--------------------------------------------------------------------------------
1 | import Vue from 'vue/dist/vue.esm'
2 | import store from './store'
3 | import cloneDeep from 'lodash.clonedeep'
4 |
5 | import VueAssignModel from 'vue-assign-model'
6 | Vue.use(VueAssignModel)
7 |
8 | const storeState = cloneDeep(store.state)
9 | var vms = []
10 | var options = {}
11 | var requireContext = require.context("./options", false, /\.js$/)
12 | requireContext.keys().forEach(key => {
13 | let name = key.split('/').pop().split('.').shift()
14 | options[name] = requireContext(key).default
15 | })
16 |
17 | document.addEventListener('turbolinks:load', () => {
18 | let templates = document.querySelectorAll('[data-vue]')
19 | for (let el of templates) {
20 | let vm = new Vue(
21 | Object.assign(options[el.dataset.vue], { el, store })
22 | )
23 | vms.push(vm)
24 | }
25 | })
26 |
27 | document.addEventListener('turbolinks:visit', () => {
28 | for (let vm of vms) {
29 | vm.$destroy()
30 | }
31 | vms = []
32 | store.replaceState(cloneDeep(storeState))
33 | })
34 |
--------------------------------------------------------------------------------
/MIT-LICENSE:
--------------------------------------------------------------------------------
1 | Copyright 2017 midnightSuyama
2 |
3 | Permission is hereby granted, free of charge, to any person obtaining
4 | a copy of this software and associated documentation files (the
5 | "Software"), to deal in the Software without restriction, including
6 | without limitation the rights to use, copy, modify, merge, publish,
7 | distribute, sublicense, and/or sell copies of the Software, and to
8 | permit persons to whom the Software is furnished to do so, subject to
9 | the following conditions:
10 |
11 | The above copyright notice and this permission notice shall be
12 | included in all copies or substantial portions of the Software.
13 |
14 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
15 | EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
16 | MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
17 | NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
18 | LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
19 | OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
20 | WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
21 |
--------------------------------------------------------------------------------
/spec/vue_melt_generator_spec.rb:
--------------------------------------------------------------------------------
1 | require 'generator_spec'
2 | require File.expand_path('../../lib/generators/vue_melt/vue_melt_generator', __FILE__)
3 |
4 | describe VueMeltGenerator, type: :generator do
5 | destination File.expand_path("../tmp", __FILE__)
6 |
7 | before :all do
8 | prepare_destination
9 | mkdir_p "#{destination_root}/app/views/layouts"
10 | cp File.expand_path('fixtures/application.html.erb', File.dirname(__FILE__)), "#{destination_root}/app/views/layouts"
11 | mkdir_p "#{destination_root}/config/webpack"
12 | cp File.expand_path('fixtures/environment.js', File.dirname(__FILE__)), "#{destination_root}/config/webpack"
13 | run_generator
14 | end
15 |
16 | after :all do
17 | rm_rf destination_root
18 | system 'yarn remove vuex vue-assign-model lodash.clonedeep > /dev/null'
19 | end
20 |
21 | it 'creates vue_melt' do
22 | assert_file 'app/javascript/packs/vue_melt/application.js'
23 | assert_file 'app/javascript/packs/vue_melt/options'
24 | assert_file 'app/javascript/packs/vue_melt/components'
25 | assert_file 'app/javascript/packs/vue_melt/store'
26 | end
27 |
28 | it 'inserts javascript_pack_tag and turbolinks-cache-control' do
29 | content = File.read("#{destination_root}/app/views/layouts/application.html.erb")
30 | expect(content).to match(/\s*<%= javascript_pack_tag 'vue_melt\/application' %>\n\s*\n\s*<\/head>/)
31 | end
32 |
33 | it 'changes extractCSS' do
34 | content = File.read("#{destination_root}/config/webpack/environment.js")
35 | expect(content).to match(/environment\.loaders\.get\('vue'\)\.options\.extractCSS = false\nmodule\.exports = environment$/)
36 | end
37 |
38 | it 'installs package' do
39 | assert_file '../../node_modules/vuex'
40 | assert_file '../../node_modules/vue-assign-model'
41 | assert_file '../../node_modules/lodash.clonedeep'
42 | end
43 | end
44 |
--------------------------------------------------------------------------------
/Gemfile.lock:
--------------------------------------------------------------------------------
1 | PATH
2 | remote: .
3 | specs:
4 | rails_vue_melt (0.2.0)
5 | rails (~> 5.1)
6 | webpacker (~> 3.0)
7 |
8 | GEM
9 | remote: https://rubygems.org/
10 | specs:
11 | actioncable (5.1.2)
12 | actionpack (= 5.1.2)
13 | nio4r (~> 2.0)
14 | websocket-driver (~> 0.6.1)
15 | actionmailer (5.1.2)
16 | actionpack (= 5.1.2)
17 | actionview (= 5.1.2)
18 | activejob (= 5.1.2)
19 | mail (~> 2.5, >= 2.5.4)
20 | rails-dom-testing (~> 2.0)
21 | actionpack (5.1.2)
22 | actionview (= 5.1.2)
23 | activesupport (= 5.1.2)
24 | rack (~> 2.0)
25 | rack-test (~> 0.6.3)
26 | rails-dom-testing (~> 2.0)
27 | rails-html-sanitizer (~> 1.0, >= 1.0.2)
28 | actionview (5.1.2)
29 | activesupport (= 5.1.2)
30 | builder (~> 3.1)
31 | erubi (~> 1.4)
32 | rails-dom-testing (~> 2.0)
33 | rails-html-sanitizer (~> 1.0, >= 1.0.3)
34 | activejob (5.1.2)
35 | activesupport (= 5.1.2)
36 | globalid (>= 0.3.6)
37 | activemodel (5.1.2)
38 | activesupport (= 5.1.2)
39 | activerecord (5.1.2)
40 | activemodel (= 5.1.2)
41 | activesupport (= 5.1.2)
42 | arel (~> 8.0)
43 | activesupport (5.1.2)
44 | concurrent-ruby (~> 1.0, >= 1.0.2)
45 | i18n (~> 0.7)
46 | minitest (~> 5.1)
47 | tzinfo (~> 1.1)
48 | arel (8.0.0)
49 | builder (3.2.3)
50 | concurrent-ruby (1.0.5)
51 | diff-lcs (1.3)
52 | erubi (1.6.1)
53 | generator_spec (0.9.4)
54 | activesupport (>= 3.0.0)
55 | railties (>= 3.0.0)
56 | globalid (0.4.0)
57 | activesupport (>= 4.2.0)
58 | i18n (0.8.6)
59 | loofah (2.0.3)
60 | nokogiri (>= 1.5.9)
61 | mail (2.6.6)
62 | mime-types (>= 1.16, < 4)
63 | method_source (0.8.2)
64 | mime-types (3.1)
65 | mime-types-data (~> 3.2015)
66 | mime-types-data (3.2016.0521)
67 | mini_portile2 (2.2.0)
68 | minitest (5.10.3)
69 | nio4r (2.1.0)
70 | nokogiri (1.8.0)
71 | mini_portile2 (~> 2.2.0)
72 | rack (2.0.3)
73 | rack-proxy (0.6.2)
74 | rack
75 | rack-test (0.6.3)
76 | rack (>= 1.0)
77 | rails (5.1.2)
78 | actioncable (= 5.1.2)
79 | actionmailer (= 5.1.2)
80 | actionpack (= 5.1.2)
81 | actionview (= 5.1.2)
82 | activejob (= 5.1.2)
83 | activemodel (= 5.1.2)
84 | activerecord (= 5.1.2)
85 | activesupport (= 5.1.2)
86 | bundler (>= 1.3.0, < 2.0)
87 | railties (= 5.1.2)
88 | sprockets-rails (>= 2.0.0)
89 | rails-dom-testing (2.0.3)
90 | activesupport (>= 4.2.0)
91 | nokogiri (>= 1.6)
92 | rails-html-sanitizer (1.0.3)
93 | loofah (~> 2.0)
94 | railties (5.1.2)
95 | actionpack (= 5.1.2)
96 | activesupport (= 5.1.2)
97 | method_source
98 | rake (>= 0.8.7)
99 | thor (>= 0.18.1, < 2.0)
100 | rake (12.0.0)
101 | rspec (3.6.0)
102 | rspec-core (~> 3.6.0)
103 | rspec-expectations (~> 3.6.0)
104 | rspec-mocks (~> 3.6.0)
105 | rspec-core (3.6.0)
106 | rspec-support (~> 3.6.0)
107 | rspec-expectations (3.6.0)
108 | diff-lcs (>= 1.2.0, < 2.0)
109 | rspec-support (~> 3.6.0)
110 | rspec-mocks (3.6.0)
111 | diff-lcs (>= 1.2.0, < 2.0)
112 | rspec-support (~> 3.6.0)
113 | rspec-support (3.6.0)
114 | sprockets (3.7.1)
115 | concurrent-ruby (~> 1.0)
116 | rack (> 1, < 3)
117 | sprockets-rails (3.2.1)
118 | actionpack (>= 4.0)
119 | activesupport (>= 4.0)
120 | sprockets (>= 3.0.0)
121 | thor (0.19.4)
122 | thread_safe (0.3.6)
123 | tzinfo (1.2.3)
124 | thread_safe (~> 0.1)
125 | webpacker (3.0.1)
126 | activesupport (>= 4.2)
127 | rack-proxy (>= 0.6.1)
128 | railties (>= 4.2)
129 | websocket-driver (0.6.5)
130 | websocket-extensions (>= 0.1.0)
131 | websocket-extensions (0.1.2)
132 |
133 | PLATFORMS
134 | ruby
135 |
136 | DEPENDENCIES
137 | generator_spec
138 | rails_vue_melt!
139 | rspec
140 |
141 | BUNDLED WITH
142 | 1.14.2
143 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | # RailsVueMelt
2 |
3 | [](http://badge.fury.io/rb/rails_vue_melt)
4 | [](https://circleci.com/gh/midnightSuyama/rails_vue_melt)
5 |
6 | Rails view with webpack=vue optimizer
7 |
8 | ## Installation
9 |
10 | Add this line to your application's Gemfile:
11 |
12 | ```ruby
13 | gem 'rails_vue_melt'
14 | ```
15 |
16 | And then execute:
17 |
18 | $ bundle
19 |
20 | Or install it yourself as:
21 |
22 | $ gem install rails_vue_melt
23 |
24 | ## Usage
25 |
26 | $ rails new APP_PATH --webpack=vue
27 | ...
28 | $ rails generate vue_melt
29 |
30 | ### Generate
31 |
32 | #### create `app/javascript/packs/vue_melt`
33 |
34 | * application.js
35 | * options/
36 | * users.js
37 | * components/
38 | * Hello.vue
39 | * store/
40 | * index.js
41 | * getters.js
42 | * actions.js
43 | * mutations.js
44 | * mutation-types.js
45 |
46 | #### insert `app/views/layouts/application.html.erb`
47 |
48 | ```html
49 | <%= javascript_pack_tag 'vue_melt/application' %>
50 |
51 | ```
52 |
53 | #### insert `config/webpack/environment.js`
54 |
55 | ```javascript
56 | environment.loaders.get('vue').options.extractCSS = false
57 | ```
58 |
59 | #### install packages
60 |
61 | * [vuex](https://www.npmjs.com/package/vuex)
62 | * [vue-assign-model](https://www.npmjs.com/package/vue-assign-model)
63 | * [lodash.clonedeep](https://www.npmjs.com/package/lodash.clonedeep)
64 |
65 | ### Example
66 |
67 | ```erb
68 |
69 |
70 |
71 |
72 |
User Name: {{ user.name }}
73 |
74 |
75 |
76 | ```
77 |
78 | Add `data-vue` attribute, the value is file name in `app/javascript/packs/vue_melt/options`. Vue instance is mounted at `turbolinks:load` event and unmounted at `turbolinks:visit` event.
79 |
80 | Before Vue rendering, `value`, `checked` or `selected` attributes of elements with `v-model` is automatically assigned to Vue model. Therefore, `form_with` and so on using Active Model can use data binding easily.
81 |
82 | #### accepts_nested_attributes_for
83 |
84 | JSON of `data-vue-model` is assigned to Vue model. Also, `v-model` with prefix `_` is not assigned for `v-for` scope.
85 |
86 | ```erb
87 |
88 |
89 |
120 | ```
121 |
122 | ## Development
123 |
124 | To install this gem onto your local machine, run `bundle exec rake install`. To release a new version, update the version number in `version.rb`, and then run `bundle exec rake release`, which will create a git tag for the version, push git commits and tags, and push the `.gem` file to [rubygems.org](https://rubygems.org).
125 |
126 | ## Contributing
127 |
128 | Bug reports and pull requests are welcome on GitHub at https://github.com/midnightSuyama/rails_vue_melt.
129 |
130 | ## License
131 | The gem is available as open source under the terms of the [MIT License](http://opensource.org/licenses/MIT).
132 |
--------------------------------------------------------------------------------