vite_rails 1.0.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +7 -0
- data/CHANGELOG.md +3 -0
- data/CONTRIBUTING.md +34 -0
- data/LICENSE.txt +21 -0
- data/README.md +64 -0
- data/lib/install/binstubs.rb +6 -0
- data/lib/install/template.rb +62 -0
- data/lib/vite_rails.rb +91 -0
- data/lib/vite_rails/builder.rb +113 -0
- data/lib/vite_rails/commands.rb +68 -0
- data/lib/vite_rails/config.rb +106 -0
- data/lib/vite_rails/dev_server.rb +23 -0
- data/lib/vite_rails/dev_server_proxy.rb +47 -0
- data/lib/vite_rails/engine.rb +40 -0
- data/lib/vite_rails/helper.rb +41 -0
- data/lib/vite_rails/manifest.rb +134 -0
- data/lib/vite_rails/runner.rb +56 -0
- data/lib/vite_rails/version.rb +5 -0
- data/package.json +28 -0
- data/package/default.vite.json +15 -0
- data/test/builder_test.rb +72 -0
- data/test/command_test.rb +35 -0
- data/test/configuration_test.rb +80 -0
- data/test/dev_server_runner_test.rb +83 -0
- data/test/dev_server_test.rb +39 -0
- data/test/engine_rake_tasks_test.rb +42 -0
- data/test/helper_test.rb +138 -0
- data/test/manifest_test.rb +75 -0
- data/test/mode_test.rb +21 -0
- data/test/mounted_app/Rakefile +6 -0
- data/test/mounted_app/test/dummy/Rakefile +5 -0
- data/test/mounted_app/test/dummy/bin/rails +5 -0
- data/test/mounted_app/test/dummy/bin/rake +5 -0
- data/test/mounted_app/test/dummy/config.ru +7 -0
- data/test/mounted_app/test/dummy/config/application.rb +12 -0
- data/test/mounted_app/test/dummy/config/environment.rb +5 -0
- data/test/mounted_app/test/dummy/config/vite.json +20 -0
- data/test/mounted_app/test/dummy/package.json +7 -0
- data/test/rake_tasks_test.rb +74 -0
- data/test/test_app/Rakefile +5 -0
- data/test/test_app/app/javascript/entrypoints/application.js +10 -0
- data/test/test_app/app/javascript/entrypoints/multi_entry.css +4 -0
- data/test/test_app/app/javascript/entrypoints/multi_entry.js +4 -0
- data/test/test_app/bin/vite +17 -0
- data/test/test_app/config.ru +7 -0
- data/test/test_app/config/application.rb +13 -0
- data/test/test_app/config/environment.rb +6 -0
- data/test/test_app/config/vite.json +20 -0
- data/test/test_app/config/vite_public_root.yml +20 -0
- data/test/test_app/package.json +13 -0
- data/test/test_app/public/vite/manifest.json +36 -0
- data/test/test_app/some.config.js +0 -0
- data/test/test_app/yarn.lock +11 -0
- data/test/test_helper.rb +34 -0
- data/test/vite_runner_test.rb +59 -0
- data/test/webpacker_test.rb +15 -0
- metadata +234 -0
checksums.yaml
ADDED
@@ -0,0 +1,7 @@
|
|
1
|
+
---
|
2
|
+
SHA256:
|
3
|
+
metadata.gz: ad566a46292f652f6533c40901952359b27afdc98224af3f67bd4414a906a951
|
4
|
+
data.tar.gz: f3a035a74e1f3d092b99d46a25dfd32cd2d6cb50071f7dc971473f0958a76893
|
5
|
+
SHA512:
|
6
|
+
metadata.gz: 77d1dd2b22130bdee130dc814e4453d1c63ad6823c3cc0cd9e6a1f8a17c3f02adb31f8924e2f97d686dc707bbd2b56b327948e6e12f5bcdf2c47132f62293891
|
7
|
+
data.tar.gz: 635ea8d95ed3e8cd3dc0e2f44fd962fdf3920578bdeb51f6cabf2be251035555371d20adb1ac9ab5a6e81d6620def27a0b646fc2f3bd8f769869d328c1ef5c40
|
data/CHANGELOG.md
ADDED
data/CONTRIBUTING.md
ADDED
@@ -0,0 +1,34 @@
|
|
1
|
+
## Setting Up a Development Environment
|
2
|
+
|
3
|
+
1. Install [Yarn](https://yarnpkg.com/)
|
4
|
+
|
5
|
+
2. Run the following commands to set up the development environment.
|
6
|
+
|
7
|
+
```
|
8
|
+
bundle install
|
9
|
+
yarn
|
10
|
+
```
|
11
|
+
|
12
|
+
## Making sure your changes pass all tests
|
13
|
+
There are a number of automated checks which run on GitHub Actions when a pull request is created.
|
14
|
+
You can run those checks on your own locally to make sure that your changes would not break the CI build.
|
15
|
+
|
16
|
+
### 1. Check the code for JavaScript style violations
|
17
|
+
```
|
18
|
+
yarn lint
|
19
|
+
```
|
20
|
+
|
21
|
+
### 2. Check the code for Ruby style violations
|
22
|
+
```
|
23
|
+
bundle exec rubocop
|
24
|
+
```
|
25
|
+
|
26
|
+
### 3. Run the JavaScript test suite
|
27
|
+
```
|
28
|
+
yarn test
|
29
|
+
```
|
30
|
+
|
31
|
+
### 4. Run the Ruby test suite
|
32
|
+
```
|
33
|
+
bundle exec rake test
|
34
|
+
```
|
data/LICENSE.txt
ADDED
@@ -0,0 +1,21 @@
|
|
1
|
+
The MIT License (MIT)
|
2
|
+
|
3
|
+
Copyright (c) 2020 Maximo Mussini
|
4
|
+
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
7
|
+
in the Software without restriction, including without limitation the rights
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
10
|
+
furnished to do so, subject to the following conditions:
|
11
|
+
|
12
|
+
The above copyright notice and this permission notice shall be included in
|
13
|
+
all copies or substantial portions of the Software.
|
14
|
+
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
21
|
+
THE SOFTWARE.
|
data/README.md
ADDED
@@ -0,0 +1,64 @@
|
|
1
|
+
<h1 align="center">
|
2
|
+
Vite ⚡️ Rails
|
3
|
+
<p align="center">
|
4
|
+
<!-- <a href="https://github.com/ElMassimo/vite_rails/actions">
|
5
|
+
<img alt="Build Status" src="https://github.com/ElMassimo/vite_rails/workflows/build/badge.svg"/>
|
6
|
+
</a> -->
|
7
|
+
<!-- <a href="https://codeclimate.com/github/ElMassimo/vite_rails">
|
8
|
+
<img alt="Maintainability" src="https://codeclimate.com/github/ElMassimo/vite_rails/badges/gpa.svg"/>
|
9
|
+
</a>
|
10
|
+
<a href="https://codeclimate.com/github/ElMassimo/vite_rails">
|
11
|
+
<img alt="Test Coverage" src="https://codeclimate.com/github/ElMassimo/vite_rails/badges/coverage.svg"/>
|
12
|
+
</a> -->
|
13
|
+
<a href="https://rubygems.org/gems/vite_rails">
|
14
|
+
<img alt="Gem Version" src="https://img.shields.io/gem/v/vite_rails.svg?colorB=e9573f"/>
|
15
|
+
</a>
|
16
|
+
<a href="https://github.com/ElMassimo/vite_rails/blob/master/LICENSE.txt">
|
17
|
+
<img alt="License" src="https://img.shields.io/badge/license-MIT-428F7E.svg"/>
|
18
|
+
</a>
|
19
|
+
</p>
|
20
|
+
</h1>
|
21
|
+
|
22
|
+
[vite_rails]: https://github.com/ElMassimo/vite_rails
|
23
|
+
[webpacker]: https://github.com/rails/webpacker
|
24
|
+
[vite]: http://vitejs.dev/
|
25
|
+
|
26
|
+
[__Vite Rails__][vite_rails] allows you to use [Vite] to power the frontend.
|
27
|
+
|
28
|
+
[Vite] is to frontend tooling as Ruby to programming, pure joy! 😍
|
29
|
+
|
30
|
+
## Features ⚡️
|
31
|
+
|
32
|
+
- 🤖 Automatic Entrypoint Detection
|
33
|
+
- ⚡️ Hot Reload
|
34
|
+
- ⚙️ Rake Tasks
|
35
|
+
- 🪝 Hooks to <kbd>assets:precompile</kbd> and friends
|
36
|
+
|
37
|
+
## Documentation 📖
|
38
|
+
|
39
|
+
Coming Soon!
|
40
|
+
|
41
|
+
## Installation 💿
|
42
|
+
|
43
|
+
Add this line to your application's Gemfile:
|
44
|
+
|
45
|
+
```ruby
|
46
|
+
gem 'vite_rails'
|
47
|
+
```
|
48
|
+
|
49
|
+
Then, run:
|
50
|
+
|
51
|
+
```bash
|
52
|
+
bundle install
|
53
|
+
bin/rake vite:install
|
54
|
+
```
|
55
|
+
|
56
|
+
This will generate configuration files and a sample setup.
|
57
|
+
|
58
|
+
## Inspiration 💡
|
59
|
+
|
60
|
+
- [webpacker]
|
61
|
+
|
62
|
+
## License
|
63
|
+
|
64
|
+
The gem is available as open source under the terms of the [MIT License](https://opensource.org/licenses/MIT).
|
@@ -0,0 +1,62 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
# Install ViteRails
|
4
|
+
copy_file "#{ __dir__ }/config/vite.json", ViteRails.config.config_path
|
5
|
+
|
6
|
+
if Dir.exist?(ViteRails.config.source_code_dir)
|
7
|
+
say 'The JavaScript app source directory already exists. Move it and try again to see a basic setup.'
|
8
|
+
else
|
9
|
+
say 'Creating JavaScript app source directory'
|
10
|
+
directory "#{ __dir__ }/javascript", ViteRails.config.source_code_dir
|
11
|
+
end
|
12
|
+
|
13
|
+
apply "#{ __dir__ }/binstubs.rb"
|
14
|
+
|
15
|
+
git_ignore_path = Rails.root.join('.gitignore')
|
16
|
+
if git_ignore_path.exist?
|
17
|
+
append_to_file(git_ignore_path) {
|
18
|
+
<<~GITIGNORE
|
19
|
+
|
20
|
+
# Vite on Rails
|
21
|
+
/public/vite
|
22
|
+
/public/vite-dev
|
23
|
+
/public/vite-test
|
24
|
+
node_modules
|
25
|
+
*.local
|
26
|
+
.DS_Store
|
27
|
+
GITIGNORE
|
28
|
+
}
|
29
|
+
end
|
30
|
+
|
31
|
+
install = if Rails.root.join('yarn.lock').exist?
|
32
|
+
'yarn add'
|
33
|
+
elsif Rails.root.join('pnpm-lock.yaml').exist?
|
34
|
+
'pnpm install'
|
35
|
+
else
|
36
|
+
'npm install'
|
37
|
+
end
|
38
|
+
|
39
|
+
Dir.chdir(Rails.root) do
|
40
|
+
say 'Installing JavaScript dependencies for Vite Rails'
|
41
|
+
package_json = File.read("#{ __dir__ }/../../package.json")
|
42
|
+
|
43
|
+
vite_version = package_json.match(/"vite": "(.*)"/)[1]
|
44
|
+
plugin_version = package_json.match(/"vite-plugin-ruby": "(.*)"/)[1]
|
45
|
+
|
46
|
+
say 'Installing vite as direct dependencies'
|
47
|
+
run "#{ install } vite@#{ vite_version } vite-plugin-ruby@#{ plugin_version }"
|
48
|
+
end
|
49
|
+
|
50
|
+
if Rails::VERSION::MAJOR == 5 && Rails::VERSION::MINOR > 1
|
51
|
+
src = begin
|
52
|
+
"#{ ViteRails.config.protocol }://#{ ViteRails.config.host_with_port }"
|
53
|
+
rescue StandardError
|
54
|
+
'http://localhost:3036'
|
55
|
+
end
|
56
|
+
say 'You need to allow vite-dev-server host as allowed origin for connect-src.', :yellow
|
57
|
+
say 'This can be done in Rails 5.2+ for development environment in the CSP initializer', :yellow
|
58
|
+
say 'config/initializers/content_security_policy.rb with a snippet like this:', :yellow
|
59
|
+
say %(policy.connect_src :self, :https, "http://#{ src }", "ws://#{ src }" if Rails.env.development?), :yellow
|
60
|
+
end
|
61
|
+
|
62
|
+
say 'ViteRails successfully installed 🎉 🍰', :green
|
data/lib/vite_rails.rb
ADDED
@@ -0,0 +1,91 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require 'active_support'
|
4
|
+
require 'active_support/core_ext/class/attribute_accessors'
|
5
|
+
|
6
|
+
require 'zeitwerk'
|
7
|
+
loader = Zeitwerk::Loader.for_gem
|
8
|
+
loader.ignore("#{ __dir__ }/install")
|
9
|
+
loader.ignore("#{ __dir__ }/tasks")
|
10
|
+
loader.setup
|
11
|
+
|
12
|
+
class ViteRails
|
13
|
+
# Internal: Prefix used for environment variables that modify the configuration.
|
14
|
+
ENV_PREFIX = 'VITE_RUBY'
|
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
|
+
class << self
|
25
|
+
delegate :config, :builder, :manifest, :commands, :dev_server, to: :instance
|
26
|
+
delegate :mode, to: :config
|
27
|
+
delegate :bootstrap, :clean, :clobber, :build, to: :commands
|
28
|
+
|
29
|
+
attr_writer :instance
|
30
|
+
|
31
|
+
def instance
|
32
|
+
@instance ||= ViteRails.new
|
33
|
+
end
|
34
|
+
|
35
|
+
def run(args)
|
36
|
+
$stdout.sync = true
|
37
|
+
ViteRails::Runner.new(args).run
|
38
|
+
end
|
39
|
+
|
40
|
+
# Public: The proxy for assets should only run in development mode.
|
41
|
+
def run_proxy?
|
42
|
+
config.mode == 'development'
|
43
|
+
rescue StandardError => error
|
44
|
+
logger.error("Failed to check mode for Vite: #{ error.message }")
|
45
|
+
false
|
46
|
+
end
|
47
|
+
|
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
|
54
|
+
end
|
55
|
+
|
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
|
63
|
+
end
|
64
|
+
|
65
|
+
# Public: Current instance configuration for Vite.
|
66
|
+
def config
|
67
|
+
@config ||= ViteRails::Config.resolve_config
|
68
|
+
end
|
69
|
+
|
70
|
+
# Public: Keeps track of watched files and triggers builds as needed.
|
71
|
+
def builder
|
72
|
+
@builder ||= ViteRails::Builder.new(self)
|
73
|
+
end
|
74
|
+
|
75
|
+
# Public: Allows to check if the Vite development server is running.
|
76
|
+
def dev_server
|
77
|
+
@dev_server ||= ViteRails::DevServer.new(config)
|
78
|
+
end
|
79
|
+
|
80
|
+
# Public: Enables looking up assets managed by Vite using name and type.
|
81
|
+
def manifest
|
82
|
+
@manifest ||= ViteRails::Manifest.new(self)
|
83
|
+
end
|
84
|
+
|
85
|
+
# Internal: Helper to run commands related with Vite.
|
86
|
+
def commands
|
87
|
+
@commands ||= ViteRails::Commands.new(self)
|
88
|
+
end
|
89
|
+
end
|
90
|
+
|
91
|
+
ViteRails::Engine if defined?(Rails)
|
@@ -0,0 +1,113 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require 'open3'
|
4
|
+
require 'digest/sha1'
|
5
|
+
|
6
|
+
# Public: Keeps track of watched files and triggers builds as needed.
|
7
|
+
class ViteRails::Builder
|
8
|
+
def initialize(vite_rails)
|
9
|
+
@vite_rails = vite_rails
|
10
|
+
end
|
11
|
+
|
12
|
+
# Public: Checks if the watched files have changed since the last compilation,
|
13
|
+
# and triggers a Vite build if any files have changed.
|
14
|
+
def build
|
15
|
+
if stale?
|
16
|
+
build_with_vite.tap { record_files_digest }
|
17
|
+
else
|
18
|
+
logger.debug 'Skipping build. Vite assets are already up-to-date ⚡️'
|
19
|
+
true
|
20
|
+
end
|
21
|
+
end
|
22
|
+
|
23
|
+
# Public: Returns true if all the assets built by Vite are up to date.
|
24
|
+
def fresh?
|
25
|
+
previous_files_digest&.== watched_files_digest
|
26
|
+
end
|
27
|
+
|
28
|
+
# Public: Returns true if any of the assets built by Vite is out of date.
|
29
|
+
def stale?
|
30
|
+
!fresh?
|
31
|
+
end
|
32
|
+
|
33
|
+
private
|
34
|
+
|
35
|
+
delegate :config, :logger, to: :@vite_rails
|
36
|
+
|
37
|
+
# Internal: Writes a digest of the watched files to disk for future checks.
|
38
|
+
def record_files_digest
|
39
|
+
config.build_cache_dir.mkpath
|
40
|
+
files_digest_path.write(watched_files_digest)
|
41
|
+
end
|
42
|
+
|
43
|
+
# Internal: The path of where a digest of the watched files is stored.
|
44
|
+
def files_digest_path
|
45
|
+
config.build_cache_dir.join("last-compilation-digest-#{ config.mode }")
|
46
|
+
end
|
47
|
+
|
48
|
+
# Internal: Reads a digest of watched files from disk.
|
49
|
+
def previous_files_digest
|
50
|
+
files_digest_path.read if files_digest_path.exist? && config.manifest_path.exist?
|
51
|
+
rescue Errno::ENOENT, Errno::ENOTDIR
|
52
|
+
end
|
53
|
+
|
54
|
+
# Internal: Returns a digest of all the watched files, allowing to detect
|
55
|
+
# changes, and skip Vite builds if no files have changed.
|
56
|
+
def watched_files_digest
|
57
|
+
Dir.chdir File.expand_path(config.root) do
|
58
|
+
files = Dir[*watched_paths].reject { |f| File.directory?(f) }
|
59
|
+
file_ids = files.sort.map { |f| "#{ File.basename(f) }/#{ Digest::SHA1.file(f).hexdigest }" }
|
60
|
+
Digest::SHA1.hexdigest(file_ids.join('/'))
|
61
|
+
end
|
62
|
+
end
|
63
|
+
|
64
|
+
# Public: Initiates a Vite build command to generate assets.
|
65
|
+
#
|
66
|
+
# Returns true if the build is successful, or false if it failed.
|
67
|
+
def build_with_vite
|
68
|
+
logger.info 'Building with Vite ⚡️'
|
69
|
+
|
70
|
+
stdout, stderr, status = Open3.capture3(vite_env,
|
71
|
+
"#{ which_ruby } ./bin/vite build --mode #{ config.mode }", chdir: File.expand_path(config.root))
|
72
|
+
|
73
|
+
if status.success?
|
74
|
+
logger.info "Build with Vite complete: #{ config.build_output_dir }"
|
75
|
+
logger.error(stderr.to_s) unless stderr.empty?
|
76
|
+
logger.info(stdout) unless config.hide_build_console_output
|
77
|
+
else
|
78
|
+
non_empty_streams = [stdout, stderr].delete_if(&:empty?)
|
79
|
+
logger.error "Build with Vite failed:\n#{ non_empty_streams.join("\n\n") }"
|
80
|
+
end
|
81
|
+
|
82
|
+
status.success?
|
83
|
+
end
|
84
|
+
|
85
|
+
# Internal: Used to prefix the bin/vite executable file.
|
86
|
+
def which_ruby
|
87
|
+
bin_vite_path = config.root.join('bin/vite')
|
88
|
+
first_line = File.readlines(bin_vite_path).first.chomp
|
89
|
+
/ruby/.match?(first_line) ? RbConfig.ruby : ''
|
90
|
+
end
|
91
|
+
|
92
|
+
# Internal: Files and directories that should be watched for changes.
|
93
|
+
#
|
94
|
+
# NOTE: You can specify additional ones in vite.json using "watchAdditionalPaths": [...]
|
95
|
+
def watched_paths
|
96
|
+
[
|
97
|
+
*config.watch_additional_paths,
|
98
|
+
"#{ config.source_code_dir }/**/*",
|
99
|
+
'yarn.lock',
|
100
|
+
'package.json',
|
101
|
+
config.config_path,
|
102
|
+
].freeze
|
103
|
+
end
|
104
|
+
|
105
|
+
# Internal: Sets additional environment variables for vite-plugin-ruby.
|
106
|
+
def vite_env
|
107
|
+
ViteRails.env.merge(
|
108
|
+
"#{ ViteRails::ENV_PREFIX }_CONFIG_PATH" => config.config_path,
|
109
|
+
"#{ ViteRails::ENV_PREFIX }_MODE" => config.mode,
|
110
|
+
"#{ ViteRails::ENV_PREFIX }_ROOT" => config.root,
|
111
|
+
).transform_values(&:to_s)
|
112
|
+
end
|
113
|
+
end
|
@@ -0,0 +1,68 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
# Public: Encapsulates common tasks, available both programatically and in Rake.
|
4
|
+
class ViteRails::Commands
|
5
|
+
def initialize(vite_rails)
|
6
|
+
@vite_rails = vite_rails
|
7
|
+
end
|
8
|
+
|
9
|
+
# Public: Loads the manifest with all the entries compiled by Vite.
|
10
|
+
def bootstrap
|
11
|
+
manifest.refresh
|
12
|
+
end
|
13
|
+
|
14
|
+
# Public: Builds all assets that are managed by Vite, from the entrypoints.
|
15
|
+
def build
|
16
|
+
builder.build.tap { manifest.refresh }
|
17
|
+
end
|
18
|
+
|
19
|
+
# Public: Removes all build cache and previously compiled assets.
|
20
|
+
def clobber
|
21
|
+
config.build_output_dir.rmtree if config.build_output_dir.exist?
|
22
|
+
config.build_cache_dir.rmtree if config.build_cache_dir.exist?
|
23
|
+
end
|
24
|
+
|
25
|
+
# Public: Cleanup old assets in the output directory.
|
26
|
+
#
|
27
|
+
# keep_up_to - Max amount of backups to preserve.
|
28
|
+
# age_in_seconds - Amount of time to look back in order to preserve them.
|
29
|
+
#
|
30
|
+
# NOTE: By default keeps the last version, or 2 if created in the past hour.
|
31
|
+
#
|
32
|
+
# Examples:
|
33
|
+
# To force only 1 backup to be kept: clean(1, 0)
|
34
|
+
# To only keep files created within the last 10 minutes: clean(0, 600)
|
35
|
+
def clean(keep_up_to: 2, age_in_seconds: 3600)
|
36
|
+
return false unless config.build_output_dir.exist? && config.manifest_path.exist?
|
37
|
+
|
38
|
+
versions.sort.reverse
|
39
|
+
.each_with_index
|
40
|
+
.drop_while { |(mtime, _), index|
|
41
|
+
max_age = [0, Time.now - Time.at(mtime)].max
|
42
|
+
max_age < age_in_seconds || index < keep_up_to
|
43
|
+
}
|
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
|
51
|
+
end
|
52
|
+
true
|
53
|
+
end
|
54
|
+
|
55
|
+
private
|
56
|
+
|
57
|
+
delegate :config, :builder, :manifest, :logger, to: :@vite_rails
|
58
|
+
|
59
|
+
def versions
|
60
|
+
all_files = Dir.glob("#{ config.build_output_dir }/**/*")
|
61
|
+
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 }
|
63
|
+
end
|
64
|
+
|
65
|
+
def current_version_files
|
66
|
+
Dir.glob(manifest.refresh.values.map { |value| config.build_output_dir.join("#{ value['file'] }*") })
|
67
|
+
end
|
68
|
+
end
|