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
@@ -0,0 +1,67 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'test_helper'
4
+
5
+ class CommandsTest < ViteRails::Test
6
+ def stub_builder(stale:, build_with_vite:)
7
+ ViteRails.builder.stub :stale?, stale do
8
+ ViteRails.builder.stub :build_with_vite, build_with_vite do
9
+ yield
10
+ end
11
+ end
12
+ end
13
+
14
+ def test_bootstrap
15
+ assert ViteRails.bootstrap
16
+ end
17
+
18
+ def test_build_returns_success_status_when_stale
19
+ stub_builder(stale: true, build_with_vite: true) {
20
+ assert_equal true, ViteRails.build
21
+ assert_equal true, ViteRails.build_from_rake
22
+ }
23
+ end
24
+
25
+ def test_build_returns_success_status_when_fresh
26
+ stub_builder(stale: false, build_with_vite: true) {
27
+ assert_equal true, ViteRails.build
28
+ assert_equal true, ViteRails.build_from_rake
29
+ }
30
+ end
31
+
32
+ def test_build_returns_failure_status_when_stale
33
+ stub_builder(stale: true, build_with_vite: false) {
34
+ assert_equal false, ViteRails.build
35
+ }
36
+ end
37
+
38
+ def test_clean
39
+ with_rails_env('test') { |config|
40
+ manifest = config.build_output_dir.join('manifest.json')
41
+
42
+ # Should not clean, the manifest does not exist.
43
+ config.build_output_dir.mkdir unless config.build_output_dir.exist?
44
+ refute ViteRails.clean
45
+
46
+ # Should not clean, the file is recent.
47
+ manifest.write('{}')
48
+ assert ViteRails.clean_from_rake(OpenStruct.new)
49
+ assert manifest.exist?
50
+
51
+ # Should clean if we remove age restrictions.
52
+ assert ViteRails.clean(keep_up_to: 0, age_in_seconds: 0)
53
+ assert config.build_output_dir.exist?
54
+ refute manifest.exist?
55
+ }
56
+ end
57
+
58
+ def test_clobber
59
+ with_rails_env('test') { |config|
60
+ config.build_output_dir.mkdir unless config.build_output_dir.exist?
61
+ config.build_output_dir.join('manifest.json').write('{}')
62
+ assert config.build_output_dir.exist?
63
+ ViteRails.clobber
64
+ refute config.build_output_dir.exist?
65
+ }
66
+ end
67
+ end
@@ -3,78 +3,120 @@
3
3
  require 'test_helper'
4
4
 
5
5
  class ConfigurationTest < ViteRails::Test
6
- def setup
7
- @config = ViteRails::Configuration.new(
8
- root_path: Pathname.new(File.expand_path('test_app', __dir__)),
9
- config_path: Pathname.new(File.expand_path('./test_app/config/vite.yml', __dir__)),
10
- env: 'production',
11
- )
6
+ def expand_path(path)
7
+ File.expand_path(Pathname.new(__dir__).join(path).to_s)
8
+ end
9
+
10
+ def assert_path(expected, actual)
11
+ assert_equal expand_path(expected), actual.to_s
12
12
  end
13
13
 
14
- def test_source_path
15
- source_path = File.expand_path File.join(File.dirname(__FILE__), 'test_app/app/javascript').to_s
16
- assert_equal source_path, @config.source_path.to_s
14
+ def assert_pathname(expected, actual)
15
+ assert_equal Pathname.new(expand_path("test_app/#{ expected }")), actual
17
16
  end
18
17
 
19
- def test_source_entry_path
20
- source_entry_path = File.expand_path File.join(File.dirname(__FILE__), 'test_app/app/javascript', 'packs').to_s
21
- assert_equal @config.source_entry_path.to_s, source_entry_path
18
+ def resolve_config(mode: 'production', root: test_app_path, **attrs)
19
+ ViteRails::Config.resolve_config(mode: mode, root: root, **attrs)
22
20
  end
23
21
 
24
- def test_public_root_path
25
- public_root_path = File.expand_path File.join(File.dirname(__FILE__), 'test_app/public').to_s
26
- assert_equal @config.public_path.to_s, public_root_path
22
+ def setup
23
+ @config = resolve_config
27
24
  end
28
25
 
29
- def test_public_output_path
30
- public_output_path = File.expand_path File.join(File.dirname(__FILE__), 'test_app/public/packs').to_s
31
- assert_equal @config.public_output_path.to_s, public_output_path
26
+ def test_source_code_dir
27
+ assert_path 'test_app/app/frontend', @config.source_code_dir
28
+ end
32
29
 
