vite_rails 1.0.4 → 1.0.9

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 (51) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +26 -1
  3. data/CONTRIBUTING.md +0 -1
  4. data/README.md +27 -65
  5. data/lib/install/javascript/entrypoints/application.js +8 -4
  6. data/lib/install/template.rb +1 -1
  7. data/lib/tasks/vite/build.rake +2 -6
  8. data/lib/tasks/vite/clean.rake +1 -3
  9. data/lib/tasks/vite/info.rake +0 -1
  10. data/lib/tasks/vite/verify_install.rake +3 -3
  11. data/lib/vite_rails.rb +19 -25
  12. data/lib/vite_rails/builder.rb +11 -4
  13. data/lib/vite_rails/commands.rb +50 -10
  14. data/lib/vite_rails/config.rb +35 -23
  15. data/lib/vite_rails/dev_server_proxy.rb +27 -16
  16. data/lib/vite_rails/helper.rb +36 -8
  17. data/lib/vite_rails/manifest.rb +20 -15
  18. data/lib/vite_rails/runner.rb +2 -5
  19. data/lib/vite_rails/version.rb +1 -1
  20. data/package.json +8 -20
  21. data/package/default.vite.json +1 -1
  22. data/test/builder_test.rb +27 -22
  23. data/test/commands_test.rb +67 -0
  24. data/test/configuration_test.rb +88 -46
  25. data/test/dev_server_proxy_test.rb +101 -0
  26. data/test/dev_server_test.rb +0 -30
  27. data/test/engine_rake_tasks_test.rb +55 -17
  28. data/test/helper_test.rb +37 -105
  29. data/test/manifest_test.rb +33 -29
  30. data/test/mode_test.rb +6 -11
  31. data/test/mounted_app/test/dummy/config/vite.json +5 -11
  32. data/test/mounted_app/test/dummy/package.json +2 -1
  33. data/test/mounted_app/test/dummy/yarn.lock +208 -0
  34. data/test/rake_tasks_test.rb +5 -19
  35. data/test/runner_test.rb +31 -0
  36. data/test/test_app/app/frontend/entrypoints/application.js +2 -0
  37. data/test/test_app/config/vite.json +0 -2
  38. data/test/test_app/config/vite_additional_paths.json +5 -0
  39. data/test/test_app/config/vite_public_dir.json +5 -0
  40. data/test/test_app/public/vite-production/manifest.json +22 -0
  41. data/test/test_helper.rb +48 -14
  42. metadata +21 -23
  43. data/test/command_test.rb +0 -35
  44. data/test/dev_server_runner_test.rb +0 -83
  45. data/test/test_app/app/javascript/entrypoints/application.js +0 -10
  46. data/test/test_app/app/javascript/entrypoints/multi_entry.css +0 -4
  47. data/test/test_app/app/javascript/entrypoints/multi_entry.js +0 -4
  48. data/test/test_app/config/vite_public_root.yml +0 -20
  49. data/test/test_app/public/vite/manifest.json +0 -36
  50. data/test/vite_runner_test.rb +0 -59
  51. data/test/webpacker_test.rb +0 -15
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: '09b3f9165e33562bd060ff1c5bc3cb2efb76a68d4de1bc3548a213110df6bba4'
4
- data.tar.gz: 3aac713bfb90f0586c2309217b45d64bc394312ed5fb08be44391d3dcb68d459
3
+ metadata.gz: a7036c3650b1b44c82158220474b56e26488785cefb0a99044444708d603001a
4
+ data.tar.gz: 8161dbb668ff8c2308de6783e1dbff81faf60b13cd87393348070a2f8b2f9c18
5
5
  SHA512:
