vue_cli-rails 0.1.4 → 0.1.6

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.
Files changed (43) hide show
  1. checksums.yaml +4 -4
  2. data/.gitignore +0 -0
  3. data/.rspec +0 -0
  4. data/.rubocop.yml +20 -0
  5. data/.travis.yml +13 -0
  6. data/Gemfile +2 -4
  7. data/Gemfile.lock +0 -0
  8. data/LICENSE +0 -0
  9. data/README.md +482 -14
  10. data/Rakefile +3 -3
  11. data/bin/console +3 -3
  12. data/lib/helpers/lib/cmd.rb +6 -0
  13. data/lib/helpers/lib/common.rb +7 -0
  14. data/lib/helpers/lib/input_loop.rb +41 -0
  15. data/lib/helpers/lib.rb +3 -0
  16. data/lib/helpers/scripts/install_rails.rb +48 -0
  17. data/lib/helpers/scripts/vue_command.rb +74 -0
  18. data/lib/helpers/scripts/vue_create.rb +153 -0
  19. data/lib/source/app/assets/vue/components/layouts/App.vue +0 -0
  20. data/lib/source/app/assets/vue/components/layouts/index.js +0 -0
  21. data/lib/source/app/assets/vue/components/views/Bar.vue +0 -0
  22. data/lib/source/app/assets/vue/components/views/Foo.vue +1 -1
  23. data/lib/source/app/assets/vue/views/bar.js +0 -0
  24. data/lib/source/app/assets/vue/views/foo.js +0 -0
  25. data/lib/source/app/controllers/vue_controller.rb +2 -4
  26. data/lib/source/app/views/layouts/vue.html.erb +0 -0
  27. data/lib/source/app/views/vue/bar.html.erb +0 -0
  28. data/lib/source/app/views/vue/foo.html.erb +0 -0
  29. data/lib/source/vue.config.js +37 -33
  30. data/lib/source/vue.rails.js +64 -28
  31. data/lib/source/vue.yml +14 -8
  32. data/lib/tasks/vue.rake +23 -120
  33. data/lib/views/layouts/vue.erb +0 -0
  34. data/lib/vue_cli/rails/configuration.rb +58 -21
  35. data/lib/vue_cli/rails/dev_server_proxy.rb +3 -3
  36. data/lib/vue_cli/rails/engine.rb +16 -7
  37. data/lib/vue_cli/rails/helper.rb +0 -0
  38. data/lib/vue_cli/rails/node_env.rb +31 -23
  39. data/lib/vue_cli/rails/version.rb +1 -1
  40. data/lib/vue_cli/rails.rb +1 -1
  41. data/tmp/.keep +0 -0
  42. data/vue_cli-rails.gemspec +18 -18
  43. metadata +32 -9