33
- @config = ViteRails::Configuration.new(
34
- root_path: @config.root_path,
35
- config_path: Pathname.new(File.expand_path('./test_app/config/vite_public_root.yml', __dir__)),
36
- env: 'production',
37
- )
30
+ def test_entrypoints_dir
31
+ assert_path 'test_app/app/frontend/entrypoints', @config.resolved_entrypoints_dir
32
+ end
38
33
 
39
- public_output_path = File.expand_path File.join(File.dirname(__FILE__), 'public/packs').to_s
40
- assert_equal @config.public_output_path.to_s, public_output_path
34
+ def test_public_dir
35
+ assert_path 'test_app/public', @config.public_dir
41
36
  end
42
37
 
43
- def test_public_manifest_path
44
- public_manifest_path = File.expand_path File.join(File.dirname(__FILE__), 'test_app/public/packs', 'manifest.json').to_s
45
- assert_equal @config.public_manifest_path.to_s, public_manifest_path
38
+ def test_build_output_dir
39
+ assert_path 'test_app/public/vite-production', @config.build_output_dir
40
+
41
+ @config = resolve_config(config_path: 'config/vite_public_dir.json')
42
+ assert_path 'public/vite', @config.build_output_dir
46
43
  end
47
44
 
48
- def test_cache_path
49
- cache_path = File.expand_path File.join(File.dirname(__FILE__), 'test_app/tmp/cache/vite').to_s
50
- assert_equal @config.cache_path.to_s, cache_path
45
+ def test_manifest_path
46
+ assert_path 'test_app/public/vite-production/manifest.json', @config.manifest_path
51
47
  end
52
48
 
53
- def test_additional_paths
54
- assert_equal @config.additional_paths, ['app/assets', '/etc/yarn', 'some.config.js', 'app/elm']
49
+ def test_build_cache_dir
50
+ assert_path 'test_app/tmp/cache/vite', @config.build_cache_dir
55
51
  end
56
52
 
57
- def test_cache_manifest?
58
- assert @config.cache_manifest?
53
+ def test_watch_additional_paths
54
+ assert_equal [], @config.watch_additional_paths
55
+ @config = resolve_config(config_path: 'config/vite_additional_paths.json')
56
+ assert_equal ['config/*'], @config.watch_additional_paths
57
+ end
59
58
 
60
- with_rails_env('development') do
61
- refute ViteRails.config.cache_manifest?
59
+ def test_auto_build
60
+ refute @config.auto_build
61
+
62
+ with_rails_env('development') do |config|
63
+ assert config.auto_build
64
+ end
65
+
66
+ with_rails_env('test') do |config|
67
+ assert config.auto_build
62
68
  end
63
69
 
64
- with_rails_env('test') do
65
- refute ViteRails.config.cache_manifest?
70
+ with_rails_env('staging') do |config|
71
+ refute config.auto_build
66
72
  end
67
73
  end
68
74
 
69
- def test_compile?
70
- refute @config.compile?
75
+ def test_protocol
76
+ assert_equal 'http', @config.protocol
77
+ end
71
78
 
72
- with_rails_env('development') do
73
- assert ViteRails.config.compile?
74
- end
79
+ def test_host_with_port
80
+ assert_equal 3036, @config.port
75
81
 
76
- with_rails_env('test') do
77
- assert ViteRails.config.compile?
82
+ with_rails_env('development') do |config|
83
+ assert_equal 3535, config.port
84
+ assert_equal 'localhost:3535', config.host_with_port
78
85
  end
79
86
  end
87
+
88
+ def test_environment_vars
89
+ ViteRails.env = {
90
+ 'VITE_RUBY_AUTO_BUILD' => 'true',
91
+ 'VITE_RUBY_HOST' => 'example.com',
92
+ 'VITE_RUBY_PORT' => '1920',
93
+ 'VITE_RUBY_HTTPS' => 'true',
94
+ 'VITE_RUBY_CONFIG_PATH' => 'config/vite_additional_paths.json',
95
+ 'VITE_RUBY_BUILD_CACHE_DIR' => 'tmp/vitebuild',
96
+ 'VITE_RUBY_PUBLIC_DIR' => 'pb',
97
+ 'VITE_RUBY_PUBLIC_OUTPUT_DIR' => 'ft',
98
+ 'VITE_RUBY_ASSETS_DIR' => 'as',
99
+ 'VITE_RUBY_SOURCE_CODE_DIR' => 'app',
100
+ 'VITE_RUBY_ENTRYPOINTS_DIR' => 'frontend/entrypoints',
101
+ 'VITE_RUBY_HIDE_BUILD_CONSOLE_OUTPUT' => 'true',
102
+ }
103
+ @config = resolve_config
104
+ assert_equal true, @config.auto_build
105
+ assert_equal 'example.com', @config.host
106
+ assert_equal 1920, @config.port
107
+ assert_equal true, @config.https
108
+ assert_equal 'https', @config.protocol
109
+ assert_equal Pathname.new('config/vite_additional_paths.json'), @config.config_path
110
+ assert_pathname 'tmp/vitebuild', @config.build_cache_dir
111
+ assert_pathname 'pb', @config.public_dir
112
+ assert_equal Pathname.new('ft'), @config.public_output_dir
113
+ assert_pathname 'pb/ft', @config.build_output_dir
114
+ assert_equal 'as', @config.assets_dir
115
+ assert_pathname 'app', @config.source_code_dir
116
+ assert_equal 'frontend/entrypoints', @config.entrypoints_dir
117
+ assert_pathname 'app/frontend/entrypoints', @config.resolved_entrypoints_dir
118
+ assert_equal true, @config.hide_build_console_output
119
+ ensure
120
+ ViteRails.env = {}
121
+ end
80
122
  end