6
- metadata.gz: '08b9ee75915396e16078094f1870211e5667cc3f9edf9502844be884a556a6c9378bbcdef8374498761643fab94c0302930d18737d98ceaae013c0da0ac9f2d6'
7
- data.tar.gz: 482461f60d07e91c99084f74089d10fe07ac2db20aad1c324a45f5b6fbb1f4f815dd436993c21798c4c18e116d5bee729b83abe08e85d02757637731a242d7b0
6
+ metadata.gz: a5ecb6327e2009b5fcf8aa91f90989264538db013dafc4b34a361e11b60a8d69bd394d6c6e5043583ff1cfe35fe5464424e26b616304ee30089c9e5a06fa2bda
7
+ data.tar.gz: 04124e8f3c0063b1461185fbfb665623b0c49c6ea3712952a857eb1bb00886e420ae64335609f4879377013ef7f32506ef84400af52f9a3385c90b9b5c025193
@@ -1,3 +1,28 @@
1
- ## Vite Rails 1.0.0
1
+ ## Vite Rails 1.0.9 (2020-01-22)
2
+
3
+ - Ensure `configPath` and `publicDir` are scoped from `root`, both in Ruby and JS.
4
+
5
+ ## Vite Rails 1.0.8 (2020-01-21)
6
+
7
+ - Change the default of `sourceCodeDir` to `app/frontend`, add instructions for folks migrating
8
+ from a `app/javascript` structure.
9
+
10
+ ## Vite Rails 1.0.7 (2020-01-20)
11
+
12
+ - Add `vite_client_tag` to ensure the Vite client can be loaded in apps that don't use any imports.
13
+
14
+ ## Vite Rails 1.0.6 (2020-01-20)
15
+
16
+ - Ensure running `bin/rake assets:precompile` automatically invokes `vite:build`.
17
+
18
+ ## Vite Rails 1.0.5 (2020-01-20)
19
+
20
+ - Automatically add `<link rel="modulepreload">` and `<link rel="stylesheet">` when using `vite_javascript_tag`, which simplifies usage.
21
+
22
+ ## Vite Rails 1.0.4 (2020-01-19)
23
+
24
+ - Remove Vue specific examples from installation templates, to ensure they always run.
25
+
26
+ ## Vite Rails 1.0.0 (2020-01-18)
2
27
 
3
28
  Initial Version
@@ -6,7 +6,6 @@
6
6
 
7
7
  ```
8
8
  bundle install
9
- yarn
10
9
  ```
11
10
 
12
11
  ## Making sure your changes pass all tests
data/README.md CHANGED
@@ -19,26 +19,35 @@
19
19
  </p>
20
20
  </h1>
21
21
 
22
+ [website]: https://vite-rails.netlify.app/
23
+ [configuration reference]: https://vite-rails.netlify.app/config/
24
+ [features]: https://vite-rails.netlify.app/guide/introduction.html
25
+ [guides]: https://vite-rails.netlify.app/guide/
26
+ [config]: https://vite-rails.netlify.app/config/
22
27
  [vite_rails]: https://github.com/ElMassimo/vite_rails
23
28
  [webpacker]: https://github.com/rails/webpacker
24
29
  [vite]: http://vitejs.dev/
25
30
  [config file]: https://github.com/ElMassimo/vite_rails/blob/main/package/default.vite.json
31
+ [example app]: https://github.com/ElMassimo/vite_rails/tree/main/examples/blog
32
+ [heroku]: https://vite-rails-demo.herokuapp.com/
26
33
 
27
- [__Vite Rails__][vite_rails] allows you to use [Vite] to power the frontend.
34
+ [__Vite Rails__][vite_rails] allows you to use [Vite] to power the frontend of your Rails app.
28
35
 
29
36
  [Vite] is to frontend tooling as Ruby to programming, pure joy! 😍
30
37
 
38
+ Check an [example app] running on [Heroku].
39
+
31
40
  ## Features ⚡️
32
41
 
33
- - 🤖 Automatic Entrypoint Detection
34
- - ⚡️ Hot Reload
35
- - ⚙️ Rake Tasks
36
- - 🪝 Hooks to <kbd>assets:precompile</kbd> and friends
37
- - And more! (detects changes, and builds automatically if Vite is not running)
42
+ - 🤖 Automatic entrypoint detection
43
+ - ⚡️ Blazing fast hot reload
44
+ - 🚀 Zero-config deployments
45
+ - 🤝 Integrated with <kbd>assets:precompile</kbd>
46
+ - [And more!][features]
38
47
 