@@ -0,0 +1,48 @@
1
+ #!/usr/bin/env ruby
2
+ require_relative 'common'
3
+
4
+ ver = ENV['RAILS_VERSION']
5
+ abort('RAILS_VERSION not found!') if ver.blank?
6
+
7
+ versions = `gem list -r -a -e rails`.scan(/\b((\d+\.)+\d+)\b/).map { |m| m[0] }
8
+ ver = versions.find { |v| v.start_with? ver }
9
+ abort("Version #{ver} not found!") if ver.blank?
10
+
11
+ run("gem install rails -v #{ver}")
12
+
13
+ RAILS_NEW_SCRIPT = {
14
+ '5' => {
15
+ args: %w[
16
+ database=sqlite3
17
+ skip-yarn
18
+ skip-git
19
+ skip-keeps
20
+ skip-sprockets
21
+ skip-spring
22
+ skip-listen
23
+ skip-turbolinks
24
+ skip-javascript
25
+ skip-test
26
+ skip-bundle
27
+ ],
28
+ keep_gems: /^\s*gem\s+['"](rails|puma|bootsnap)/,
29
+ append: <<~RUBY
30
+ gem 'sqlite3', '~> 1.3.10'
31
+ RUBY
32
+ },
33
+ }
34
+
35
+ require 'pathname'
36
+ require 'fileutils'
37
+
38
+ scirpt = RAILS_NEW_SCRIPT[ver[0]]
39
+ run "rails new test_vcr #{scirpt[:args].map { |a| "--#{a}" }.join(' ')}"
40
+ FileUtils.chdir 'test_vcr'
41
+
42
+ root = Pathname.new(FileUtils.pwd)
43
+ gemfile = root.join('Gemfile').read.split("\n")
44
+ .reject(&:empty?).reject { |s| s =~ /^\s*#/ }
45
+ .reject { |s| s =~ /^\s*gem/ && s !~ scirpt[:keep_gems] }
46
+ root.join('Gemfile').write("#{(gemfile + [scirpt[:append]]).join("\n")}\n")
47
+ run 'bundle install'
48
+ # rails new test_vcr --database=sqlite3 --skip-yarn --skip-git --skip-sprockets --skip-spring --skip-listen --skip-turbolinks --skip-javascript --skip-test --skip-bundle
@@ -0,0 +1,74 @@
1
+ require_relative '../lib'
2
+
3
+ class VueCommand
4
+ SASS = %w[sass-loader node-sass].freeze
5
+
6
+ SUPPORED_FORMATS = {
7
+ 'pug' => %w[pug-plain-loader pug],
8
+ 'sass' => SASS,
9
+ 'scss' => SASS,
10
+ 'less' => %w[less-loader less],
11
+ 'stylus' => %w[stylus-loader stylus],
12
+ }.freeze
13
+
14
+ def initialize
15
+ @pm = VueCli::Rails::Configuration.instance.node_env
16
+ end
17
+
18
+ def install_format_support(formats)
19
+ pkgs, unknown = group_formats(formats)
20
+ if pkgs.empty?
21
+ msg = unknown.empty? ? 'No formats supplied' : "Unsupported formats #{unknown}"
22
+ raise(ArgumentError, msg)
23
+ end
24
+
25
+ STDERR.puts "Unsupported formats #{unknown}" if unknown.any?
26
+ @pm.add "-D #{pkgs.join(' ')}"
27
+ end
28
+
29
+ def install_node_dev
30
+ pack_json = ::Rails.root.join('package.json')
31
+ abort('Not found package.json!') unless pack_json.exist? && pack_json.file?
32
+
33
+ add_deps(pack_json, %w[cross-env npm-run-all])
34
+ add_scripts(pack_json,
35
+ dev: 'run-p rails-s serve',
36
+ prod: 'cross-env RAILS_ENV=production vue-cli-service build',
37
+ serve: 'vue-cli-service serve',
38
+ 'rails-s' => 'cross-env NO_WEBPACK_DEV_SERVER=1 rails s')
39
+ puts 'Dependencies and scripts have been installed successfully'
40
+ cmd = @pm.package_manager == :npm ? 'npm run' : 'yarn'
41
+ puts " Please use `#{cmd} dev` to start dev server"
42
+ end
43
+
44
+ private
45
+
46
+ def add_deps(package_json, *packages, dev: true)
47
+ json = JSON.parse(package_json.read)
48
+ deps = json[dev ? 'devDependencies' : 'dependencies']
49
+ pkgs = [packages].flatten.find_all do |dep|
50
+ !(dep.blank? || deps.key?(dep))
51
+ end
52
+ @pm.add "#{dev ? '-D ' : ''}#{pkgs.join(' ')}" if pkgs.any?
53
+ end
54
+
55
+ def add_scripts(package_json, commands = {})
56
+ json = JSON.parse(package_json.read)
57
+ scripts = json['scripts']
58
+ commands.stringify_keys.each do |key, cmd|
59
+ scripts[key] = cmd unless scripts.key? key
60
+ end
61
+ package_json.write(JSON.pretty_generate(json))
62
+ end
63
+
64
+ def group_formats(formats)
65
+ formats.each_with_object([[], []]) do |result, fmt|
66
+ fmts = SUPPORED_FORMATS[fmt.downcase]
67
+ if fmts
68
+ result[0] += fmts
69
+ else
70
+ result[1] << fmt
71
+ end
72
+ end
73
+ end
74
+ end
@@ -0,0 +1,153 @@
1
+ require_relative '../lib'
2
+
3
+ class VueCreate
4
+ def initialize
5
+ @input = InputLoop.new
6
+ @pwd = FileUtils.pwd
7
+ @root = ::Rails.root
8
+ @pack = @root.join('package.json')
9
+ @src_dir = Pathname.new(__FILE__).dirname.join('..', '..', 'source')
10
+ end
11
+
12
+ def self.run!
13
+ new.start
14
+ end
15
+
16
+ def start
17
+ check_node!
18
+ FileUtils.chdir @root
19
+ begin
20
+ package_manager?
21
+ install_vue_cli
22
+ run_vue_create?
23
+ install_dev_deps
24
+ delete_vue_src?
25
+ copy_demo?
26
+ copy_config
27
+ generate_vue_yml
28
+ puts 'vue:create finished!'
29
+ ensure
30
+ FileUtils.chdir @pwd
31
+ end
32
+ end
33
+
34
+ private
35
+
36
+ def check_node!
37
+ @pm = VueCli::Rails::NodeEnv.new
38
+ abort('Cannot find node.js') unless @pm.node?
39
+ end
40
+
41
+ def package_manager?
42
+ yarn = @pm.yarn_version
43
+ npm = @pm.npm_version
44
+ abort('Cannot find npm or yarn') unless yarn || npm
45
+
46
+ if yarn && npm
47
+ input = @input.gets(
48
+ 'Which package manager to use?',
49
+ @root.join('package-lock.json').exist? ? 'yN' : 'Yn',
50
+ y: 'yarn', n: 'npm',
51
+ )
52
+ else
53
+ input = npm ? 'n' : 'y'
54
+ end
55
+ @pm.use!(input == 'n' ? :npm : :yarn)
56
+ puts "Using package manager: #{@pm.package_manager}"
57
+ end
58
+
59
+ def install_vue_cli
60
+ return if @pm.vue?
61
+
62
+ puts "@vue/cli haven't been installed"
63
+ pm.global_add('@vue/cli')
64
+ end
65
+
66
+ def run_vue_create?
67
+ input = 'y'
68
+ if @pack.exist?
69
+ puts 'Detected `package.json`!'
70
+ input = @input.gets(
71
+ ' Do you want `vue create?` to overwrite your package.json',
72
+ 'ynAk',
73
+ a: 'Auto', k: 'Keep',
74
+ )
75
+ end
76
+ return if input == 'n'
77
+
78
+ src_json = JSON.parse(@pack.read) unless input == 'y'
79
+ @pm.exec('vue create', '', "-n -m #{@pm.package_manager} .")
80
+
81
+ dst_json = JSON.parse(@pack.read) unless input == 'y'
82
+ return if input == 'y' || dst_json == src_json
83
+
84
+ src_json, dst_json = [dst_json, src_json] if input == 'a'
85
+ dst_json.deep_merge!(src_json)
86
+ @pack.write(JSON.pretty_generate(dst_json))
87
+ @pm.install
88
+ end
89
+
90
+ def install_dev_deps
91
+ package = JSON.parse(@pack.read)
92
+ dev_deps = package['devDependencies']
93
+ dd = %w[webpack-assets-manifest js-yaml].find_all do |dep|
94
+ !dev_deps.key?(dep)
95
+ end
96
+ @pm.add "-D #{dd.join(' ')}" if dd.any?
97
+ end
98
+
99
+ def delete_vue_src?
100
+ src = @root.join('src')
101
+ return unless src.exist? && src.directory?
102
+
103
+ puts 'Detected `src` folder (should be generated by vue-cli)'
104
+ FileUtils.rm_rf(src.to_s) if @input.gets(' Do you want to delete src folder?') == 'y'
105
+ end
106
+
107
+ def copy_demo?
108
+ return unless @input.gets('Do you want to copy demo code?', 'yN') == 'y'
109
+
110
+ FileUtils.cp_r(@src_dir.join('app'), @root)
111
+ routes = @root.join('config', 'routes.rb')
112
+ return unless routes.exist?
113
+
114
+ route_lines = routes.read.split("\n")
115
+ foo = false
116
+ bar = false
117
+ route_lines.each do |line|
118
+ foo ||= line.include? 'vue#foo'
119
+ bar ||= line.include? 'vue#bar'
120
+ end
121
+ return if foo && bar
122
+
123
+ end_line = route_lines.rindex { |ln| ln =~ /^\s*end\b/ }
124
+ return if end_line.blank?
125
+
126
+ route_lines.insert(end_line, " get 'vue/bar' => 'vue#bar'") unless bar
127
+ route_lines.insert(end_line, " get 'vue/foo' => 'vue#foo'") unless foo
128
+ route_lines.insert(end_line, ' # Example of vue_cli-rails')
129
+ routes.write(route_lines.join("\n"))
130
+ end
131
+
132
+ def copy_config
133
+ puts 'Copying configuration files...'
134
+ FileUtils.cp(@src_dir.join('vue.rails.js'), "#{@root}/")
135
+ if @root.join('vue.config.js').exist?
136
+ puts 'Detected `vue.config.js`!'
137
+ return if @input.gets(' Do you want to overwrite vue.config.js?', 'yN') == 'n'
138
+ end
139
+ FileUtils.cp(@src_dir.join('vue.config.js'), "#{@root}/")
140
+ end
141
+
142
+ def generate_vue_yml
143
+ yml_dest = @root.join('config', 'vue.yml')
144
+ if yml_dest.exist?
145
+ puts 'Detected `config/vue.yml`!'
146
+ return if @input.gets(' Do you want to overwrite config/vue.yml?') == 'n'
147
+ end
148
+
149
+ yml = @src_dir.join('vue.yml').read
150
+ yml = yml.sub('${PACKAGE_MANAGER}', pm.package_manager.to_s)
151
+ yml_dest.write(yml)
152
+ end
153
+ end
File without changes
File without changes
@@ -10,7 +10,7 @@ export default {
10
10
  };
11
11
  </script>
12
12
 
13
- <style>
13
+ <style scoped>
14
14
  #foo {
15
15
  color: red;
16
16
  }
File without changes
File without changes
@@ -1,9 +1,7 @@
1
1
  class VueController < ApplicationController
2
2
  layout 'vue'
3
3
 
4
- def foo
5
- end
4
+ def foo; end
6
5
 
7
- def bar
8
- end
6
+ def bar; end
9
7
  end
File without changes
File without changes
File without changes
@@ -1,34 +1,41 @@
1
+ // const { resolve } = require('path');
1
2
  // const CompressionWebpackPlugin = require('compression-webpack-plugin');
2
3
  // const { BundleAnalyzerPlugin } = require('webpack-bundle-analyzer');
3
4
 
5
+ const railsConfig = require('./vue.rails');
6
+
4
7
  const {
5
- entry,
6
- css,
7
- alias,
8
- outputDir,
9
- devServer,
10
- publicPath,
11
8
  manifest,
12
- isProd,
13
- } = require('./vue.rails');
9
+ pickUpSettings,
10
+ // isProd,
11
+ // getSettings, // (keys: string[]) => Object. Returns all available settings by default
12
+ } = railsConfig;
14
13
 