@@ -0,0 +1,101 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'test_helper'
4
+
5
+ class DevServerProxyTest < ViteRails::Test
6
+ include Rack::Test::Methods
7
+
8
+ def app
9
+ # Capture all changes to the env made by the proxy.
10
+ capture_app = Rack::Builder.new.run(->(env) {
11
+ [200, { 'Content-Type' => 'application/json' }, env.to_json]
12
+ })
13
+ # Avoid actually using the proxy.
14
+ Rack::Proxy.define_method(:perform_request) { |env| capture_app.call(env) }
15
+
16
+ ViteRails::DevServerProxy.new(capture_app)
17
+ end
18
+
19
+ def test_non_asset
20
+ get_with_dev_server_running '/'
21
+ assert_not_forwarded
22
+ end
23
+
24
+ def test_non_vite_asset
25
+ get_with_dev_server_running '/example_import.js'
26
+ assert_not_forwarded
27
+ end
28
+
29
+ def test_vite_asset
30
+ get_with_dev_server_running '/vite-production/application.js'
31
+ assert_forwarded to: '/application.js'
32
+ end
33
+
34
+ def test_vite_client
35
+ get_with_dev_server_running '/@vite/client'
36
+ assert_forwarded to: '/@vite/client'
37
+ end
38
+
39
+ def test_vite_import
40
+ get_with_dev_server_running '/@fs//package/example/app/frontend/App.vue?import&t=1611322300214&vue&type=style&index=0&lang.css'
41
+ assert_forwarded to: '/@fs//package/example/app/frontend/App.vue?import&t=1611322300214&vue&type=style&index=0&lang.css'
42
+ end
43
+
44
+ def test_hmr_for_stylesheet
45
+ get_with_dev_server_running '/colored.css?t=1611322562923'
46
+ assert_forwarded to: '/colored.css?t=1611322562923'
47
+ end
48
+
49
+ def test_hmr_for_imported_entrypoint
50
+ get_with_dev_server_running '/colored.css?import&t=1611322562923'
51
+ assert_forwarded to: '/colored.css?import&t=1611322562923'
52
+ end
53
+
54
+ def test_entrypoint_imported_from_entrypoint
55
+ header 'Referer', 'http://localhost:3000/vite-production/application.js'
56
+ get_with_dev_server_running '/example_import.js'
57
+ assert_forwarded to: '/example_import.js'
58
+ end
59
+
60
+ def test_without_dev_server_running
61
+ get '/vite-production/application.js'
62
+ assert_not_forwarded
63
+
64
+ get '/colored.css?import&t=1611322562923'
65
+ assert_not_forwarded
66
+
67
+ header 'Referer', 'http://localhost:3000/vite-production/application.js'
68
+ get '/example_import.js'
69
+ assert_not_forwarded
70
+ end
71
+
72
+ private
73
+
74
+ def get_with_dev_server_running(*args)
75
+ with_dev_server_running {
76
+ get(*args)
77
+ }
78
+ end
79
+
80
+ def assert_not_forwarded
81
+ assert last_response.ok?
82
+ env = JSON.parse(last_response.body)
83
+ assert_nil env['HTTP_X_FORWARDED_HOST']
84
+ assert_nil env['HTTP_X_FORWARDED_PORT']
85
+ end
86
+
87
+ def assert_forwarded(to: nil)
88
+ assert last_response.ok?
89
+ env = JSON.parse(last_response.body)
90
+
91
+ assert_equal ViteRails.config.host, env['HTTP_X_FORWARDED_HOST']
92
+ assert_equal ViteRails.config.port, Integer(env['HTTP_X_FORWARDED_PORT'])
93
+
94
+ return unless to
95
+
96
+ path, query = to.split('?')
97
+ assert_equal path, env['PATH_INFO']
98
+ assert_equal query, env['QUERY_STRING']
99
+ assert_equal to, env['REQUEST_URI']
100
+ end
101
+ end
@@ -6,34 +6,4 @@ class DevServerTest < ViteRails::Test
6
6
  def test_running?