39
48
  ## Documentation 📖
40
49
 
41
- A documentation website is coming soon!
50
+ Visit the [documentation website][website] to check out the [guides] and searchable [configuration reference].
42
51
 
43
52
  ## Installation 💿
44
53
 
@@ -57,74 +66,27 @@ bin/rake vite:install
57
66
 
58
67
  This will generate configuration files and a sample setup.
59
68
 
60
- ## Usage 🚀
61
-
62
- Drawing inspiration from [webpacker], any files in `app/javascript/entrypoints`
63
- will be considered entries to your application (SPAs or pages).
64
-
65
- These files will be detected, and passed on to Vite, all configuration is done
66
- for you.
67
-
68
- ### Imports ⤵️
69
-
70
- For convenience, a `~/` import alias is configured to `app/javascript`, allowing
71
- you to use absolute paths:
69
+ Additional installation instructions are available in the [documentation website][website].
72
70
 
73
- ```js
74
- import { createApp } from 'vue'
75
- import App from '~/App.vue'
76
- import '~/channels'
71
+ ## Getting Started 💻
77
72
 
78
- createApp(App).mount('#app')
79
- ```
80
-
81
- ### Tags 🏷
82
-
83
- `vite_typescript_tag`, `vite_javascript_tag`, and `vite_stylesheet_tag` can be
84
- used to output `<script>` and `<link>` tags in your Rails layouts or templates.
73
+ Restart your Rails server, and then run <kbd>bin/vite</kbd> to start the Vite development server.
85
74
 