15
14
  module.exports = {
16
- outputDir,
17
- publicPath,
18
- devServer,
19
- css,
15
+ ...pickUpSettings`
16
+ outputDir
17
+ publicPath
18
+ devServer
19
+ configureWebpack
20
+
21
+ filenameHashing
22
+ lintOnSave
23
+ runtimeCompiler
24
+ transpileDependencies
25
+ productionSourceMap
26
+ crossorigin
27
+ css
28
+ parallel
29
+ pwa
30
+ pluginOptions
31
+ `,
20
32
  chainWebpack: (config) => {
33
+ /* [DO NOT EDIT!] begin */
21
34
  config
22
35
  // clear entry points if there is any
23
36
  .entryPoints
24
37
  .clear()
25
38
  .end()
26
- /* [DO NOT EDIT!] begin */
27
- .plugin('manifest')
28
- .use(manifest.plugin)
29
- .init(Plugin => new Plugin(manifest.options))
30
- .end()
31
- /* [DO NOT EDIT!] end */
32
39
  .plugins
33
40
  // disable copy plugin
34
41
  .delete('copy')
@@ -37,10 +44,18 @@ module.exports = {
37
44
  .delete('preload')
38
45
  .delete('prefetch')
39
46
  .end();
47
+ if (manifest) {
48
+ config
49
+ .plugin('manifest')
50
+ .use(manifest.plugin)
51
+ .init(Plugin => new Plugin(manifest.options))
52
+ .end();
53
+ }
54
+ /* [DO NOT EDIT!] end */
55
+
56
+ /* put your custom code here
57
+ // Example: npm/yarn add -D compression-webpack-plugin webpack-bundle-analyzer
40
58
  if (isProd) {
41
- // put your custom code here
42
- // Example: yarn -D compression-webpack-plugin webpack-bundle-analyzer
43
- /*
44
59
  config
45
60
  .plugin('compression')
46
61
  .use(CompressionWebpackPlugin)
@@ -56,21 +71,10 @@ module.exports = {
56
71
  .plugin('analyzer')
57
72
  .use(BundleAnalyzerPlugin)
58
73
  .init(Plugin => new Plugin({
59
- openAnalyzer: true,
60
74
  reportFilename: resolve(__dirname, 'tmp/bundle-analyzer-report.html'),
61
75
  analyzerMode: 'static',
62
76
  }));
63
- */
64
77
  }
65
- },
66
- configureWebpack: {
67
- entry,
68
- resolve: {
69
- alias,
70
- },
71
- output: {
72
- filename: '[name].[hash:8].js',
73
- chunkFilename: 'js/[name].[hash:8].js',
74
- },
78
+ // */
75
79
  },
76
80
  };