7
7
  refute ViteRails.dev_server.running?
8
8
  end
9
-
10
- def test_host
11
- with_rails_env('development') do
12
- assert_equal ViteRails.config.host, 'localhost'
13
- end
14
- end
15
-
16
- def test_port
17
- with_rails_env('development') do
18
- assert_equal ViteRails.config.port, 3035
19
- end
20
- end
21
-
22
- def test_https?
23
- with_rails_env('development') do
24
- assert_equal ViteRails.config.https, false
25
- end
26
- end
27
-
28
- def test_protocol
29
- with_rails_env('development') do
30
- assert_equal ViteRails.config.protocol, 'http'
31
- end
32
- end
33
-
34
- def test_host_with_port
35
- with_rails_env('development') do
36
- assert_equal ViteRails.config.host_with_port, 'localhost:3035'
37
- end
38
- end
39
9
  end
@@ -4,39 +4,77 @@ require 'test_helper'
4
4
 
5
5
  class EngineRakeTasksTest < Minitest::Test
6
6
  def setup
7
- remove_vite_binstubs
7
+ remove_vite_files
8
8
  end
9
9
 
10
10
  def teardown
11
- remove_vite_binstubs
11
+ remove_vite_files
12
12
  end
13
13
 
14
- def test_task_mounted
15
- output = Dir.chdir(mounted_app_path) { `rake -T` }
14
+ def test_tasks_mounted
15
+ output = within_mounted_app { `bundle exec rake -T` }
16
16
  assert_includes output, 'app:vite'
17
17
  end
18
18
 
19
- def test_binstubs
20
- Dir.chdir(mounted_app_path) { `bundle exec rake app:vite:binstubs` }
21
- vite_binstub_paths.each { |path| assert File.exist?(path) }
19
+ def test_rake_tasks
20
+ within_mounted_app { `bundle exec rake app:vite:binstubs` }
21
+ assert vite_binstub_path.exist?
22
+
23
+ within_mounted_app { `bundle exec rake app:vite:install` }
24
+ assert vite_config_ts_path.exist?
25
+ assert app_frontend_dir.exist?
26
+
27
+ within_mounted_app { `bundle exec rake app:vite:build` }
28
+ assert app_public_dir.exist?
29
+ assert app_public_dir.join('manifest.json').exist?
30
+ assert app_public_dir.join('assets').exist?
31
+
32
+ within_mounted_app { `bundle exec rake app:vite:clean` }
33
+ assert app_public_dir.join('manifest.json').exist? # Still fresh
34
+
35
+ within_mounted_app { `bundle exec rake app:vite:clean[0,0]` }
36
+ refute app_public_dir.join('manifest.json').exist?
37
+
38
+ within_mounted_app { `bundle exec rake app:vite:clobber` }
39
+ refute app_public_dir.exist?
40
+ rescue Minitest::Assertion => error
41
+ raise error unless Rails.gem_version >= Gem::Version.new('6.1.0')
22
42
  end
23
43
 
24
44
  private
25
45
 
46
+ def within_mounted_app
47
+ Dir.chdir(mounted_app_path) { yield }
48
+ end
49
+
26
50
  def mounted_app_path
27
- File.expand_path('mounted_app', __dir__)
51
+ Pathname.new(File.expand_path(__dir__)).join('mounted_app')
52
+ end
53
+
54
+ def root_dir
55
+ mounted_app_path.join('test/dummy')
56
+ end
57
+
58
+ def vite_binstub_path
59
+ root_dir.join('bin/vite')
60
+ end
61
+
62
+ def vite_config_ts_path
63
+ root_dir.join('vite.config.ts')
64
+ end
65
+
66
+ def app_frontend_dir
67
+ root_dir.join('app/frontend')
28
68
  end
29
69
 
30
- def vite_binstub_paths
31
- [
32
- "#{ mounted_app_path }/test/dummy/bin/vite",
33
- "#{ mounted_app_path }/test/dummy/bin/vite-dev-server",
34
- ]
70
+ def app_public_dir
71
+ root_dir.join('public/vite-dev')
35
72
  end
36
73
 
37
- def remove_vite_binstubs
38
- vite_binstub_paths.each do |path|
39
- File.delete(path) if File.exist?(path)
40
- end
74
+ def remove_vite_files
75
+ vite_binstub_path.delete if vite_binstub_path.exist?
76
+ vite_config_ts_path.delete if vite_config_ts_path.exist?
77
+ app_frontend_dir.rmtree if app_frontend_dir.exist?
78
+ app_public_dir.rmtree if app_public_dir.exist?
41
79
  end
42
80
  end