vite_rails 1.0.6 → 1.0.11
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/CHANGELOG.md +24 -0
 - data/CONTRIBUTING.md +0 -1
 - data/README.md +43 -70
 - data/lib/install/config/vite.config.ts +1 -1
 - data/lib/install/javascript/entrypoints/application.js +8 -4
 - data/lib/install/template.rb +3 -3
 - data/lib/tasks/vite/build.rake +12 -6
 - data/lib/tasks/vite/clean.rake +1 -3
 - data/lib/tasks/vite/install_dependencies.rake +3 -9
 - data/lib/tasks/vite/verify_install.rake +3 -3
 - data/lib/vite_rails.rb +23 -34
 - data/lib/vite_rails/builder.rb +11 -13
 - data/lib/vite_rails/commands.rb +51 -10
 - data/lib/vite_rails/config.rb +65 -35
 - data/lib/vite_rails/dev_server_proxy.rb +26 -18
 - data/lib/vite_rails/helper.rb +17 -8
 - data/lib/vite_rails/manifest.rb +14 -12
 - data/lib/vite_rails/runner.rb +3 -6
 - data/lib/vite_rails/version.rb +1 -1
 - data/package.json +9 -2
 - data/package/default.vite.json +2 -1
 - data/test/builder_test.rb +27 -22
 - data/test/commands_test.rb +67 -0
 - data/test/config_test.rb +133 -0
 - data/test/dev_server_proxy_test.rb +102 -0
 - data/test/dev_server_test.rb +0 -30
 - data/test/engine_rake_tasks_test.rb +56 -17
 - data/test/helper_test.rb +37 -105
 - data/test/manifest_test.rb +33 -29
 - data/test/mode_test.rb +6 -11
 - data/test/mounted_app/test/dummy/config/vite.json +5 -11
 - data/test/mounted_app/test/dummy/package.json +5 -4
 - data/test/mounted_app/test/dummy/yarn.lock +208 -0
 - data/test/rake_tasks_test.rb +7 -21
 - data/test/runner_test.rb +31 -0
 - data/test/test_app/app/frontend/entrypoints/application.js +2 -0
 - data/test/test_app/config/vite.json +0 -2
 - data/test/test_app/config/vite_additional_paths.json +5 -0
 - data/test/test_app/config/vite_public_dir.json +5 -0
 - data/test/test_app/public/vite-production/manifest.json +22 -0
 - data/test/test_helper.rb +48 -14
 - metadata +23 -25
 - data/test/command_test.rb +0 -35
 - data/test/configuration_test.rb +0 -80
 - data/test/dev_server_runner_test.rb +0 -83
 - data/test/test_app/app/javascript/entrypoints/application.js +0 -10
 - data/test/test_app/app/javascript/entrypoints/multi_entry.css +0 -4
 - data/test/test_app/app/javascript/entrypoints/multi_entry.js +0 -4
 - data/test/test_app/config/vite_public_root.yml +0 -20
 - data/test/test_app/public/vite/manifest.json +0 -36
 - data/test/vite_runner_test.rb +0 -59
 - data/test/webpacker_test.rb +0 -15
 
    
        data/lib/vite_rails/commands.rb
    CHANGED
    
    | 
         @@ -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 }
         
     | 
| 
         @@ -20,6 +29,14 @@ class ViteRails::Commands 
     | 
|
| 
       20 
29 
     | 
    
         
             
              def clobber
         
     | 
| 
       21 
30 
     | 
    
         
             
                config.build_output_dir.rmtree if config.build_output_dir.exist?
         
     | 
| 
       22 
31 
     | 
    
         
             
                config.build_cache_dir.rmtree if config.build_cache_dir.exist?
         
     | 
| 
      
 32 
     | 
    
         
            +
                config.vite_cache_dir.rmtree if config.vite_cache_dir.exist?
         
     | 
| 
      
 33 
     | 
    
         
            +
              end
         
     | 
| 
      
 34 
     | 
    
         
            +
             
     | 
| 
      
 35 
     | 
    
         
            +
              # Public: Receives arguments from a rake task.
         
     | 
| 
      
 36 
     | 
    
         
            +
              def clean_from_rake(args)
         
     | 
| 
      
 37 
     | 
    
         
            +
                ensure_log_goes_to_stdout {
         
     | 
| 
      
 38 
     | 
    
         
            +
                  clean(keep_up_to: Integer(args.keep || 2), age_in_seconds: Integer(args.age || 3600))
         
     | 
| 
      
 39 
     | 
    
         
            +
                }
         
     | 
| 
       23 
40 
     | 
    
         
             
              end
         
     | 
| 
       24 
41 
     | 
    
         | 
| 
       25 
42 
     | 
    
         
             
              # Public: Cleanup old assets in the output directory.
         
     | 
| 
         @@ -33,21 +50,16 @@ class ViteRails::Commands 
     | 
|
| 
       33 
50 
     | 
    
         
             
              #   To force only 1 backup to be kept: clean(1, 0)
         
     | 
| 
       34 
51 
     | 
    
         
             
              #   To only keep files created within the last 10 minutes: clean(0, 600)
         
     | 
| 
       35 
52 
     | 
    
         
             
              def clean(keep_up_to: 2, age_in_seconds: 3600)
         
     | 
| 
       36 
     | 
    
         
            -
                return false unless  
     | 
| 
      
 53 
     | 
    
         
            +
                return false unless may_clean?
         
     | 
| 
       37 
54 
     | 
    
         | 
| 
       38 
     | 
    
         
            -
                versions 
     | 
| 
      
 55 
     | 
    
         
            +
                versions
         
     | 
| 
       39 
56 
     | 
    
         
             
                  .each_with_index
         
     | 
| 
       40 
57 
     | 
    
         
             
                  .drop_while { |(mtime, _), index|
         
     | 
| 
       41 
58 
     | 
    
         
             
                    max_age = [0, Time.now - Time.at(mtime)].max
         
     | 
| 
       42 
59 
     | 
    
         
             
                    max_age < age_in_seconds || index < keep_up_to
         
     | 
| 
       43 
60 
     | 
    
         
             
                  }
         
     | 
