vue_cli-rails 0.2.0 → 0.3.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/README.md +256 -19
- data/lib/helpers/scripts/vue_create.rb +28 -4
- data/lib/source/app/assets/vue/components/HelloWorld.vue +20 -0
- data/lib/source/app/assets/vue/entry_points/bar.js +9 -0
- data/lib/source/app/assets/vue/entry_points/foo.js +4 -0
- data/lib/source/app/assets/vue/{components/views → views}/Bar.vue +0 -0
- data/lib/source/app/assets/vue/views/Foo.vue +21 -0
- data/lib/source/app/controllers/vue_demo_controller.rb +11 -0
- data/lib/source/app/views/layouts/{vue.html.erb → vue_demo.html.erb} +2 -2
- data/lib/source/app/views/{vue → vue_demo}/foo.html.erb +0 -0
- data/lib/source/vue.rails.js +17 -6
- data/lib/source/vue.yml +2 -3
- data/lib/vue_cli/rails/configuration.rb +24 -20
- data/lib/vue_cli/rails/engine.rb +26 -6
- data/lib/vue_cli/rails/helper.rb +9 -12
- data/lib/vue_cli/rails/node_env.rb +1 -1
- data/lib/vue_cli/rails/version.rb +1 -1
- metadata +11 -11
- data/lib/source/app/assets/vue/components/views/Foo.vue +0 -17
- data/lib/source/app/assets/vue/views/bar.js +0 -4
- data/lib/source/app/assets/vue/views/foo.js +0 -4
- data/lib/source/app/controllers/vue_controller.rb +0 -7
- data/lib/source/app/views/vue/bar.html.erb +0 -1
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: e23e30ec06f2e4f661258507ac78cca3ee9b9e2f583fac001b231cfc0194d00f
|
4
|
+
data.tar.gz: 4fe54577949add5a0739a612bf501ef667c1ac7b3964c0c9e7423f1019d0a46a
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: e866c1167152e328b6b1d750dfabcc88ecf495342d493153e319bd2309d85e6554b2d92bae1a95c7545c65631415486765f14e965505f56f10d3de71f4a10a8c
|
7
|
+
data.tar.gz: d9178061fe4134ab393c386cafd3530aa7fa2e7d3f3d7d485f540fb539f000b87fca2c7b542919e98a7002efaef1f870d6e265113893f25e8b6a0d7352af3747
|
data/README.md
CHANGED
@@ -28,9 +28,12 @@ And then execute:
|
|
28
28
|
- Feel free to use `yarn` or `npm`.
|
29
29
|
- Single `vue_entry` rather than confusing `stylesheet_pack_tag`, `javascript_packs_tag` and `javascript_packs_with_chunks_tag`.
|
30
30
|
- Get all benefits of [@vue/cli](https://cli.vuejs.org/).
|
31
|
-
|
32
|
-
|
33
|
-
|
31
|
+
|
32
|
+
- Powered by `webpack` 4
|
33
|
+
- DRY: all-in-one configuration file rather than repeating for `webpack`, `eslint` and etc.
|
34
|
+
- Out-of-box tooling: Babel, TypeScript, PWA, `vue-router`, `vuex`, CSS pre-processors, linter and testing tools.
|
35
|
+
- Enhanced alias support in `jest.config.js`.
|
36
|
+
|
34
37
|
- Run `webpack-dev-server` together with Rails server with development mode.
|
35
38
|
- Just single `RAILS_ENV`, no more `NODE_ENV`.
|
36
39
|
- Rails way configurations in `config/vue.yml`.
|
@@ -40,9 +43,13 @@ And then execute:
|
|
40
43
|
Out-of-box workflow:
|
41
44
|
|
42
45
|
1. `bundle exec rake vue:create` and follow the steps.
|
43
|
-
|
44
|
-
|
45
|
-
|
46
|
+
|
47
|
+
> Don NOT select `In package.json` for "Where do you prefer placing config for Babel, PostCSS, ESLint, etc.?". Some functionalities like alias of jest may not work.
|
48
|
+
|
49
|
+
2. Put your JavaScript files under `app/assets/vue/entry_points`.
|
50
|
+
3. Insert your entry point by `vue_entry 'entry_point'` in views or `render_vue 'entry_point'` in controllers.
|
51
|
+
4. `webpack-dev-server` auto starts alongside `rails server` in dev mode.
|
52
|
+
5. Invoke `env RAILS_ENV=production bundle exec rake vue:compile` to compile assets (you still must manually set `RAILS_ENV` to `production`).
|
46
53
|
|
47
54
|
> More settings are available in `config/vue.yml`
|
48
55
|
|
@@ -52,9 +59,11 @@ Out-of-box workflow:
|
|
52
59
|
|
53
60
|
#### Concept: Entry Point and File structure
|
54
61
|
|
55
|
-
|
62
|
+
The root path of your Vue assets is `app/assets/vue`. This gem will generate several folders. However, `app/assets/vue/entry_points` is the only one matters.
|
56
63
|
|
57
|
-
|
64
|
+
Webpack sees one JavaScript file as the center of a web page rather than HTML. Thus all styles, images, fonts and other assets are related to a JS files by `import 'css/png/svg/woff2/json'`. Any `.js` file under `app/assets/vue/entry_points` will be a entry-point.
|
65
|
+
|
66
|
+
Please ONLY puts your entry-point files under `app/assets/vue/entry_points` folder with `.js` extension name.
|
58
67
|
|
59
68
|
> Be aware, `.js.erb` and `.vue.erb` are NOT supported. I will explain the reason in [Q&A section](#difference-from-webpacker).
|
60
69
|
|
@@ -62,7 +71,7 @@ If you are new to modern front-end development, or more specifically with `webpa
|
|
62
71
|
|
63
72
|
#### Helper `vue_entry`
|
64
73
|
|
65
|
-
`vue_entry` is like `javascript_include_tag` and `stylesheet_link_tag` which generates relative assets links for your entry point. (It's like
|
74
|
+
`vue_entry` is like `javascript_include_tag` and `stylesheet_link_tag` which generates relative assets links for your entry point. (It's like `javascript_packs_with_chunks_tag` in Webpacker 4. I will explain why it's different in [Q&A](#qa).)
|
66
75
|
|
67
76
|
> You may have interest of path alias in `config/vue.yml`.
|
68
77
|
|
@@ -74,12 +83,11 @@ If you are new to modern front-end development, or more specifically with `webpa
|
|
74
83
|
[+] app
|
75
84
|
[+] assets
|
76
85
|
[+] vue
|
77
|
-
[+]
|
78
|
-
[+] views - alias `~views`
|
79
|
-
[-] FooBar.vue - Vue component for `foo/bar`
|
80
|
-
[+] views - Folder for entry points
|
86
|
+
[+] entry_points - Folder for entry points
|
81
87
|
[+] foo
|
82
88
|
[-] bar.js - entry point: import '~views/FooBar.vue'
|
89
|
+
[+] views - alias `~views`
|
90
|
+
[-] FooBar.vue - Vue component for `foo/bar`
|
83
91
|
[+] controllers
|
84
92
|
[+] foo_controller.rb - controller
|
85
93
|
[+] views
|
@@ -94,7 +102,7 @@ If you are new to modern front-end development, or more specifically with `webpa
|
|
94
102
|
```yaml
|
95
103
|
# default
|
96
104
|
alias:
|
97
|
-
~views: app/assets/vue/
|
105
|
+
~views: app/assets/vue/views
|
98
106
|
```
|
99
107
|
|
100
108
|
- Your controller:
|
@@ -117,7 +125,7 @@ If you are new to modern front-end development, or more specifically with `webpa
|
|
117
125
|
- Entry point JS:
|
118
126
|
|
119
127
|
```js
|
120
|
-
// file - app/assets/vue/
|
128
|
+
// file - app/assets/vue/entry_points/foo/bar.js
|
121
129
|
import Vue from 'vue';
|
122
130
|
|
123
131
|
import Foo from '~views/FooBar.vue';
|
@@ -130,7 +138,7 @@ If you are new to modern front-end development, or more specifically with `webpa
|
|
130
138
|
- Your Vue component for your entry point:
|
131
139
|
|
132
140
|
```vue
|
133
|
-
// file - app/assets/vue/
|
141
|
+
// file - app/assets/vue/views/FooBar.vue
|
134
142
|
<template>
|
135
143
|
<div id="foo-bar">
|
136
144
|
<h1>Foo/bar</h1>
|
@@ -168,6 +176,55 @@ If you are new to modern front-end development, or more specifically with `webpa
|
|
168
176
|
|
169
177
|
</details>
|
170
178
|
|
179
|
+
#### Use `render_vue` in controllers
|
180
|
+
|
181
|
+
Usually you only need `<div id="app"></div>` and `vue_entry 'entry/point'` to render a Vue page. You can use `render_vue 'entry/point'` inside your controller.
|
182
|
+
|
183
|
+
This method is simply a wrap of `render html: vue_entry('entry_point'), layout: true`. So you can pass any arguments supported by `render` including `layout`.
|
184
|
+
|
185
|
+
<details><summary>For example</summary>
|
186
|
+
|
187
|
+
```ruby
|
188
|
+
# app/controllers/my_vue_controller
|
189
|
+
class MyVueController < ApplicationController
|
190
|
+
layout 'vue_base'
|
191
|
+
|
192
|
+
def foo
|
193
|
+
render_vue 'foo/bar'
|
194
|
+
end
|
195
|
+
end
|
196
|
+
```
|
197
|
+
|
198
|
+
```html
|
199
|
+
<!-- app/views/layouts/vue_base.erb -->
|
200
|
+
<!DOCTYPE html>
|
201
|
+
<html>
|
202
|
+
<head>
|
203
|
+
<title>My Vue</title>
|
204
|
+
</head>
|
205
|
+
<body>
|
206
|
+
<div id="app"></div>
|
207
|
+
<%= yield %>
|
208
|
+
</body>
|
209
|
+
</html>
|
210
|
+
```
|
211
|
+
|
212
|
+
```js
|
213
|
+
// app/assets/vue/entry_points/foo/bar.js
|
214
|
+
|
215
|
+
import Vue from 'vue';
|
216
|
+
|
217
|
+
import Bar from '../views/Bar.vue';
|
218
|
+
|
219
|
+
Vue.config.productionTip = false;
|
220
|
+
|
221
|
+
new Vue({
|
222
|
+
render: h => h(Bar),
|
223
|
+
}).$mount('#app');
|
224
|
+
```
|
225
|
+
|
226
|
+
</details>
|
227
|
+
|
171
228
|
#### Public Output Path
|
172
229
|
|
173
230
|
If the default setting `vue_assets` does not bother you at all, you can ignore this section.
|
@@ -192,13 +249,19 @@ Actually `public_output_path` in `config/vue.yml` is very simple - just a sub pa
|
|
192
249
|
|
193
250
|
</details>
|
194
251
|
|
252
|
+
#### Summary
|
253
|
+
|
254
|
+
If you still feel confusing, please create a new project and select copy demo code.
|
255
|
+
|
256
|
+
I will explain what happens in [Explanation by Demo](#explanation-by-demo).
|
257
|
+
|
195
258
|
### Available Settings
|
196
259
|
|
197
260
|
#### General settings file is `config/vue.yml`
|
198
261
|
|
199
262
|
- `manifest_output`
|
200
263
|
|
201
|
-
Where to put `manifest.json` which required by Rails.
|
264
|
+
Where to put `manifest.json` which required by Rails production mode. You can set it in development mode for inspection.
|
202
265
|
|
203
266
|
All entry-points will be compiled into assets files. Rails needs `manifest.json` to know what are the files and will serve all its JS/CSS tags.
|
204
267
|
|
@@ -218,9 +281,13 @@ Actually `public_output_path` in `config/vue.yml` is very simple - just a sub pa
|
|
218
281
|
|
219
282
|
Please see [available options](#valid-vue-cli-config-options).
|
220
283
|
|
284
|
+
- `alias`
|
285
|
+
|
286
|
+
It's basically `resolve/alias` for Webpack. However, you don't have to config this settings in `.eslintrc.js` and `jest.config.js` again and again. `@vue/cli` will pass the settings to eslint via its plugin. The configuration for jest will be generated and passed to `jest.config.js` through `vue.rails.js`.
|
287
|
+
|
221
288
|
#### Customize your webpack configurations in `vue.config.js`
|
222
289
|
|
223
|
-
Feel free update `vue.config.js` by yourself. There are some lines of boiler-plate code to adapt `compression-webpack-plugin` and `webpack-bundle-analyzer`.
|
290
|
+
Feel free to update `vue.config.js` by yourself. There are some lines of boiler-plate code to adapt `compression-webpack-plugin` and `webpack-bundle-analyzer`.
|
224
291
|
|
225
292
|
### Rake Tasks
|
226
293
|
|
@@ -313,7 +380,7 @@ Feel free update `vue.config.js` by yourself. There are some lines of boiler-pla
|
|
313
380
|
}
|
314
381
|
```
|
315
382
|
|
316
|
-
> You may need to invoke with `bundle exec`. Rails 5 and above supports new `rails rake:task` flavor.
|
383
|
+
> You may need to invoke `rake` with `bundle exec`. Rails 5 and above supports new `rails rake:task` flavor.
|
317
384
|
|
318
385
|
## Valid Vue CLI config Options
|
319
386
|
|
@@ -505,3 +572,173 @@ Sorry, I don't think many gems work on Windows. Please install a virtual machine
|
|
505
572
|
Currently `vue.config.js` is reading configurations from `vue.rails.js` which depends on `js-yaml`. It will fallback to `bundle exec rake vue:json_config` without `js-yaml` installed. You may suffer performance issue if your rake tasks are slow.
|
506
573
|
|
507
574
|
</details>
|
575
|
+
|
576
|
+
## Explanation by Demo
|
577
|
+
|
578
|
+
<!-- <details><summary>Explanation by Demo</summary> -->
|
579
|
+
|
580
|
+
### Install
|
581
|
+
|
582
|
+
Run `bundle exec rake vue:create` or `rails vue:create` in Rails 5+, and follow the steps:
|
583
|
+
|
584
|
+
```
|
585
|
+
$ bundle exec rake vue:create
|
586
|
+
Which package manager to use? (Y=yarn, N=npm) [Yn]
|
587
|
+
...
|
588
|
+
? Generate project in current directory? Yes
|
589
|
+
...
|
590
|
+
? Check the features needed for your project: Babel, Linter, Unit
|
591
|
+
? Pick a linter / formatter config: Airbnb
|
592
|
+
? Pick additional lint features: (Press <space> to select, <a> to toggle all, <i> to invert selection)Lint on save
|
593
|
+
? Pick a unit testing solution: Jest
|
594
|
+
? Where do you prefer placing config for Babel, PostCSS, ESLint, etc.? In dedicated config files
|
595
|
+
...
|
596
|
+
Do you want to copy demo code? (Y=Yes, N=No) [yN]y
|
597
|
+
...
|
598
|
+
```
|
599
|
+
|
600
|
+
### First Taste
|
601
|
+
|
602
|
+
Now with `rails s`, open `http://localhost:3000/vue_demo/foo` in a browser you should be able to see a red big red "Foo" with blue "Hello Vue!".
|
603
|
+
|
604
|
+
Do not stop your rails server, open `app/assets/vue/views/Foo.vue` in your editor:
|
605
|
+
|
606
|
+
```diff
|
607
|
+
<template>
|
608
|
+
<div id="app">
|
609
|
+
<h1>Foo</h1>
|
610
|
+
- <HelloWorld msg="Vue!"></HelloWorld>
|
611
|
+
+ <HelloWorld msg="Rails!"></HelloWorld>
|
612
|
+
</div>
|
613
|
+
</template>
|
614
|
+
```
|
615
|
+
|
616
|
+
Change `msg="Vue!"` to `msg="Rails!"` and save. You will the text in your browser changed to "Hello Rails!". You can change styles or edit `app/assets/vue/components/HelloWorld.vue` and immediately see the result as well.
|
617
|
+
|
618
|
+
This functionality is called [HMR (Hot Module Replacement)](https://webpack.js.org/concepts/hot-module-replacement/) which is the killing feature provided by webpack-dev-server. You will soon fail in love with this feature and never want to go back to manually refresh your browser again and again.
|
619
|
+
|
620
|
+
### What in the box
|
621
|
+
|
622
|
+
```
|
623
|
+
.
|
624
|
+
├── app
|
625
|
+
│ ├── assets
|
626
|
+
│ │ └── vue
|
627
|
+
│ │ ├── components
|
628
|
+
│ │ │ ├── HelloWorld.vue
|
629
|
+
│ │ │ └── layouts
|
630
|
+
│ │ │ ├── App.vue
|
631
|
+
│ │ │ └── index.js
|
632
|
+
│ │ ├── entry_points
|
633
|
+
│ │ │ ├── bar.js
|
634
|
+
│ │ │ └── foo.js
|
635
|
+
│ │ └── views
|
636
|
+
│ │ ├── Bar.vue
|
637
|
+
│ │ └── Foo.vue
|
638
|
+
│ ├── controllers
|
639
|
+
│ │ └── vue_demo_controller.rb
|
640
|
+
│ └── views
|
641
|
+
│ ├── layouts
|
642
|
+
│ │ └── vue_demo.html.erb
|
643
|
+
│ └── vue_demo
|
644
|
+
│ └── foo.html.erb
|
645
|
+
├── config
|
646
|
+
│ ├── routes.rb
|
647
|
+
│ └── vue.yml
|
648
|
+
├── tests
|
649
|
+
│ └── unit
|
650
|
+
│ └── example.spec.js
|
651
|
+
├── .browserslistrc
|
652
|
+
├── .editorconfig
|
653
|
+
├── .eslintrc.js
|
654
|
+
├── .gitignore
|
655
|
+
├── babel.config.js
|
656
|
+
├── jest.config.js
|
657
|
+
├── package.json
|
658
|
+
├── postcss.config.js
|
659
|
+
├── vue.config.js
|
660
|
+
├── vue.rails.js
|
661
|
+
└── yarn.lock
|
662
|
+
```
|
663
|
+
|
664
|
+
You can run ESLint by
|
665
|
+
|
666
|
+
$ yarn lint
|
667
|
+
|
668
|
+
Run Jest
|
669
|
+
|
670
|
+
$ yarn test:unit
|
671
|
+
|
672
|
+
### Compile Assets
|
673
|
+
|
674
|
+
First let's compile the assets
|
675
|
+
|
676
|
+
```
|
677
|
+
$ env RAILS_ENV=production bundle exec rake vue:compile
|
678
|
+
run: yarn exec vue-cli-service build
|
679
|
+
...
|
680
|
+
File Size Gzipped
|
681
|
+
|
682
|
+
public/vue_assets/js/chunk-vendors.b54 82.49 KiB 29.80 KiB
|
683
|
+
85759.js
|
684
|
+
public/vue_assets/js/foo.dcbad15e.js 2.74 KiB 1.23 KiB
|
685
|
+
public/vue_assets/js/bar.d4fc59af.js 2.03 KiB 1.00 KiB
|
686
|
+
public/vue_assets/css/foo.4bbe6793.css 0.12 KiB 0.11 KiB
|
687
|
+
public/vue_assets/css/bar.96de90a8.css 0.02 KiB 0.04 KiB
|
688
|
+
|
689
|
+
Images and other types of assets omitted.
|
690
|
+
...
|
691
|
+
```
|
692
|
+
|
693
|
+
Your file names could be different from mine. Don't worry, we won't look those files. There are the files you got:
|
694
|
+
|
695
|
+
```
|
696
|
+
.
|
697
|
+
├── app
|
698
|
+
│ ├── assets
|
699
|
+
│ │ └── vue
|
700
|
+
│ │ └── manifest.json
|
701
|
+
└── public
|
702
|
+
└── vue_assets
|
703
|
+
├── css
|
704
|
+
│ ├── bar.96de90a8.css
|
705
|
+
│ └── foo.4bbe6793.css
|
706
|
+
└── js
|
707
|
+
├── bar.d4fc59af.js
|
708
|
+
├── chunk-vendors.b5485759.js
|
709
|
+
└── foo.dcbad15e.js
|
710
|
+
```
|
711
|
+
|
712
|
+
Let have a look at `app/assets/vue/manifest.json`:
|
713
|
+
|
714
|
+
```json
|
715
|
+
{
|
716
|
+
"bar.css": "/vue_assets/css/bar.96de90a8.css",
|
717
|
+
"bar.js": "/vue_assets/js/bar.d4fc59af.js",
|
718
|
+
"chunk-vendors.js": "/vue_assets/js/chunk-vendors.b5485759.js",
|
719
|
+
"entrypoints": {
|
720
|
+
"bar": {
|
721
|
+
"js": [
|
722
|
+
"/vue_assets/js/chunk-vendors.b5485759.js",
|
723
|
+
"/vue_assets/js/bar.d4fc59af.js"
|
724
|
+
],
|
725
|
+
"css": [
|
726
|
+
"/vue_assets/css/bar.96de90a8.css"
|
727
|
+
]
|
728
|
+
},
|
729
|
+
"foo": {
|
730
|
+
"js": [
|
731
|
+
"/vue_assets/js/chunk-vendors.b5485759.js",
|
732
|
+
"/vue_assets/js/foo.dcbad15e.js"
|
733
|
+
],
|
734
|
+
"css": [
|
735
|
+
"/vue_assets/css/foo.4bbe6793.css"
|
736
|
+
]
|
737
|
+
}
|
738
|
+
},
|
739
|
+
"foo.css": "/vue_assets/css/foo.4bbe6793.css",
|
740
|
+
"foo.js": "/vue_assets/js/foo.dcbad15e.js"
|
741
|
+
}
|
742
|
+
```
|
743
|
+
|
744
|
+
<!-- </details> -->
|
@@ -27,6 +27,7 @@ class VueCreate
|
|
27
27
|
copy_demo?
|
28
28
|
copy_config
|
29
29
|
generate_vue_yml
|
30
|
+
ensure_entry_point!
|
30
31
|
fix_jest_config!
|
31
32
|
puts 'vue:create finished!'
|
32
33
|
ensure
|
@@ -101,6 +102,9 @@ class VueCreate
|
|
101
102
|
end
|
102
103
|
pub_dir = @root.join('public')
|
103
104
|
FileUtils.mv(pub_dir, "#{pub_dir}.backup")
|
105
|
+
reademe = @root.join('README.md')
|
106
|
+
reademe = reademe.exist? && reademe
|
107
|
+
FileUtils.mv(reademe, "#{reademe}.backup") if reademe
|
104
108
|
|
105
109
|
begin
|
106
110
|
@pm.exec('vue create', '', "-n -m #{@pm.package_manager} .")
|
@@ -109,6 +113,10 @@ class VueCreate
|
|
109
113
|
FileUtils.rm_rf(pub_dir) if pub_dir.exist?
|
110
114
|
FileUtils.mv("#{pub_dir}.backup", pub_dir)
|
111
115
|
FileUtils.mv("#{vue_config}.backup", vue_config) if backup_vue_config
|
116
|
+
if reademe
|
117
|
+
FileUtils.rm_f(reademe)
|
118
|
+
FileUtils.mv("#{reademe}.backup", reademe)
|
119
|
+
end
|
112
120
|
end
|
113
121
|
|
114
122
|
# merge gitignore
|
@@ -169,16 +177,17 @@ class VueCreate
|
|
169
177
|
foo = false
|
170
178
|
bar = false
|
171
179
|
route_lines.each do |line|
|
172
|
-
foo ||= line.include?('
|
173
|
-
bar ||= line.include?('
|
180
|
+
foo ||= line.include?('vue_demo#foo')
|
181
|
+
bar ||= line.include?('vue_demo#bar')
|
174
182
|
end
|
175
183
|
return if foo && bar
|
176
184
|
|
177
185
|
end_line = route_lines.rindex { |ln| ln =~ /^\s*end\b/ }
|
178
186
|
return if end_line.blank?
|
179
187
|
|
180
|
-
route_lines.insert(end_line, " get '
|
181
|
-
route_lines.insert(end_line, " get '
|
188
|
+
route_lines.insert(end_line, " get 'vue_demo/baz' => 'vue_demo#baz'") unless foo
|
189
|
+
route_lines.insert(end_line, " get 'vue_demo/bar' => 'vue_demo#bar'") unless bar
|
190
|
+
route_lines.insert(end_line, " get 'vue_demo/foo' => 'vue_demo#foo'") unless foo
|
182
191
|
route_lines.insert(end_line, ' # Example of vue_cli-rails')
|
183
192
|
routes.write(route_lines.join("\n"))
|
184
193
|
end
|
@@ -205,12 +214,27 @@ class VueCreate
|
|
205
214
|
yml_dest.write(yml)
|
206
215
|
end
|
207
216
|
|
217
|
+
def ensure_entry_point!
|
218
|
+
%w[entry_points assets components utils views].each do |dir_name|
|
219
|
+
dir = @root.join("app/assets/vue/#{dir_name}")
|
220
|
+
FileUtils.mkdir_p(dir) unless dir.exist?
|
221
|
+
end
|
222
|
+
|
223
|
+
ep_dir = @root.join('app/assets/vue/entry_points')
|
224
|
+
return if Dir[ep_dir.join('**/*.js')].any?
|
225
|
+
ep_dir.join('entry_point_demo.js').write("console.log('This is a demo entry point')")
|
226
|
+
end
|
227
|
+
|
208
228
|
def fix_jest_config!
|
209
229
|
jest_file = @root.join('jest.config.js')
|
210
230
|
return unless jest_file.exist?
|
211
231
|
|
212
232
|
jest_config = %x`node -e "console.log(JSON.stringify(require('./jest.config.js')))"`
|
213
233
|
jest_config = JSON.parse(jest_config)
|
234
|
+
if jest_config['transformIgnorePatterns'] &&
|
235
|
+
!jest_config['transformIgnorePatterns'].include?('<rootDir>/node_modules/')
|
236
|
+
jest_config['transformIgnorePatterns'] << '<rootDir>/node_modules/'
|
237
|
+
end
|
214
238
|
jest_config.delete('moduleNameMapper')
|
215
239
|
jest = <<~JS
|
216
240
|
const { jestModuleNameMapper: moduleNameMapper } = require('./vue.rails');
|
@@ -0,0 +1,20 @@
|
|
1
|
+
<template>
|
2
|
+
<div class="hello">
|
3
|
+
<h2>Hello {{ msg }}</h2>
|
4
|
+
</div>
|
5
|
+
</template>
|
6
|
+
|
7
|
+
<script>
|
8
|
+
export default {
|
9
|
+
name: 'HelloWorld',
|
10
|
+
props: {
|
11
|
+
msg: String,
|
12
|
+
},
|
13
|
+
};
|
14
|
+
</script>
|
15
|
+
|
16
|
+
<style scoped>
|
17
|
+
h2 {
|
18
|
+
color: blue;
|
19
|
+
}
|
20
|
+
</style>
|
File without changes
|
@@ -0,0 +1,21 @@
|
|
1
|
+
<template>
|
2
|
+
<div id="app">
|
3
|
+
<h1>Foo</h1>
|
4
|
+
<HelloWorld msg="Vue!"></HelloWorld>
|
5
|
+
</div>
|
6
|
+
</template>
|
7
|
+
|
8
|
+
<script>
|
9
|
+
import HelloWorld from '../components/HelloWorld.vue';
|
10
|
+
|
11
|
+
export default {
|
12
|
+
name: 'Foo',
|
13
|
+
components: { HelloWorld },
|
14
|
+
};
|
15
|
+
</script>
|
16
|
+
|
17
|
+
<style scoped>
|
18
|
+
h1 {
|
19
|
+
color: red;
|
20
|
+
}
|
21
|
+
</style>
|
File without changes
|
data/lib/source/vue.rails.js
CHANGED
@@ -2,6 +2,7 @@ const { env } = require('process');
|
|
2
2
|
|
3
3
|
module.exports = (() => {
|
4
4
|
let settings = {};
|
5
|
+
const assets = {};
|
5
6
|
|
6
7
|
try {
|
7
8
|
/* eslint-disable global-require,import/no-extraneous-dependencies */
|
@@ -36,7 +37,7 @@ module.exports = (() => {
|
|
36
37
|
devServer.contentBase = resolve(root, devServer.contentBase);
|
37
38
|
}
|
38
39
|
const entry = {};
|
39
|
-
const assetRoot = resolve(root, 'app/assets/vue/
|
40
|
+
const assetRoot = resolve(root, 'app/assets/vue/entry_points');
|
40
41
|
const findAllJsFiles = (path) => {
|
41
42
|
readdirSync(path).forEach((fn) => {
|
42
43
|
const filename = resolve(path, fn);
|
@@ -58,7 +59,7 @@ module.exports = (() => {
|
|
58
59
|
settings = {
|
59
60
|
env: railsEnv,
|
60
61
|
root,
|
61
|
-
manifestOutput: resolve(root, manifestOutput),
|
62
|
+
manifestOutput: manifestOutput && resolve(root, manifestOutput),
|
62
63
|
|
63
64
|
outputDir: resolve(root, 'public', pop),
|
64
65
|
publicPath: `/${pop}/`,
|
@@ -80,7 +81,15 @@ module.exports = (() => {
|
|
80
81
|
}/$1`,
|
81
82
|
}), {}),
|
82
83
|
|
83
|
-
devServer
|
84
|
+
devServer: devServer && {
|
85
|
+
...devServer,
|
86
|
+
before(app) {
|
87
|
+
app.get('/__manifest/', ({ query }, res) => {
|
88
|
+
const entryPoint = Object.keys(query || {})[0];
|
89
|
+
res.json(entryPoint === '!!INSPECT!!' ? assets : assets.entrypoints[entryPoint]);
|
90
|
+
});
|
91
|
+
},
|
92
|
+
},
|
84
93
|
filenameHashing,
|
85
94
|
lintOnSave,
|
86
95
|
runtimeCompiler,
|
@@ -109,17 +118,19 @@ module.exports = (() => {
|
|
109
118
|
return v === undefined ? cfg : { ...cfg, [k]: v };
|
110
119
|
}, {});
|
111
120
|
const { jestModuleNameMapper } = settings;
|
121
|
+
const isProd = settings.env === 'production';
|
112
122
|
|
113
123
|
return {
|
114
|
-
isProd
|
124
|
+
isProd,
|
115
125
|
manifest: {
|
116
126
|
/* eslint-disable-next-line global-require,import/no-extraneous-dependencies */
|
117
127
|
plugin: require('webpack-assets-manifest'),
|
118
128
|
options: {
|
129
|
+
assets,
|
119
130
|
entrypoints: true,
|
120
|
-
writeToDisk:
|
131
|
+
writeToDisk: !!settings.manifestOutput,
|
121
132
|
publicPath: true,
|
122
|
-
output: settings.manifestOutput,
|
133
|
+
output: settings.manifestOutput || '',
|
123
134
|
},
|
124
135
|
},
|
125
136
|
jestModuleNameMapper,
|
data/lib/source/vue.yml
CHANGED
@@ -1,17 +1,16 @@
|
|
1
1
|
default: &default
|
2
2
|
package_manager: ${PACKAGE_MANAGER}
|
3
|
-
manifest_output: tmp/manifest.json
|
4
3
|
public_output_path: vue_assets
|
5
4
|
# js_output:
|
6
5
|
# filename: 'js/[name].[hash:8].js'
|
7
6
|
# chunkFilename: 'js/[name].[hash:8].js'
|
8
7
|
alias:
|
9
8
|
'@': app/assets/vue
|
10
|
-
~
|
11
|
-
~v-launcher: app/assets/vue/components/layouts
|
9
|
+
# '~': app/assets/vue/components
|
12
10
|
|
13
11
|
development:
|
14
12
|
<<: *default
|
13
|
+
# manifest_output: tmp/manifest.json
|
15
14
|
devServer:
|
16
15
|
contentBase: public
|
17
16
|
host: localhost
|
@@ -4,6 +4,16 @@ module VueCli
|
|
4
4
|
def initialize
|
5
5
|
@root = ::Rails.root
|
6
6
|
load_config(YAML.load_file(@root.join('config/vue.yml')))
|
7
|
+
self.class.setup(self)
|
8
|
+
end
|
9
|
+
|
10
|
+
def entry_assets_prod(entry_point)
|
11
|
+
self.class.entry_points[entry_point]
|
12
|
+
end
|
13
|
+
|
14
|
+
def entry_assets_dev(entry_point)
|
15
|
+
assets = Net::HTTP.get(URI("#{self.class.dev_server_url}?#{entry_point}"))
|
16
|
+
assets.blank? ? nil : JSON.parse(assets)
|
7
17
|
end
|
8
18
|
|
9
19
|
def node_env
|
@@ -33,9 +43,6 @@ module VueCli
|
|
33
43
|
c['root'] = @root.to_s
|
34
44
|
cw['output'] = config['js_output'] if config['js_output'].present?
|
35
45
|
c['manifestOutput'] = config['manifest_output']
|
36
|
-
unless c['manifestOutput'].presence
|
37
|
-
raise(Error, 'Incorrect manifest_output in config/vue.yml')
|
38
|
-
end
|
39
46
|
|
40
47
|
public_output_path = c['public_output_path'] || 'vue_assets'
|
41
48
|
c['outputDir'] = File.join(resolve('public'), public_output_path)
|
@@ -60,7 +67,7 @@ module VueCli
|
|
60
67
|
|
61
68
|
jest = {}
|
62
69
|
c['jestModuleNameMapper'] = jest
|
63
|
-
resolve_config(c, 'manifestOutput')
|
70
|
+
resolve_config(c, 'manifestOutput') if c['manifestOutput'].present?
|
64
71
|
config['alias']&.tap do |aliases|
|
65
72
|
aliases.each_key do |k|
|
66
73
|
key = k.gsub(%r<(?=[-{}()+.,^$#/\s\]])>, '\\')
|
@@ -72,8 +79,7 @@ module VueCli
|
|
72
79
|
end
|
73
80
|
dev_server = c['devServer'] || {}
|
74
81
|
resolve_config(dev_server, 'contentBase')
|
75
|
-
|
76
|
-
self.class.manifest_file = c['manifestOutput']
|
82
|
+
ensure
|
77
83
|
@config = c
|
78
84
|
end
|
79
85
|
|
@@ -94,26 +100,24 @@ module VueCli
|
|
94
100
|
JSON.pretty_generate(@config)
|
95
101
|
end
|
96
102
|
|
97
|
-
def manifest_data
|
98
|
-
self.class.manifest.data
|
99
|
-
end
|
100
|
-
|
101
103
|
class << self
|
104
|
+
attr_reader :dev_server_url, :entry_points
|
105
|
+
|
102
106
|
def instance
|
103
107
|
@instance ||= new
|
104
108
|
end
|
105
109
|
|
106
|
-
def
|
107
|
-
|
108
|
-
|
110
|
+
def setup(config)
|
111
|
+
config.dev_server_host.presence&.tap do |host|
|
112
|
+
@dev_server_url = "http://#{host}/__manifest/"
|
113
|
+
end
|
109
114
|
|
110
|
-
|
111
|
-
|
112
|
-
|
113
|
-
|
114
|
-
@
|
115
|
+
@entry_points = {}
|
116
|
+
manifest = config['manifestOutput'].presence
|
117
|
+
manifest &&= Pathname.new(manifest)
|
118
|
+
if manifest&.exist?
|
119
|
+
@entry_points = (JSON.parse(manifest.read || '{}')['entrypoints'] || {}).freeze
|
115
120
|
end
|
116
|
-
@manifest
|
117
121
|
end
|
118
122
|
end
|
119
123
|
|
@@ -124,7 +128,7 @@ module VueCli
|
|
124
128
|
end
|
125
129
|
|
126
130
|
def entry
|
127
|
-
base_dir = @root.join('app/assets/vue/
|
131
|
+
base_dir = @root.join('app/assets/vue/entry_points')
|
128
132
|
start = base_dir.to_s.size + 1
|
129
133
|
Dir[base_dir.join('**/*.js')].each_with_object({}) do |filename, h|
|
130
134
|
h[filename[start...-3]] = filename
|
data/lib/vue_cli/rails/engine.rb
CHANGED
@@ -4,14 +4,32 @@ module VueCli
|
|
4
4
|
|
5
5
|
class Engine < ::Rails::Engine
|
6
6
|
initializer 'vue_cli' do |app|
|
7
|
-
if
|
8
|
-
|
9
|
-
|
10
|
-
|
7
|
+
if defined?(::Rails::Server)
|
8
|
+
is_dev = ::Rails.env.development?
|
9
|
+
|
10
|
+
if is_dev
|
11
|
+
require 'vue_cli/rails/dev_server_proxy'
|
12
|
+
|
13
|
+
app.middleware.insert_before(0, DevServerProxy)
|
14
|
+
Engine.start_wds! if ENV['NO_WEBPACK_DEV_SERVER'].blank?
|
15
|
+
end
|
16
|
+
|
17
|
+
Configuration.class_eval do
|
18
|
+
alias_method :entry_assets, :"entry_assets_#{is_dev ? 'dev' : 'prod'}"
|
19
|
+
remove_method :entry_assets_dev, :entry_assets_prod
|
20
|
+
end
|
21
|
+
Configuration.instance unless is_dev
|
11
22
|
end
|
12
23
|
|
13
24
|
::ActiveSupport.on_load(:action_controller) do
|
14
|
-
::ActionController::Base.
|
25
|
+
::ActionController::Base.class_eval do
|
26
|
+
helper(Helper)
|
27
|
+
include(Helper)
|
28
|
+
|
29
|
+
define_method(:render_vue) do |entry, **args|
|
30
|
+
render({ html: vue_entry(entry), layout: true }.merge(args))
|
31
|
+
end
|
32
|
+
end
|
15
33
|
end
|
16
34
|
|
17
35
|
::ActiveSupport.on_load(:action_view) do
|
@@ -28,7 +46,9 @@ module VueCli
|
|
28
46
|
pid = running&.dig(1)&.split(/\s+/, 3)&.dig(1)
|
29
47
|
Process.kill('INT', pid.to_i) if pid.present?
|
30
48
|
end
|
31
|
-
|
49
|
+
|
50
|
+
cmd = config['launch_dev_service'].presence || 'vue-cli-service serve'
|
51
|
+
config.node_env.exec(cmd)
|
32
52
|
end
|
33
53
|
end
|
34
54
|
end
|
data/lib/vue_cli/rails/helper.rb
CHANGED
@@ -1,21 +1,18 @@
|
|
1
1
|
module VueCli
|
2
2
|
module Rails
|
3
3
|
module Helper
|
4
|
-
def vue_entry(
|
5
|
-
|
4
|
+
def vue_entry(entry)
|
5
|
+
assets = VueCli::Rails::Configuration.instance.entry_assets(entry)
|
6
|
+
raise(ArgumentError, "Vue entry (#{entry}) not found!") if assets.blank?
|
6
7
|
|
7
|
-
|
8
|
-
|
9
|
-
|
10
|
-
assets = []
|
11
|
-
(entry['css'] || []).each do |css|
|
12
|
-
assets << stylesheet_link_tag(css)
|
8
|
+
tags = ''.dup
|
9
|
+
(assets['css'] || []).each do |css|
|
10
|
+
tags << %{<link href="#{css}" rel="stylesheet">}
|
13
11
|
end
|
14
|
-
(
|
15
|
-
|
12
|
+
(assets['js'] || []).each do |js|
|
13
|
+
tags << %{<script src="#{js}"></script>}
|
16
14
|
end
|
17
|
-
|
18
|
-
assets.join('').html_safe
|
15
|
+
tags.html_safe
|
19
16
|
end
|
20
17
|
end
|
21
18
|
end
|
@@ -11,7 +11,7 @@ module VueCli
|
|
11
11
|
def use!(manager)
|
12
12
|
@pm = manager.to_sym
|
13
13
|
raise(ArgumentError, "Unsupported manager: #{@pm}") unless %i[npm yarn].include?(@pm)
|
14
|
-
raise(
|
14
|
+
raise(ArgumentError, "Not installed: #{@pm}") unless try(:"#{@pm}?")
|
15
15
|
end
|
16
16
|
|
17
17
|
def reset
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: vue_cli-rails
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.
|
4
|
+
version: 0.3.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- James Chen
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2019-03-
|
11
|
+
date: 2019-03-12 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: activesupport
|
@@ -131,16 +131,16 @@ files:
|
|
131
131
|
- lib/helpers/scripts/install_rails.rb
|
132
132
|
- lib/helpers/scripts/vue_command.rb
|
133
133
|
- lib/helpers/scripts/vue_create.rb
|
134
|
+
- lib/source/app/assets/vue/components/HelloWorld.vue
|
134
135
|
- lib/source/app/assets/vue/components/layouts/App.vue
|
135
136
|
- lib/source/app/assets/vue/components/layouts/index.js
|
136
|
-
- lib/source/app/assets/vue/
|
137
|
-
- lib/source/app/assets/vue/
|
138
|
-
- lib/source/app/assets/vue/views/
|
139
|
-
- lib/source/app/assets/vue/views/
|
140
|
-
- lib/source/app/controllers/
|
141
|
-
- lib/source/app/views/layouts/
|
142
|
-
- lib/source/app/views/
|
143
|
-
- lib/source/app/views/vue/foo.html.erb
|
137
|
+
- lib/source/app/assets/vue/entry_points/bar.js
|
138
|
+
- lib/source/app/assets/vue/entry_points/foo.js
|
139
|
+
- lib/source/app/assets/vue/views/Bar.vue
|
140
|
+
- lib/source/app/assets/vue/views/Foo.vue
|
141
|
+
- lib/source/app/controllers/vue_demo_controller.rb
|
142
|
+
- lib/source/app/views/layouts/vue_demo.html.erb
|
143
|
+
- lib/source/app/views/vue_demo/foo.html.erb
|
144
144
|
- lib/source/vue.config.js
|
145
145
|
- lib/source/vue.rails.js
|
146
146
|
- lib/source/vue.yml
|
@@ -174,7 +174,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
174
174
|
- !ruby/object:Gem::Version
|
175
175
|
version: '0'
|
176
176
|
requirements: []
|
177
|
-
rubygems_version: 3.0.
|
177
|
+
rubygems_version: 3.0.3
|
178
178
|
signing_key:
|
179
179
|
specification_version: 4
|
180
180
|
summary: Get vue-cli working with Rails
|
@@ -1 +0,0 @@
|
|
1
|
-
<%= vue_entry('bar') %>
|