@@ -3,19 +3,36 @@ const { env } = require('process');
3
3
  module.exports = (() => {
4
4
  let settings = {};
5
5
 
6
- /* eslint-disable global-require,import/no-extraneous-dependencies */
7
- const WebpackAssetsManifest = require('webpack-assets-manifest');
8
6
  try {
7
+ /* eslint-disable global-require,import/no-extraneous-dependencies */
9
8
  const yaml = require('js-yaml');
10
9
  const { readFileSync, readdirSync, lstatSync } = require('fs');
11
10
  const { resolve } = require('path');
11
+ /* eslint-enable global-require,import/no-extraneous-dependencies */
12
12
 
13
13
  const railsEnv = env.RAILS_ENV || 'development';
14
14
  const config = yaml.safeLoad(readFileSync(resolve('config/vue.yml'), 'utf8'))[railsEnv];
15
15
  const root = resolve(__dirname);
16
- const po = (config.public_output_path || 'vue_assets').replace(/(^\/+|\/+$)/g, '');
17
- const { manifestOutput, alias = {}, devServer = {} } = config;
18
- if (devServer.contentBase) {
16
+ const pop = (config.public_output_path || 'vue_assets').replace(/(^\/+|\/+$)/g, '');
17
+ const {
18
+ manifest_output: manifestOutput,
19
+ js_output: output,
20
+ alias = {},
21
+ devServer,
22
+
23
+ filenameHashing,
24
+ lintOnSave,
25
+ runtimeCompiler,
26
+ transpileDependencies,
27
+ productionSourceMap,
28
+ crossorigin,
29
+ css,
30
+ parallel,
31
+ pwa,
32
+ pluginOptions,
33
+ } = config;
34
+
35
+ if (devServer && devServer.contentBase) {
19
36
  devServer.contentBase = resolve(root, devServer.contentBase);
20
37
  }
21
38
  const entry = {};
@@ -34,20 +51,37 @@ module.exports = (() => {
34
51
  findAllJsFiles(assetRoot);
35
52
 
36
53
  settings = {
37
- ...config,
38
54
  env: railsEnv,
39
55
  root,
40
- outputDir: resolve(root, 'public', po),
41
- publicPath: `/${po}/`,
42
- alias: Object.keys(alias).reduce((obj, key) => ({
43
- ...obj,
44
- [key]: resolve(root, alias[key]),
45
- }), {}),
46
56
  manifestOutput: resolve(root, manifestOutput),
57
+
58
+ outputDir: resolve(root, 'public', pop),
59
+ publicPath: `/${pop}/`,
60
+ configureWebpack: {
61
+ entry,
62
+ output,
63
+ resolve: {
64
+ alias: Object.keys(alias).reduce((obj, key) => ({
65
+ ...obj,
66
+ [key]: resolve(root, alias[key]),
67
+ }), {}),
68
+ },
69
+ },
70
+
47
71
  devServer,
48
- entry,
72
+ filenameHashing,
73
+ lintOnSave,
74
+ runtimeCompiler,
75
+ transpileDependencies,
76
+ productionSourceMap,
77
+ crossorigin,
78
+ css,
79
+ parallel,
80
+ pwa,
81
+ pluginOptions,
49
82
  };
50
83
  } catch (e) {
84
+ /* eslint-disable-next-line global-require,import/no-extraneous-dependencies */
51
85
  const { execSync } = require('child_process');
52
86
 
53
87
  settings = JSON.parse(execSync('bundle exec rake vue:json_config', {
@@ -55,24 +89,26 @@ module.exports = (() => {
55
89
  encoding: 'utf8',
56
90
  }));
57
91
  }
58
- /* eslint-enable global-require,import/no-extraneous-dependencies */
59
92
 
60
- const assets = {};
61
- const manifest = {
62
- plugin: WebpackAssetsManifest,
63
- assets,
64
- options: {
65
- assets,
66
- entrypoints: true,
67
- writeToDisk: true,
68
- publicPath: true,
69
- output: settings.manifestOutput,
70
- },
71
- };
93
+ const getSettingsFromKeys = keys => [].concat(keys).filter(s => s)
94
+ .reduce((cfg, k) => {
95
+ const v = settings[k];
96
+ return v === undefined ? cfg : { ...cfg, [k]: v };
97
+ }, {});
72
98
 
73
99
  return {
74
- ...settings,
75
- manifest,
76
100
  isProd: settings.env === 'production',
101
+ manifest: {
102
+ /* eslint-disable-next-line global-require,import/no-extraneous-dependencies */
103
+ plugin: require('webpack-assets-manifest'),
104
+ options: {
105
+ entrypoints: true,
106
+ writeToDisk: true,
107
+ publicPath: true,
108
+ output: settings.manifestOutput,
109
+ },
110
+ },
111
+ getSettings: (keys = Object.keys(settings)) => getSettingsFromKeys(keys),
112
+ pickUpSettings: ([lines]) => getSettingsFromKeys(lines.split('\n').map(s => s.trim())),
77
113
  };
78
114
  })();
data/lib/source/vue.yml CHANGED
@@ -1,7 +1,10 @@
1
1
  default: &default
2
- package_manager: #PACKAGE_MANAGER
3
- manifestOutput: tmp/manifest.dev.json
2
+ package_manager: ${PACKAGE_MANAGER}
3
+ manifest_output: tmp/manifest.json
4
4
  public_output_path: vue_assets
5
+ # js_output:
6
+ # filename: 'js/[name].[hash:8].js'
7
+ # chunkFilename: 'js/[name].[hash:8].js'
5
8
  alias:
6
9
  '@': app/assets/vue
7
10
  ~views: app/assets/vue/components/views
@@ -12,15 +15,18 @@ development:
12
15
  devServer:
13
16
  contentBase: public
14
17
  host: localhost
15
- port: 3033
18
+ port: 3080
16
19
  compress: true
17
- launch_node: vue-cli-service serve
18
-
19
- test:
20
- <<: *default
21
20
 
22
21
  production:
23
22
  <<: *default
23
+ manifest_output: app/assets/vue/manifest.json
24
+ productionSourceMap: false
24
25
  css:
25
26
  extract: true
26
- manifestOutput: app/assets/vue/manifest.json
27
+ modern: true
28
+
29
+ test:
30
+ <<: *default
31
+ # launch_dev_service: vue-cli-service serve
32
+ # filenameHashing: false