| 
       44 
     | 
    
         
            -
                  .each do |(_, files),  
     | 
| 
       45 
     | 
    
         
            -
                    files 
     | 
| 
       46 
     | 
    
         
            -
                      next unless File.file?(file)
         
     | 
| 
       47 
     | 
    
         
            -
             
     | 
| 
       48 
     | 
    
         
            -
                      File.delete(file)
         
     | 
| 
       49 
     | 
    
         
            -
                      logger.info("Removed #{ file }")
         
     | 
| 
       50 
     | 
    
         
            -
                    end
         
     | 
| 
      
 61 
     | 
    
         
            +
                  .each do |(_, files), _|
         
     | 
| 
      
 62 
     | 
    
         
            +
                    clean_files(files)
         
     | 
| 
       51 
63 
     | 
    
         
             
                  end
         
     | 
| 
       52 
64 
     | 
    
         
             
                true
         
     | 
| 
       53 
65 
     | 
    
         
             
              end
         
     | 
| 
         @@ -56,13 +68,42 @@ private 
     | 
|
| 
       56 
68 
     | 
    
         | 
| 
       57 
69 
     | 
    
         
             
              delegate :config, :builder, :manifest, :logger, to: :@vite_rails
         
     | 
| 
       58 
70 
     | 
    
         | 
| 
      
 71 
     | 
    
         
            +
              def may_clean?
         
     | 
| 
      
 72 
     | 
    
         
            +
                config.build_output_dir.exist? && config.manifest_path.exist?
         
     | 
| 
      
 73 
     | 
    
         
            +
              end
         
     | 
| 
      
 74 
     | 
    
         
            +
             
     | 
| 
      
 75 
     | 
    
         
            +
              def clean_files(files)
         
     | 
| 
      
 76 
     | 
    
         
            +
                files.select { |file| File.file?(file) }.each do |file|
         
     | 
| 
      
 77 
     | 
    
         
            +
                  File.delete(file)
         
     | 
| 
      
 78 
     | 
    
         
            +
                  logger.info("Removed #{ file }")
         
     | 
| 
      
 79 
     | 
    
         
            +
                end
         
     | 
| 
      
 80 
     | 
    
         
            +
              end
         
     | 
| 
      
 81 
     | 
    
         
            +
             
     | 
| 
       59 
82 
     | 
    
         
             
              def versions
         
     | 
| 
       60 
83 
     | 
    
         
             
                all_files = Dir.glob("#{ config.build_output_dir }/**/*")
         
     | 
| 
       61 
84 
     | 
    
         
             
                entries = all_files - [config.manifest_path] - current_version_files
         
     | 
| 
       62 
     | 
    
         
            -
                entries.reject { |file| File.directory?(file) } 
     | 
| 
      
 85 
     | 
    
         
            +
                entries.reject { |file| File.directory?(file) }
         
     | 
| 
      
 86 
     | 
    
         
            +
                  .group_by { |file| File.mtime(file).utc.to_i }
         
     | 
| 
      
 87 
     | 
    
         
            +
                  .sort.reverse
         
     | 
| 
       63 
88 
     | 
    
         
             
              end
         
     | 
| 
       64 
89 
     | 
    
         | 
| 
       65 
90 
     | 
    
         
             
              def current_version_files
         
     | 
| 
       66 
91 
     | 
    
         
             
                Dir.glob(manifest.refresh.values.map { |value| config.build_output_dir.join("#{ value['file'] }*") })
         
     | 
| 
       67 
92 
     | 
    
         
             
              end
         
     | 
| 
      
 93 
     | 
    
         
            +
             
     | 
| 
      
 94 
     | 
    
         
            +
              def with_node_env(env)
         
     | 
| 
      
 95 
     | 
    
         
            +
                original = ENV['NODE_ENV']
         
     | 
| 
      
 96 
     | 
    
         
            +
                ENV['NODE_ENV'] = env
         
     | 
| 
      
 97 
     | 
    
         
            +
                yield
         
     | 
| 
      
 98 
     | 
    
         
            +
              ensure
         
     | 
| 
      
 99 
     | 
    
         
            +
                ENV['NODE_ENV'] = original
         
     | 
| 
      
 100 
     | 
    
         
            +
              end
         
     | 
| 
      
 101 
     | 
    
         
            +
             
     | 
| 
      
 102 
     | 
    
         
            +
              def ensure_log_goes_to_stdout
         
     | 
| 
      
 103 
     | 
    
         
            +
                old_logger = ViteRails.logger
         
     | 
| 
      
 104 
     | 
    
         
            +
                ViteRails.logger = ActiveSupport::Logger.new(STDOUT)
         
     | 
| 
      
 105 
     | 
    
         
            +
                yield
         
     | 
| 
      
 106 
     | 
    
         
            +
              ensure
         
     | 
| 
      
 107 
     | 
    
         
            +
                ViteRails.logger = old_logger
         
     | 
| 
      
 108 
     | 
    
         
            +
              end
         
     | 
| 
       68 
109 
     | 
    
         
             
            end
         
     | 
    
        data/lib/vite_rails/config.rb
    CHANGED
    
    | 
         @@ -1,16 +1,14 @@ 
     | 
|
| 
       1 
1 
     | 
    
         
             
            # frozen_string_literal: true
         
     | 
| 
       2 
2 
     | 
    
         | 
| 
      
 3 
     | 
    
         
            +
            require 'json'
         
     | 
| 
      
 4 
     | 
    
         
            +
             
     | 
| 
       3 
5 
     | 
    
         
             
            # Public: Allows to resolve configuration sourced from `config/vite.json` and
         
     | 
| 
       4 
6 
     | 
    
         
             
            # environment variables, combining them with the default options.
         
     | 
