New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Improve webpacker:clear task #2443
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -5,12 +5,34 @@ def initialize(webpacker) | |
@webpacker = webpacker | ||
end | ||
|
||
def clean(count = 2) | ||
if config.public_output_path.exist? && config.public_manifest_path.exist? && versions.count > count | ||
versions.drop(count).flat_map(&:last).each do |file| | ||
File.delete(file) if File.file?(file) | ||
logger.info "Removed #{file}" | ||
end | ||
# Cleanup old assets in the compile directory. By default it will | ||
# keep the latest version, 2 backups created within the past hour. | ||
# | ||
# Examples | ||
# | ||
# To force only 1 backup to be kept, set count=1 and age=0. | ||
# | ||
# To only keep files created within the last 10 minutes, set count=0 and | ||
# age=600. | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. @gauravtiwari if you really want to clean the directory, saving what Webpack created, why not just skip the whole There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I was investigating this code today and I think those comments are misleading (or I'm mixing booleans in my head). if we pass the same story for the second line, you can't pass |
||
# | ||
def clean(count = 2, age = 3600) | ||
if config.public_output_path.exist? && config.public_manifest_path.exist? | ||
versions | ||
.sort | ||
.reverse | ||
.each_with_index | ||
.drop_while do |(mtime, _), index| | ||
max_age = [0, Time.now - Time.at(mtime)].max | ||
max_age < age && index < count | ||
end | ||
.each do |(_, files), index| | ||
files.each do |file| | ||
if File.file?(file) | ||
File.delete(file) | ||
logger.info "Removed #{file}" | ||
end | ||
end | ||
end | ||
end | ||
|
||
true | ||
|
@@ -37,14 +59,16 @@ def versions | |
manifest_config = Dir.glob("#{config.public_manifest_path}*") | ||
|
||
packs = all_files - manifest_config - current_version | ||
packs.group_by { |file| File.mtime(file).utc.to_i }.sort.reverse | ||
packs.reject { |file| File.directory?(file) }.group_by { |file| File.mtime(file).utc.to_i } | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. This still assumes that all the files for a given compilation run of webpack are going to be outputted within 1 second, and so can be grouped into distinct runs and counted that way. That's not a valid assumption. The max_age code helps, but this still could lead to confusing and incorrect behavior. If files are older than the Also, with default capistrano config or heroku buildpacks or docker deploys, users don't often have the option of (easily) changing the params given to There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. @sbeam see my comment above. How about cleaning before compilation, rather than after with all this logic? There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. @justin808 that would work for some situations (including mine), but as I understand it, the point of keeping the last 2-3 versions of each compiled asses is in cases of rolling deploys or clients that have partially cached some of them, and there are still references to them out in the wild. So suddenly 404ing all old assets on each deploy isn't good. This is potentially an issue if you have e.g. capistrano deploys to multiple servers behind a naive load balancer that complete at different times. That's why sprockets has similar code more or less for years. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. @justin808 if you do want to clean the dir entirely, I think you could use the clean webpack plugin There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. @sbeam I think for rails/webpacker, that can work. However, I generally prefer that the webpack config be solely focused on webpack builds and not things like deleting files from some directory. In other words, I find plain shell commands more descriptive. Another issue is that many React + React + SSR projects build the client and server bundles in the same directory. So some thought must be given the order of the webpack builds, if concurrency is used, and ensuring that the clean stuff is configured right. |
||
end | ||
|
||
def current_version | ||
manifest.refresh.values.map do |value| | ||
packs = manifest.refresh.values.map do |value| | ||
next if value.is_a?(Hash) | ||
|
||
File.join(config.root_path, "public", value) | ||
File.join(config.root_path, "public", "#{value}*") | ||
end.compact | ||
|
||
Dir.glob(packs).uniq | ||
end | ||
end |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
In what way is the age of the retained files important? This just causes asset availability downtime and doesn't include any explanation of why such a thing is desirable.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@gauravtiwari @sbeam, maybe we can use the versions so long as they are OLDER than the age?
Right now, as soon as we find a few files with timestamps that differ by a second, we delete everything that's not in the current manifest.