86
- ```html
87
- <head>
88
- <title>Joie</title>
89
- <%= csrf_meta_tags %>
90
- <%= csp_meta_tag %>
75
+ Add the following your `views/layouts/application.html.erb`:
91
76
 
92
- <%= stylesheet_link_tag 'application', media: 'all', 'data-turbolinks-track': 'reload' %>
93
- <%= javascript_pack_tag 'application', 'data-turbolinks-track': 'reload' %>
94
-
95
- <%= vite_stylesheet_tag 'strange' %>
96
- <%= vite_typescript_tag 'application' %>
97
- </head>
77
+ ```erb
78
+ <%= vite_client_tag %>
79
+ <%= vite_javascript_tag 'application' %>
98
80
  ```
99
81
 
100
- For other types of assets, you can use `vite_asset_path` and pass that to the appropriate tag helper.
101
-
102
- ## Configuration ⚙️
103
-
104
- This is what your `config/vite.json` might look like:
105
-
106
- ```json
107
- {
108
- "all": {
109
- "watchAdditionalPaths": []
110
- },
111
- "development": {
112
- "autoBuild": true,
113
- "publicOutputDir": "vite-dev",
114
- "port": 3036
115
- },
116
- "test": {
117
- "autoBuild": true,
118
- "publicOutputDir": "vite-test"
119
- }
120
- }
121
- ```
82
+ Visit any page and you should see a printed console output: `Vite ⚡️ Rails`.
122
83
 
123
- Check [this file][config file] to see all config options, documentation is coming soon.
84
+ For more [guides] and a full [configuration reference], check the [documentation website][website].
124
85
 
125
- ## Inspiration 💡
86
+ ## Special Thanks 🙏
126
87
 
127
88
  - [webpacker]
89
+ - [vite]
128
90
 
129
91
  ## License
130
92
 
@@ -1,3 +1,10 @@
1
+ // To see this message, add the following to the `<head>` section in your
2
+ // views/layouts/application.html.erb
3
+ //
4
+ // <%= vite_client_tag %>
5
+ // <%= vite_javascript_tag 'application' %>
6
+ console.log('Vite ⚡️ Rails')
7
+
1
8
  // Example: Load Rails libraries in Vite.
2
9
  //
3
10
  // import '@rails/ujs'
@@ -11,8 +18,5 @@
11
18
  // Turbolinks.start()
12
19
  // ActiveStorage.start()
13
20
 
14
- // Example: Import a stylesheet in app/javascript/index.css
21
+ // Example: Import a stylesheet in app/frontend/index.css
15
22
  // import '~/index.css'
16
-
17
- console.log('Vite ⚡️ Rails')
18
-
@@ -6,7 +6,7 @@ copy_file "#{ __dir__ }/config/vite.json", ViteRails.config.config_path
6
6
  copy_file "#{ __dir__ }/config/vite.config.ts", Rails.root.join('vite.config.ts')
7
7
 
8
8
  say 'Creating entrypoints directory'
9
- directory "#{ __dir__ }/javascript/entrypoints", ViteRails.config.source_code_dir.join(ViteRails.config.entrypoints_dir)
9
+ directory "#{ __dir__ }/javascript/entrypoints", ViteRails.config.resolved_entrypoints_dir
10
10
 
11
11
  apply "#{ __dir__ }/binstubs.rb"
12
12
 
@@ -3,7 +3,7 @@
3
3
  $stdout.sync = true
4
4
 
5
5
  def enhance_assets_precompile
6
- Rake::Task['assets:precompile'] do |task|
6
+ Rake::Task['assets:precompile'].enhance do |task|
7
7
  prefix = task.name.split(/#|assets:precompile/).first
8
8
 
9
9
  Rake::Task["#{ prefix }vite:build"].invoke
@@ -13,11 +13,7 @@ end
13
13
  namespace :vite do
14
14
  desc 'Compile JavaScript packs using vite for production with digests'
15
15
  task build: [:'vite:verify_install', :environment] do
16
- ViteRails.with_node_env(ENV.fetch('NODE_ENV', 'production')) do
17
- ViteRails.ensure_log_goes_to_stdout do
18
- ViteRails.build || exit!
19
- end
20
- end
16
+ ViteRails.build_from_rake
21
17
  end
22
18
  end
23
19
 
@@ -5,9 +5,7 @@ $stdout.sync = true
5
5
  namespace :vite do
6
6
  desc 'Remove old compiled vites'
7
7
  task :clean, [:keep, :age] => [:'vite:verify_install', :environment] do |_, args|
8
- ViteRails.ensure_log_goes_to_stdout do
9
- ViteRails.clean(keep_up_to: Integer(args.keep || 2), age_in_seconds: Integer(args.age || 3600))
10
- end
8
+ ViteRails.clean_from_rake(args)
11
9
  end
12
10
  end
13
11
 
@@ -14,7 +14,6 @@ namespace :vite do
14
14
  $stdout.puts "vite-plugin-ruby: \n#{ `npm list vite-plugin-ruby version` }"
15
15
 
16
16
  $stdout.puts "Is bin/vite present?: #{ File.exist? 'bin/vite' }"
17
- $stdout.puts "Is bin/vite-dev-server present?: #{ File.exist? 'bin/vite-dev-server' }"
18
17
  $stdout.puts "Is bin/yarn present?: #{ File.exist? 'bin/yarn' }"
19
18
  end
20
19
  end
@@ -11,10 +11,10 @@ namespace :vite do
11
11
  WARN
12
12
  exit!
13
13
  end
14
- unless ViteRails.config.config_path.exist?
15
- path = ViteRails.config.config_path.relative_path_from(Pathname.new(pwd)).to_s
14
+ config_path = Rails.root.join(ViteRails.config.config_path)
15
+ unless config_path.exist?
16
16
  warn <<~WARN
17
- Configuration #{ path } file for vite-plugin-ruby not found.
17
+ Configuration #{ config_path } file for vite-plugin-ruby not found.
18
18
  Make sure vite:install has run successfully before running dependent tasks.
19
19
  WARN
20
20
  exit!
@@ -1,7 +1,7 @@
1
1
  # frozen_string_literal: true
2
2
 
3
- require 'active_support'
4
- require 'active_support/core_ext/class/attribute_accessors'
3
+ require 'rails'
4
+ require 'active_support/all'
5
5
 
6
6
  require 'zeitwerk'
7
7
  loader = Zeitwerk::Loader.for_gem
@@ -13,18 +13,10 @@ class ViteRails
13
13
  # Internal: Prefix used for environment variables that modify the configuration.
14
14
  ENV_PREFIX = 'VITE_RUBY'
15
15
 
16
- # Public: Additional environment variables to pass to Vite.
17
- #
18
- # Example:
19
- # ViteRails.env['VITE_RUBY_CONFIG_PATH'] = 'config/alternate_vite.json'
20
- cattr_accessor(:env) { ENV.select { |key, _| key.start_with?(ENV_PREFIX) } }
21
-
22
- cattr_accessor(:logger) { ActiveSupport::TaggedLogging.new(ActiveSupport::Logger.new(STDOUT)) }
23
-
24
16
  class << self
25
- delegate :config, :builder, :manifest, :commands, :dev_server, to: :instance
17
+ delegate :config, :builder, :manifest, :commands, :dev_server, :dev_server_running?, to: :instance
26
18
  delegate :mode, to: :config
27
- delegate :bootstrap, :clean, :clobber, :build, to: :commands
19
+ delegate :bootstrap, :clean, :clean_from_rake, :clobber, :build, :build_from_rake, to: :commands
28
20
 
29
21
  attr_writer :instance
30
22
 
@@ -45,21 +37,23 @@ class ViteRails
45
37
  false
46
38
  end
47
39
 
48
- def with_node_env(env)
49
- original = ENV['NODE_ENV']
50
- ENV['NODE_ENV'] = env
51
- yield
52
- ensure
53
- ENV['NODE_ENV'] = original
40
+ # Internal: Allows to obtain any env variables for configuration options.
41
+ def load_env_variables
42
+ ENV.select { |key, _| key.start_with?(ENV_PREFIX) }
54
43
  end
44
+ end
55
45
 
56
- def ensure_log_goes_to_stdout
57
- old_logger = ViteRails.logger
58
- ViteRails.logger = ActiveSupport::Logger.new(STDOUT)
59
- yield
60
- ensure
61
- ViteRails.logger = old_logger
62
- end
46
+ # Public: Additional environment variables to pass to Vite.
47
+ #
48
+ # Example:
49
+ # ViteRails.env['VITE_RUBY_CONFIG_PATH'] = 'config/alternate_vite.json'
50
+ cattr_accessor(:env) { load_env_variables }
51
+
52
+ cattr_accessor(:logger) { ActiveSupport::TaggedLogging.new(ActiveSupport::Logger.new(STDOUT)) }
53
+
54
+ # Public: Returns true if the Vite development server is running.
55
+ def dev_server_running?
56
+ ViteRails.run_proxy? && dev_server.running?
63
57
  end
64
58
 
65
59
  # Public: Current instance configuration for Vite.
@@ -67,9 +67,18 @@ private
67
67
  def build_with_vite
68
68
  logger.info 'Building with Vite ⚡️'
69
69
 
70
- stdout, stderr, status = Open3.capture3(vite_env,
71
- "#{ which_ruby } ./bin/vite build --mode #{ config.mode }", chdir: File.expand_path(config.root))
70
+ command = "#{ which_ruby } ./bin/vite build --mode #{ config.mode }"
71
+ stdout, stderr, status = Open3.capture3(vite_env, command, chdir: File.expand_path(config.root))
72
72
 
73
+ log_build_result(stdout, stderr, status)
74
+
75
+ status.success?
76
+ end
77
+
78
+ # Internal: Outputs the build results.
79
+ #
80
+ # NOTE: By default it also outputs the manifest entries.
81
+ def log_build_result(stdout, stderr, status)
73
82
  if status.success?
74
83
  logger.info "Build with Vite complete: #{ config.build_output_dir }"
75
84
  logger.error(stderr.to_s) unless stderr.empty?
@@ -78,8 +87,6 @@ private
78
87
  non_empty_streams = [stdout, stderr].delete_if(&:empty?)
79
88
  logger.error "Build with Vite failed:\n#{ non_empty_streams.join("\n\n") }"
80
89
  end
81
-
82
- status.success?
83
90
  end
84
91
 
85
92
  # Internal: Used to prefix the bin/vite executable file.
@@ -11,6 +11,15 @@ class ViteRails::Commands
11
11
  manifest.refresh
12
12
  end
13
13
 
14
+ # Public: Defaults to production, and exits if the build fails.
15
+ def build_from_rake
16
+ with_node_env(ENV.fetch('NODE_ENV', 'production')) {
17
+ ensure_log_goes_to_stdout {
18
+ build || exit!
19
+ }
20
+ }
21
+ end
22
+
14
23
  # Public: Builds all assets that are managed by Vite, from the entrypoints.
15
24
  def build
16
25
  builder.build.tap { manifest.refresh }
@@ -22,6 +31,13 @@ class ViteRails::Commands
22
31
  config.build_cache_dir.rmtree if config.build_cache_dir.exist?
23
32
  end
24
33
 
34
+ # Public: Receives arguments from a rake task.
35
+ def clean_from_rake(args)
36
+ ensure_log_goes_to_stdout {
37
+ clean(keep_up_to: Integer(args.keep || 2), age_in_seconds: Integer(args.age || 3600))
38
+ }
39
+ end
40
+
25
41
  # Public: Cleanup old assets in the output directory.
26
42
  #
27
43
  # keep_up_to - Max amount of backups to preserve.
@@ -33,21 +49,16 @@ class ViteRails::Commands
33
49
  # To force only 1 backup to be kept: clean(1, 0)
34
50
  # To only keep files created within the last 10 minutes: clean(0, 600)
35
51
  def clean(keep_up_to: 2, age_in_seconds: 3600)
36
- return false unless config.build_output_dir.exist? && config.manifest_path.exist?
52
+ return false unless may_clean?
37
53
 
38
- versions.sort.reverse
54
+ versions
39
55
  .each_with_index
40
56
  .drop_while { |(mtime, _), index|
41
57
  max_age = [0, Time.now - Time.at(mtime)].max
42
58
  max_age < age_in_seconds || index < keep_up_to
43
59
  }
44
- .each do |(_, files), _index|
45
- files.each do |file|
46
- next unless File.file?(file)
47
-
48
- File.delete(file)
49
- logger.info("Removed #{ file }")
50
- end
60
+ .each do |(_, files), _|
61
+ clean_files(files)
51
62
  end
52
63
  true
53
64
  end
@@ -56,13 +67,42 @@ private
56
67
 
57
68
  delegate :config, :builder, :manifest, :logger, to: :@vite_rails
58
69
 
70
+ def may_clean?
71
+ config.build_output_dir.exist? && config.manifest_path.exist?
72
+ end
73
+
74
+ def clean_files(files)
75
+ files.select { |file| File.file?(file) }.each do |file|
76
+ File.delete(file)
77
+ logger.info("Removed #{ file }")
78
+ end
79
+ end
80
+
59
81
  def versions
60
82
  all_files = Dir.glob("#{ config.build_output_dir }/**/*")
61
83
  entries = all_files - [config.manifest_path] - current_version_files
62
- entries.reject { |file| File.directory?(file) }.group_by { |file| File.mtime(file).utc.to_i }
84
+ entries.reject { |file| File.directory?(file) }
85
+ .group_by { |file| File.mtime(file).utc.to_i }
86
+ .sort.reverse
63
87
  end
64
88
 
65
89
  def current_version_files
66
90
  Dir.glob(manifest.refresh.values.map { |value| config.build_output_dir.join("#{ value['file'] }*") })
67
91
  end
92
+
93
+ def with_node_env(env)
94
+ original = ENV['NODE_ENV']
95
+ ENV['NODE_ENV'] = env
96
+ yield
97
+ ensure
98
+ ENV['NODE_ENV'] = original
99
+ end
100
+
101
+ def ensure_log_goes_to_stdout
102
+ old_logger = ViteRails.logger
103
+ ViteRails.logger = ActiveSupport::Logger.new(STDOUT)
104
+ yield
105
+ ensure
106
+ ViteRails.logger = old_logger
107
+ end
68
108
  end