| 
       5 
7 
     | 
    
         
             
            class ViteRails::Config
         
     | 
| 
       6 
8 
     | 
    
         
             
              delegate :as_json, :inspect, to: :@config
         
     | 
| 
       7 
9 
     | 
    
         | 
| 
       8 
     | 
    
         
            -
              def initialize( 
     | 
| 
       9 
     | 
    
         
            -
                @config =  
     | 
| 
       10 
     | 
    
         
            -
             
     | 
| 
       11 
     | 
    
         
            -
                config.each_key do |option|
         
     | 
| 
       12 
     | 
    
         
            -
                  define_singleton_method(option) { @config[option] }
         
     | 
| 
       13 
     | 
    
         
            -
                end
         
     | 
| 
      
 10 
     | 
    
         
            +
              def initialize(attrs)
         
     | 
| 
      
 11 
     | 
    
         
            +
                @config = attrs.tap { |config| coerce_values(config) }.freeze
         
     | 
| 
       14 
12 
     | 
    
         
             
              end
         
     | 
| 
       15 
13 
     | 
    
         | 
| 
       16 
14 
     | 
    
         
             
              def protocol
         
     | 
| 
         @@ -28,7 +26,26 @@ class ViteRails::Config 
     | 
|
| 
       28 
26 
     | 
    
         | 
| 
       29 
27 
     | 
    
         
             
              # Public: The directory where Vite will store the built assets.
         
     | 
| 
       30 
28 
     | 
    
         
             
              def build_output_dir
         
     | 
| 
       31 
     | 
    
         
            -
                 
     | 
| 
      
 29 
     | 
    
         
            +
                root.join(public_dir, public_output_dir)
         
     | 
| 
      
 30 
     | 
    
         
            +
              end
         
     | 
| 
      
 31 
     | 
    
         
            +
             
     | 
| 
      
 32 
     | 
    
         
            +
              # Public: The directory where the entries are located.
         
     | 
| 
      
 33 
     | 
    
         
            +
              def resolved_entrypoints_dir
         
     | 
| 
      
 34 
     | 
    
         
            +
                root.join(source_code_dir, entrypoints_dir)
         
     | 
| 
      
 35 
     | 
    
         
            +
              end
         
     | 
| 
      
 36 
     | 
    
         
            +
             
     | 
| 
      
 37 
     | 
    
         
            +
              # Internal: The directory where Vite stores its processing cache.
         
     | 
| 
      
 38 
     | 
    
         
            +
              def vite_cache_dir
         
     | 
| 
      
 39 
     | 
    
         
            +
                root.join('node_modules/.vite')
         
     | 
| 
      
 40 
     | 
    
         
            +
              end
         
     | 
| 
      
 41 
     | 
    
         
            +
             
     | 
| 
      
 42 
     | 
    
         
            +
              # Public: Sets additional environment variables for vite-plugin-ruby.
         
     | 
| 
      
 43 
     | 
    
         
            +
              def to_env
         
     | 
| 
      
 44 
     | 
    
         
            +
                CONFIGURABLE_WITH_ENV.each_with_object({}) do |option, env|
         
     | 
| 
      
 45 
     | 
    
         
            +
                  unless (value = @config[option]).nil?
         
     | 
| 
      
 46 
     | 
    
         
            +
                    env["#{ ViteRails::ENV_PREFIX }_#{ option.upcase }"] = value.to_s
         
     | 
| 
      
 47 
     | 
    
         
            +
                  end
         
     | 
| 
      
 48 
     | 
    
         
            +
                end.merge(ViteRails.env)
         
     | 
| 
       32 
49 
     | 
    
         
             
              end
         
     | 
| 
       33 
50 
     | 
    
         | 
| 
       34 
51 
     | 
    
         
             
            private
         
     | 
| 
         @@ -36,10 +53,11 @@ private 
     | 
|
| 
       36 
53 
     | 
    
         
             
              # Internal: Coerces all the configuration values, in case they were passed
         
     | 
| 
       37 
54 
     | 
    
         
             
              # as environment variables which are always strings.
         
     | 
| 
       38 
55 
     | 
    
         
             
              def coerce_values(config)
         
     | 
| 
       39 
     | 
    
         
            -
                 
     | 
| 
       40 
     | 
    
         
            -
                coerce_paths(config, 'assets_dir', 'build_cache_dir', 'config_path', 'public_dir', 'source_code_dir', 'public_output_dir', 'root')
         
     | 
| 
      
 56 
     | 
    
         
            +
                config['mode'] = config['mode'].to_s
         
     | 
| 
       41 
57 
     | 
    
         
             
                config['port'] = config['port'].to_i
         
     | 
| 
       42 
     | 
    
         
            -
                config['root']  
     | 
| 
      
 58 
     | 
    
         
            +
                config['root'] = Pathname.new(config['root'])
         
     | 
| 
      
 59 
     | 
    
         
            +
                config['build_cache_dir'] = config['root'].join(config['build_cache_dir'])
         
     | 
| 
      
 60 
     | 
    
         
            +
                coerce_booleans(config, 'auto_build', 'hide_build_console_output', 'https')
         
     | 
| 
       43 
61 
     | 
    
         
             
              end
         
     | 
| 
       44 
62 
     | 
    
         | 
| 
       45 
63 
     | 
    
         
             
              # Internal: Coerces configuration options to boolean.
         
     | 
| 
         @@ -47,58 +65,70 @@ private 
     | 
|
| 
       47 
65 
     | 
    
         
             
                names.each { |name| config[name] = [true, 'true'].include?(config[name]) }
         
     | 
| 
       48 
66 
     | 
    
         
             
              end
         
     | 
| 
       49 
67 
     | 
    
         | 
| 
       50 
     | 
    
         
            -
              # Internal: Converts configuration options to pathname.
         
     | 
| 
       51 
     | 
    
         
            -
              def coerce_paths(config, *names)
         
     | 
| 
       52 
     | 
    
         
            -
                names.each { |name| config[name] = Pathname.new(config[name]) unless config[name].nil? }
         
     | 
| 
       53 
     | 
    
         
            -
              end
         
     | 
| 
       54 
     | 
    
         
            -
             
     | 
| 
       55 
68 
     | 
    
         
             
              class << self
         
     | 
| 
       56 
69 
     | 
    
         
             
                # Public: Returns the project configuration for Vite.
         
     | 
| 
       57 
     | 
    
         
            -
                def resolve_config
         
     | 
| 
       58 
     | 
    
         
            -
                   
     | 
| 
       59 
     | 
    
         
            -
             
     | 
| 
       60 
     | 
    
         
            -
                   
     | 
| 
       61 
     | 
    
         
            -
                  new DEFAULT_CONFIG.merge(config_from_env)
         
     | 
| 
      
 70 
     | 
    
         
            +
                def resolve_config(**attrs)
         
     | 
| 
      
 71 
     | 
    
         
            +
                  config = attrs.transform_keys(&:to_s).reverse_merge(config_defaults)
         
     | 
| 
      
 72 
     | 
    
         
            +
                  file_path = File.join(config['root'], config['config_path'])
         
     | 
| 
      
 73 
     | 
    
         
            +
                  file_config = config_from_file(file_path, mode: config['mode'])
         
     | 
| 
      
 74 
     | 
    
         
            +
                  new DEFAULT_CONFIG.merge(file_config).merge(config_from_env).merge(config)
         
     | 
| 
       62 
75 
     | 
    
         
             
                end
         
     | 
| 
       63 
76 
     | 
    
         | 
| 
       64 
77 
     | 
    
         
             
              private
         
     | 
| 
       65 
78 
     | 
    
         | 
| 
      
 79 
     | 
    
         
            +
                # Internal: Default values for a Rails application.
         
     | 
| 
      
 80 
     | 
    
         
            +
                def config_defaults
         
     | 
| 
      
 81 
     | 
    
         
            +
                  {
         
     | 
| 
      
 82 
     | 
    
         
            +
                    'asset_host' => option_from_env('asset_host') || Rails.application&.config&.action_controller&.asset_host,
         
     | 
| 
      
 83 
     | 
    
         
            +
                    'config_path' => option_from_env('config_path') || DEFAULT_CONFIG.fetch('config_path'),
         
     | 
| 
      
 84 
     | 
    
         
            +
                    'mode' => option_from_env('mode') || Rails.env.to_s,
         
     | 
| 
      
 85 
     | 
    
         
            +
                    'root' => option_from_env('root') || Rails.root || Dir.pwd,
         
     | 
| 
      
 86 
     | 
    
         
            +
                  }
         
     | 
| 
      
 87 
     | 
    
         
            +
                end
         
     | 
| 
      
 88 
     | 
    
         
            +
             
     | 
| 
       66 
89 
     | 
    
         
             
                # Internal: Used to load a JSON file from the specified path.
         
     | 
| 
       67 
90 
     | 
    
         
             
                def load_json(path)
         
     | 
| 
       68 
91 
     | 
    
         
             
                  JSON.parse(File.read(File.expand_path(path))).deep_transform_keys(&:underscore)
         
     | 
| 
       69 
92 
     | 
    
         
             
                end
         
     | 
| 
       70 
93 
     | 
    
         | 
| 
       71 
94 
     | 
    
         
             
                # Internal: Retrieves a configuration option from environment variables.
         
     | 
| 
       72 
     | 
    
         
            -
                def  
     | 
| 
       73 
     | 
    
         
            -
                   
     | 
| 
      
 95 
     | 
    
         
            +
                def option_from_env(name)
         
     | 
| 
      
 96 
     | 
    
         
            +
                  ViteRails.env["#{ ViteRails::ENV_PREFIX }_#{ name.upcase }"]
         
     | 
| 
       74 
97 
     | 
    
         
             
                end
         
     | 
| 
       75 
98 
     | 
    
         | 
| 
       76 
99 
     | 
    
         
             
                # Internal: Extracts the configuration options provided as env vars.
         
     | 
| 
       77 
100 
     | 
    
         
             
                def config_from_env
         
     | 
| 
       78 
     | 
    
         
            -
                  CONFIGURABLE_WITH_ENV.each_with_object({}) do | 
     | 
| 
       79 
     | 
    
         
            -
                    if value =  
     | 
| 
       80 
     | 
    
         
            -
                      env_vars[ 
     | 
| 
      
 101 
     | 
    
         
            +
                  CONFIGURABLE_WITH_ENV.each_with_object({}) do |option, env_vars|
         
     | 
| 
      
 102 
     | 
    
         
            +
                    if value = option_from_env(option)
         
     | 
| 
      
 103 
     | 
    
         
            +
                      env_vars[option] = value
         
     | 
| 
       81 
104 
     | 
    
         
             
                    end
         
     | 
| 
       82 
     | 
    
         
            -
                  end 
     | 
| 
       83 
     | 
    
         
            -
                end
         
     | 
| 
       84 
     | 
    
         
            -
             
     | 
| 
       85 
     | 
    
         
            -
                # Internal: The mode Vite should run on.
         
     | 
| 
       86 
     | 
    
         
            -
                def vite_mode
         
     | 
| 
       87 
     | 
    
         
            -
                  config_option_from_env('mode') || Rails.env.to_s
         
     | 
| 
      
 105 
     | 
    
         
            +
                  end
         
     | 
| 
       88 
106 
     | 
    
         
             
                end
         
     | 
| 
       89 
107 
     | 
    
         | 
| 
       90 
108 
     | 
    
         
             
                # Internal: Loads the configuration options provided in a JSON file.
         
     | 
| 
       91 
     | 
    
         
            -
                def config_from_file
         
     | 
| 
       92 
     | 
    
         
            -
                  path = config_option_from_env('config_path') || DEFAULT_CONFIG.fetch('config_path')
         
     | 
| 
      
 109 
     | 
    
         
            +
                def config_from_file(path, mode:)
         
     | 
| 
       93 
110 
     | 
    
         
             
                  multi_env_config = load_json(path)
         
     | 
| 
       94 
111 
     | 
    
         
             
                  multi_env_config.fetch('all', {})
         
     | 
| 
       95 
     | 
    
         
            -
                    .merge(multi_env_config.fetch( 
     | 
| 
      
 112 
     | 
    
         
            +
                    .merge(multi_env_config.fetch(mode, {}))
         
     | 
| 
      
 113 
     | 
    
         
            +
                rescue Errno::ENOENT => error
         
     | 
| 
      
 114 
     | 
    
         
            +
                  warn "Check that your vite.json configuration file is available in the load path. #{ error.message }"
         
     | 
| 
      
 115 
     | 
    
         
            +
                  {}
         
     | 
| 
       96 
116 
     | 
    
         
             
                end
         
     | 
| 
       97 
117 
     | 
    
         
             
              end
         
     | 
| 
       98 
118 
     | 
    
         | 
| 
       99 
119 
     | 
    
         
             
              # Internal: Shared configuration with the Vite plugin for Ruby.
         
     | 
| 
       100 
120 
     | 
    
         
             
              DEFAULT_CONFIG = load_json("#{ __dir__ }/../../package/default.vite.json").freeze
         
     | 
| 
       101 
121 
     | 
    
         | 
| 
      
 122 
     | 
    
         
            +
              # Internal: Configuration options that can not be provided as env vars.
         
     | 
| 
      
 123 
     | 
    
         
            +
              NOT_CONFIGURABLE_WITH_ENV = %w[watch_additional_paths].freeze
         
     | 
| 
      
 124 
     | 
    
         
            +
             
     | 
| 
       102 
125 
     | 
    
         
             
              # Internal: Configuration options that can be provided as env vars.
         
     | 
| 
       103 
     | 
    
         
            -
              CONFIGURABLE_WITH_ENV = (DEFAULT_CONFIG.keys + [ 
     | 
| 
      
 126 
     | 
    
         
            +
              CONFIGURABLE_WITH_ENV = (DEFAULT_CONFIG.keys + %w[mode root] - NOT_CONFIGURABLE_WITH_ENV).freeze
         
     | 
| 
      
 127 
     | 
    
         
            +
             
     | 
| 
      
 128 
     | 
    
         
            +
            public
         
     | 
| 
      
 129 
     | 
    
         
            +
             
     | 
| 
      
 130 
     | 
    
         
            +
              # Define getters for the configuration options.
         
     | 
| 
      
 131 
     | 
    
         
            +
              (CONFIGURABLE_WITH_ENV + NOT_CONFIGURABLE_WITH_ENV).each do |option|
         
     | 
| 
      
 132 
     | 
    
         
            +
                define_method(option) { @config[option] }
         
     | 
| 
      
 133 
     | 
    
         
            +
              end
         
     | 
| 
       104 
134 
     | 
    
         
             
            end
         
     | 
| 
         @@ -14,18 +14,8 @@ class ViteRails::DevServerProxy < Rack::Proxy 
     | 
|
| 
       14 
14 
     | 
    
         | 
| 
       15 
15 
     | 
    
         
             
              # Rack: Intercept asset requests and send them to the Vite server.
         
     | 
| 
       16 
16 
     | 
    
         
             
              def perform_request(env)
         
     | 
| 
       17 
     | 
    
         
            -
                if vite_should_handle?(env 
     | 
| 
       18 
     | 
    
         
            -
                  env 
     | 
| 
       19 
     | 
    
         
            -
                    .sub(vite_asset_url_prefix, '/')
         
     | 
| 
       20 
     | 
    
         
            -
                    .sub('.ts.js', '.ts') # Patch: Rails helpers always append the extension.
         
     | 
| 
       21 
     | 
    
         
            -
                  env['PATH_INFO'], env['QUERY_STRING'] = env['REQUEST_URI'].split('?')
         
     | 
| 
       22 
     | 
    
         
            -
             
     | 
| 
       23 
     | 
    
         
            -
                  env['HTTP_HOST'] = env['HTTP_X_FORWARDED_HOST'] = config.host
         
     | 
| 
       24 
     | 
    
         
            -
                  env['HTTP_X_FORWARDED_SERVER'] = config.host_with_port
         
     | 
| 
       25 
     | 
    
         
            -
                  env['HTTP_PORT'] = env['HTTP_X_FORWARDED_PORT'] = config.port.to_s
         
     | 
| 
       26 
     | 
    
         
            -
                  env['HTTP_X_FORWARDED_PROTO'] = env['HTTP_X_FORWARDED_SCHEME'] = config.protocol
         
     | 
| 
       27 
     | 
    
         
            -
                  env['HTTPS'] = env['HTTP_X_FORWARDED_SSL'] = 'off' unless config.https
         
     | 
| 
       28 
     | 
    
         
            -
                  env['SCRIPT_NAME'] = ''
         
     | 
| 
      
 17 
     | 
    
         
            +
                if vite_should_handle?(env) && dev_server_running?
         
     | 
| 
      
 18 
     | 
    
         
            +
                  forward_to_vite_dev_server(env)
         
     | 
| 
       29 
19 
     | 
    
         
             
                  super(env)
         
     | 
| 
       30 
20 
     | 
    
         
             
                else
         
     | 
| 
       31 
21 
     | 
    
         
             
                  @app.call(env)
         
     | 
| 
         @@ -34,13 +24,31 @@ class ViteRails::DevServerProxy < Rack::Proxy 
     | 
|
| 
       34 
24 
     | 
    
         | 
| 
       35 
25 
     | 
    
         
             
            private
         
     | 
| 
       36 
26 
     | 
    
         | 
| 
       37 
     | 
    
         
            -
              delegate :config, : 
     | 
| 
      
 27 
     | 
    
         
            +
              delegate :config, :dev_server_running?, to: :@vite_rails
         
     | 
| 
       38 
28 
     | 
    
         | 
| 
       39 
     | 
    
         
            -
              def  
     | 
| 
       40 
     | 
    
         
            -
                 
     | 
| 
       41 
     | 
    
         
            -
             
     | 
| 
       42 
     | 
    
         
            -
                 
     | 
| 
       43 
     | 
    
         
            -
             
     | 
| 
      
 29 
     | 
    
         
            +
              def rewrite_uri_for_vite(env)
         
     | 
| 
      
 30 
     | 
    
         
            +
                uri = env.fetch('REQUEST_URI') { [env['PATH_INFO'], env['QUERY_STRING']].reject(&:blank?).join('?') }
         
     | 
| 
      
 31 
     | 
    
         
            +
                  .sub(vite_asset_url_prefix, '/')
         
     | 
| 
      
 32 
     | 
    
         
            +
                env['PATH_INFO'], env['QUERY_STRING'] = (env['REQUEST_URI'] = uri).split('?')
         
     | 
| 
      
 33 
     | 
    
         
            +
              end
         
     | 
| 
      
 34 
     | 
    
         
            +
             
     | 
| 
      
 35 
     | 
    
         
            +
              def forward_to_vite_dev_server(env)
         
     | 
| 
      
 36 
     | 
    
         
            +
                rewrite_uri_for_vite(env)
         
     | 
| 
      
 37 
     | 
    
         
            +
                env['HTTP_HOST'] = env['HTTP_X_FORWARDED_HOST'] = config.host
         
     | 
| 
      
 38 
     | 
    
         
            +
                env['HTTP_X_FORWARDED_SERVER'] = config.host_with_port
         
     | 
| 
      
 39 
     | 
    
         
            +
                env['HTTP_PORT'] = env['HTTP_X_FORWARDED_PORT'] = config.port.to_s
         
     | 
| 
      
 40 
     | 
    
         
            +
                env['HTTP_X_FORWARDED_PROTO'] = env['HTTP_X_FORWARDED_SCHEME'] = config.protocol
         
     | 
| 
      
 41 
     | 
    
         
            +
                env['HTTPS'] = env['HTTP_X_FORWARDED_SSL'] = 'off' unless config.https
         
     | 
| 
      
 42 
     | 
    
         
            +
                env['SCRIPT_NAME'] = ''
         
     | 
| 
      
 43 
     | 
    
         
            +
              end
         
     | 
| 
      
 44 
     | 
    
         
            +
             
     | 
| 
      
 45 
     | 
    
         
            +
              def vite_should_handle?(env)
         
     | 
| 
      
 46 
     | 
    
         
            +
                path, query, referer = env['PATH_INFO'], env['QUERY_STRING'], env['HTTP_REFERER']
         
     | 
| 
      
 47 
     | 
    
         
            +
                return true if path.start_with?(vite_asset_url_prefix) # Vite asset
         
     | 
| 
      
 48 
     | 
    
         
            +
                return true if path.start_with?(VITE_DEPENDENCY_PREFIX) # Packages and imports
         
     | 
| 
      
 49 
     | 
    
         
            +
                return true if query&.start_with?('t=') # Hot Reload for a stylesheet
         
     | 
| 
      
 50 
     | 
    
         
            +
                return true if query&.start_with?('import&') # Hot Reload for an imported entrypoint
         
     | 
| 
      
 51 
     | 
    
         
            +
                return true if referer && URI.parse(referer).path.start_with?(vite_asset_url_prefix) # Entry imported from another entry.
         
     | 
| 
       44 
52 
     | 
    
         
             
              end
         
     | 
| 
       45 
53 
     | 
    
         | 
| 
       46 
54 
     | 
    
         
             
              def vite_asset_url_prefix
         
     | 
    
        data/lib/vite_rails/helper.rb
    CHANGED
    
    | 
         @@ -2,19 +2,26 @@ 
     | 
|
| 
       2 
2 
     | 
    
         | 
| 
       3 
3 
     | 
    
         
             
            # Public: Allows to render HTML tags for scripts and styles processed by Vite.
         
     | 
| 
       4 
4 
     | 
    
         
             
            module ViteRails::Helper
         
     | 
| 
       5 
     | 
    
         
            -
              DEFAULT_VITE_SKIP_PRELOAD_TAGS = Rails 
     | 
| 
      
 5 
     | 
    
         
            +
              DEFAULT_VITE_SKIP_PRELOAD_TAGS = Rails.gem_version < Gem::Version.new('5.2.0')
         
     | 
| 
       6 
6 
     | 
    
         | 
| 
       7 
7 
     | 
    
         
             
              # Public: Returns the current Vite Rails instance.
         
     | 
| 
       8 
8 
     | 
    
         
             
              def current_vite_instance
         
     | 
| 
       9 
9 
     | 
    
         
             
                ViteRails.instance
         
     | 
| 
       10 
10 
     | 
    
         
             
              end
         
     | 
| 
       11 
11 
     | 
    
         | 
| 
       12 
     | 
    
         
            -
              # Public:  
     | 
| 
      
 12 
     | 
    
         
            +
              # Public: Renders a script tag for vite/client to enable HMR in development.
         
     | 
| 
      
 13 
     | 
    
         
            +
              def vite_client_tag
         
     | 
| 
      
 14 
     | 
    
         
            +
                return unless current_vite_instance.dev_server_running?
         
     | 
| 
      
 15 
     | 
    
         
            +
             
     | 
| 
      
 16 
     | 
    
         
            +
                content_tag('script', '', src: current_vite_instance.manifest.prefix_vite_asset('@vite/client'), type: 'module')
         
     | 
| 
      
 17 
     | 
    
         
            +
              end
         
     | 
| 
      
 18 
     | 
    
         
            +
             
     | 
| 
      
 19 
     | 
    
         
            +
              # Public: Resolves the path for the specified Vite asset.
         
     | 
| 
       13 
20 
     | 
    
         
             
              #
         
     | 
| 
       14 
21 
     | 
    
         
             
              # Example:
         
     | 
| 
       15 
22 
     | 
    
         
             
              #   <%= vite_asset_path 'calendar.css' %> # => "/vite/assets/calendar-1016838bab065ae1e122.css"
         
     | 
| 
       16 
23 
     | 
    
         
             
              def vite_asset_path(name, **options)
         
     | 
| 
       17 
     | 
    
         
            -
                current_vite_instance.manifest.lookup!(name, **options).fetch('file')
         
     | 
| 
      
 24 
     | 
    
         
            +
                path_to_asset current_vite_instance.manifest.lookup!(name, **options).fetch('file')
         
     | 
| 
       18 
25 
     | 
    
         
             
              end
         
     | 
| 
       19 
26 
     | 
    
         | 
| 
       20 
27 
     | 
    
         
             
              # Public: Renders a <script> tag for the specified Vite entrypoints.
         
     | 
| 
         @@ -26,15 +33,17 @@ module ViteRails::Helper 
     | 
|
| 
       26 
33 
     | 
    
         
             
                                      crossorigin: 'anonymous',
         
     | 
| 
       27 
34 
     | 
    
         
             
                                      **options)
         
     | 
| 
       28 
35 
     | 
    
         
             
                js_entries = names.map { |name| current_vite_instance.manifest.lookup!(name, type: asset_type) }
         
     | 
| 
       29 
     | 
    
         
            -
                js_tags = javascript_include_tag(*js_entries.map { |entry| entry['file'] },  
     | 
| 
      
 36 
     | 
    
         
            +
                js_tags = javascript_include_tag(*js_entries.map { |entry| entry['file'] }, crossorigin: crossorigin, type: type, **options)
         
     | 
| 
       30 
37 
     | 
    
         | 
| 
       31 
     | 
    
         
            -
                unless skip_preload_tags ||  
     | 
| 
      
 38 
     | 
    
         
            +
                unless skip_preload_tags || current_vite_instance.dev_server_running?
         
     | 
| 
       32 
39 
     | 
    
         
             
                  preload_paths = js_entries.flat_map { |entry| entry['imports'] }.compact.uniq
         
     | 
| 
       33 
40 
     | 
    
         
             
                  preload_tags = preload_paths.map { |path| preload_link_tag(path, crossorigin: crossorigin) }
         
     | 
| 
       34 
41 
     | 
    
         
             
                end
         
     | 
| 
       35 
42 
     | 
    
         | 
| 
       36 
     | 
    
         
            -
                unless skip_style_tags ||  
     | 
| 
       37 
     | 
    
         
            -
                  style_paths = names.map { |name| 
     | 
| 
      
 43 
     | 
    
         
            +
                unless skip_style_tags || current_vite_instance.dev_server_running?
         
     | 
| 
      
 44 
     | 
    
         
            +
                  style_paths = names.map { |name|
         
     | 
| 
      
 45 
     | 
    
         
            +
                    current_vite_instance.manifest.lookup(name.delete_suffix('.js'), type: :stylesheet)&.fetch('file')
         
     | 
| 
      
 46 
     | 
    
         
            +
                  }.compact
         
     | 
| 
       38 
47 
     | 
    
         
             
                  style_tags = stylesheet_link_tag(*style_paths)
         
     | 
| 
       39 
48 
     | 
    
         
             
                end
         
     | 
| 
       40 
49 
     | 
    
         | 
| 
         @@ -46,7 +55,7 @@ module ViteRails::Helper 
     | 
|
| 
       46 
55 
     | 
    
         
             
              # NOTE: Because TypeScript is not a valid target in browsers, we only specify
         
     | 
| 
       47 
56 
     | 
    
         
             
              # the ts file when running the Vite development server.
         
     | 
| 
       48 
57 
     | 
    
         
             
              def vite_typescript_tag(*names, **options)
         
     | 
| 
       49 
     | 
    
         
            -
                vite_javascript_tag(*names, asset_type: :typescript, **options)
         
     | 
| 
      
 58 
     | 
    
         
            +
                vite_javascript_tag(*names, asset_type: :typescript, extname: false, **options)
         
     | 
| 
       50 
59 
     | 
    
         
             
              end
         
     | 
| 
       51 
60 
     | 
    
         | 
| 
       52 
61 
     | 
    
         
             
              # Public: Renders a <link> tag for the specified Vite entrypoints.
         
     | 
    
        data/lib/vite_rails/manifest.rb
    CHANGED
    
    | 
         @@ -31,7 +31,7 @@ class ViteRails::Manifest 
     | 
|
| 
       31 
31 
     | 
    
         
             
              # Example:
         
     | 
| 
       32 
32 
     | 
    
         
             
              #   ViteRails.manifest.lookup('calendar.js')
         
     | 
| 
       33 
33 
     | 
    
         
             
              #   # { "file" => "/vite/assets/calendar-1016838bab065ae1e122.js", "imports" => [] }
         
     | 
| 
       34 
     | 
    
         
            -
              def lookup(name, type:)
         
     | 
| 
      
 34 
     | 
    
         
            +
              def lookup(name, type: nil)
         
     | 
| 
       35 
35 
     | 
    
         
             
                build if should_build?
         
     | 
| 
       36 
36 
     | 
    
         | 
| 
       37 
37 
     | 
    
         
             
                find_manifest_entry(with_file_extension(name, type))
         
     | 
| 
         @@ -42,6 +42,11 @@ class ViteRails::Manifest 
     | 
|
| 
       42 
42 
     | 
    
         
             
                @manifest = load_manifest
         
     | 
| 
       43 
43 
     | 
    
         
             
              end
         
     | 
| 
       44 
44 
     | 
    
         | 
| 
      
 45 
     | 
    
         
            +
              # Public: Scopes an asset to the output folder in public, as a path.
         
     | 
| 
      
 46 
     | 
    
         
            +
              def prefix_vite_asset(path)
         
     | 
| 
      
 47 
     | 
    
         
            +
                File.join("/#{ config.public_output_dir }", path)
         
     | 
| 
      
 48 
     | 
    
         
            +
              end
         
     | 
| 
      
 49 
     | 
    
         
            +
             
     | 
| 
       45 
50 
     | 
    
         
             
            private
         
     | 
| 
       46 
51 
     | 
    
         | 
| 
       47 
52 
     | 
    
         
             
              delegate :config, :builder, :dev_server_running?, to: :@vite_rails
         
     | 
| 
         @@ -55,7 +60,7 @@ private 
     | 
|
| 
       55 
60 
     | 
    
         
             
              # Internal: Finds the specified entry in the manifest.
         
     | 
| 
       56 
61 
     | 
    
         
             
              def find_manifest_entry(name)
         
     | 
| 
       57 
62 
     | 
    
         
             
                if dev_server_running?
         
     | 
| 
       58 
     | 
    
         
            -
                  { 'file' =>  
     | 
| 
      
 63 
     | 
    
         
            +
                  { 'file' => prefix_vite_asset(name.to_s) }
         
     | 
| 
       59 
64 
     | 
    
         
             
                else
         
     | 
| 
       60 
65 
     | 
    
         
             
                  manifest[name.to_s]
         
     | 
| 
       61 
66 
     | 
    
         
             
                end
         
     | 
| 
         @@ -80,8 +85,8 @@ private 
     | 
|
| 
       80 
85 
     | 
    
         
             
              def load_manifest
         
     | 
| 
       81 
86 
     | 
    
         
             
                if config.manifest_path.exist?
         
     | 
| 
       82 
87 
     | 
    
         
             
                  JSON.parse(config.manifest_path.read).each do |_, entry|
         
     | 
| 
       83 
     | 
    
         
            -
                    entry['file'] =  
     | 
| 
       84 
     | 
    
         
            -
                    entry['imports'] = entry['imports']&.map { |path|  
     | 
| 
      
 88 
     | 
    
         
            +
                    entry['file'] = prefix_vite_asset(entry['file'])
         
     | 
| 
      
 89 
     | 
    
         
            +
                    entry['imports'] = entry['imports']&.map { |path| prefix_vite_asset(path) }
         
     | 
| 
       85 
90 
     | 
    
         
             
                  end
         
     | 
| 
       86 
91 
     | 
    
         
             
                else
         
     | 
| 
       87 
92 
     | 
    
         
             
                  {}
         
     | 
| 
         @@ -92,12 +97,8 @@ private 
     | 
|
| 
       92 
97 
     | 
    
         
             
              def with_file_extension(name, entry_type)
         
     | 
| 
       93 
98 
     | 
    
         
             
                return name unless File.extname(name.to_s).empty?
         
     | 
| 
       94 
99 
     | 
    
         | 
| 
       95 
     | 
    
         
            -
                 
     | 
| 
       96 
     | 
    
         
            -
             
     | 
| 
       97 
     | 
    
         
            -
             
     | 
| 
       98 
     | 
    
         
            -
              # Internal: Scopes the paths in the manifest to the output folder in public.
         
     | 
| 
       99 
     | 
    
         
            -
              def within_public_output_dir(path)
         
     | 
| 
       100 
     | 
    
         
            -
                "/#{ config.public_output_dir.join(path) }"
         
     | 
| 
      
 100 
     | 
    
         
            +
                extension = extension_for_type(entry_type)
         
     | 
| 
      
 101 
     | 
    
         
            +
                extension ? "#{ name }.#{ extension }" : name
         
     | 
| 
       101 
102 
     | 
    
         
             
              end
         
     | 
| 
       102 
103 
     | 
    
         | 
| 
       103 
104 
     | 
    
         
             
              # Internal: Allows to receive :javascript and :stylesheet as :type in helpers.
         
     | 
| 
         @@ -106,7 +107,7 @@ private 
     | 
|
| 
       106 
107 
     | 
    
         
             
                when :javascript then 'js'
         
     | 
| 
       107 
108 
     | 
    
         
             
                when :stylesheet then 'css'
         
     | 
| 
       108 
109 
     | 
    
         
             
                when :typescript then dev_server_running? ? 'ts' : 'js'
         
     | 
| 
       109 
     | 
    
         
            -
                else entry_type 
     | 
| 
      
 110 
     | 
    
         
            +
                else entry_type
         
     | 
| 
       110 
111 
     | 
    
         
             
                end
         
     | 
| 
       111 
112 
     | 
    
         
             
              end
         
     | 
| 
       112 
113 
     | 
    
         | 
| 
         @@ -129,9 +130,10 @@ private 
     | 
|
| 
       129 
130 
     | 
    
         
             
                [
         
     | 
| 
       130 
131 
     | 
    
         
             
                  (dev_server_running? && 'Vite has not yet re-built your latest changes.'),
         
     | 
| 
       131 
132 
     | 
    
         
             
                  (local && !dev_server_running? && "\"autoBuild\": false in your #{ config.mode } configuration."),
         
     | 
| 
      
 133 
     | 
    
         
            +
                  (local && !dev_server_running? && 'The Vite development server has crashed or is no longer available.'),
         
     | 
| 
       132 
134 
     | 
    
         
             
                  'You have misconfigured config/vite.json file.',
         
     | 
| 
       133 
135 
     | 
    
         
             
                  (!local && 'Assets have not been precompiled'),
         
     | 
| 
       134 
     | 
    
         
            -
                ]. 
     | 
| 
      
 136 
     | 
    
         
            +
                ].compact
         
     | 
| 
       135 
137 
     | 
    
         
             
              rescue StandardError
         
     | 
| 
       136 
138 
     | 
    
         
             
                []
         
     | 
| 
       137 
139 
     | 
    
         
             
              end
         
     |