lib/vite_ruby/builder.rb in vite_ruby-1.0.5 vs lib/vite_ruby/builder.rb in vite_ruby-1.1.0
- old
+ new
@@ -1,59 +1,60 @@
# frozen_string_literal: true
+require 'json'
require 'digest/sha1'
# Public: Keeps track of watched files and triggers builds as needed.
class ViteRuby::Builder
def initialize(vite_ruby)
@vite_ruby = vite_ruby
end
# Public: Checks if the watched files have changed since the last compilation,
# and triggers a Vite build if any files have changed.
- def build
- if stale?
- build_with_vite.tap { record_files_digest }
- else
- logger.debug 'Skipping build. Vite assets are already up-to-date ⚡️'
+ def build(*args)
+ last_build = last_build_metadata
+ if args.delete('--force') || last_build.stale?
+ build_with_vite(*args).tap { |success| record_build_metadata(success, last_build) }
+ elsif last_build.success
+ logger.debug "Skipping vite build. Watched files have not changed since the last build at #{ last_build.timestamp }"
true
+ else
+ logger.error "Skipping vite build. Watched files have not changed since the build failed at #{ last_build.timestamp } ❌"
+ false
end
end
- # Public: Returns true if all the assets built by Vite are up to date.
- def fresh?
- previous_files_digest&.== watched_files_digest
+ # Internal: Reads the result of the last compilation from disk.
+ def last_build_metadata
+ ViteRuby::Build.from_previous(last_build_attrs, watched_files_digest)
end
- # Public: Returns true if any of the assets built by Vite is out of date.
- def stale?
- !fresh?
- end
-
private
extend Forwardable
def_delegators :@vite_ruby, :config, :logger
+ # Internal: Reads metadata recorded on the last build, if it exists.
+ def last_build_attrs
+ last_build_path.exist? ? JSON.parse(last_build_path.read.to_s) : {}
+ rescue JSON::JSONError, Errno::ENOENT, Errno::ENOTDIR
+ {}
+ end
+
# Internal: Writes a digest of the watched files to disk for future checks.
- def record_files_digest
+ def record_build_metadata(success, build)
config.build_cache_dir.mkpath
- files_digest_path.write(watched_files_digest)
+ last_build_path.write build.with_result(success).to_json
end
- # Internal: The path of where a digest of the watched files is stored.
- def files_digest_path
- config.build_cache_dir.join("last-compilation-digest-#{ config.mode }")
+ # Internal: The file path where metadata of the last build is stored.
+ def last_build_path
+ config.build_cache_dir.join("last-build-#{ config.mode }.json")
end
- # Internal: Reads a digest of watched files from disk.
- def previous_files_digest
- files_digest_path.read if files_digest_path.exist? && config.manifest_path.exist?
- rescue Errno::ENOENT, Errno::ENOTDIR
- end
-
# Internal: Returns a digest of all the watched files, allowing to detect
# changes, and skip Vite builds if no files have changed.
def watched_files_digest
Dir.chdir File.expand_path(config.root) do
files = Dir[*watched_paths].reject { |f| File.directory?(f) }
@@ -63,32 +64,30 @@
end
# Public: Initiates a Vite build command to generate assets.
#
# Returns true if the build is successful, or false if it failed.
- def build_with_vite
+ def build_with_vite(*args)
logger.info 'Building with Vite ⚡️'
- stdout, stderr, status = ViteRuby.run(['build'], capture: true)
- log_build_result(stdout, stderr, status)
+ stdout, stderr, status = ViteRuby.run(['build', *args], capture: true)
+ log_build_result(stdout, stderr.to_s, status)
status.success?
end
# Internal: Outputs the build results.
#
# NOTE: By default it also outputs the manifest entries.
- def log_build_result(stdout, stderr, status)
+ def log_build_result(_stdout, stderr, status)
if status.success?
logger.info "Build with Vite complete: #{ config.build_output_dir }"
- logger.error(stderr.to_s) unless stderr.empty?
- logger.info(stdout) unless config.hide_build_console_output
+ logger.error stderr.to_s unless stderr.empty?
else
- non_empty_streams = [stdout, stderr].delete_if(&:empty?)
- errors = non_empty_streams.join("\n\n")
- errors += "\n❌ Check that vite and vite-plugin-ruby are in devDependencies and have been installed. " if errors.include?('ERR! canceled')
- logger.error "Build with Vite failed:\n#{ errors }"
+ logger.error stderr
+ logger.error 'Build with Vite failed! ❌'
+ logger.error '❌ Check that vite and vite-plugin-ruby are in devDependencies and have been installed. ' if stderr.include?('ERR! canceled')
end
end
# Internal: Files and directories that should be watched for changes.
#
@@ -96,10 +95,14 @@
def watched_paths
[
*config.watch_additional_paths,
"#{ config.source_code_dir }/**/*",
'yarn.lock',
+ 'package-lock.json',
+ 'pnpm-lock.yaml',
'package.json',
+ 'vite.config.ts',
+ 'vite.config.js',
config.config_path,
].freeze
end
end