В Rails 3 были rake assets: precompile: nodigest task, которая собирала активы и записывала их без части digest в каталоге /public/assets. В Rails 4 это было удалено, и по умолчанию все активы предварительно скомпилированы только с помощью дайджеста. По разным причинам мне нужна также некодированная версия некоторых активов. Есть ли простой способ вернуть прежнее поведение?
Rake assets: precompile: nodigest в Rails 4
Ответ 1
Версия sprockets-rails
, используемая в Rails 4.0.0, больше не поддерживает неперевариваемые активы.
Per звездочка Readme:
Только компилирует имена файлов дайджеста. Статические неперевариваемые активы должны просто жить в общественных местах
Таким образом, любые активы, которые должны быть статичными, могут быть вручную помещены в вашу папку public
. Если вам нужно скопировать скомпилированные активы, такие как файлы SCSS и т.д., Эта задача rake может помочь (источник):
task non_digested: :environment do
assets = Dir.glob(File.join(Rails.root, 'public/assets/**/*'))
regex = /(-{1}[a-z0-9]{32}*\.{1}){1}/
assets.each do |file|
next if File.directory?(file) || file !~ regex
source = file.split('/')
source.push(source.pop.gsub(regex, '.'))
non_digested = File.join(source)
FileUtils.cp(file, non_digested)
end
end
Ответ 2
Существует также драгоценный камень, чтобы сделать это для вас: несколько вызывающе названный non-stupid-digest-assets.
gem "non-stupid-digest-assets"
Ответ 3
Как лучший ответ, я рекомендую сначала прочитать проблему, чтобы полностью понять предысторию, если вы не спешите. Мне больше нравится эта идея, https://github.com/rails/sprockets-rails/issues/49#issuecomment-24837265.
И ниже мой личный прием, в основном я взял код из вышеприведенного ответа. В моем случае у меня есть только 2 файла, которые я хочу не переваривать, widget.js и widget.css. Поэтому я использую метод sprockets для поиска переваренных файлов, а затем символически привязываю его к общей папке.
# config/environments/production.rb
config.assets.precompile += %w[v1/widget.js v1/widget.css]
# lib/tasks/assets.rake
namespace :assets do
desc 'symlink digested widget-xxx.js and widget-xxx.css to widget.js and widget.css'
task symlink_widget: :environment do
next if Rails.env.development? || Rails.env.test?
digested_files = []
# e.g. /webapps/myapp/public/assets
assets_path = File.join(Rails.root, 'public', Rails.configuration.assets.prefix)
%w(v1/widget.js v1/widget.css).each do |asset|
# e.g. 'v1/widget-b61b9eaaa5ef0d92bd537213138eb0c9.js'
logical_path = Rails.application.assets.find_asset(asset).digest_path
digested_files << File.join(assets_path, logical_path)
end
fingerprint_regex = /(-{1}[a-z0-9]{32}*\.{1}){1}/
digested_files.each do |file|
next unless file =~ fingerprint_regex
# remove fingerprint & '/assets' from file path
non_digested = file.gsub(fingerprint_regex, '.')
.gsub(Rails.configuration.assets.prefix, '')
puts "Symlinking #{file} to #{non_digested}"
system "ln -nfs #{file} #{non_digested}"
end
end
end
Ответ 4
Мой огромный анализ всех доступных опций находится здесь:
https://bibwild.wordpress.com/2014/10/02/non-digested-asset-names-in-rails-4-your-options/
Я решил добавить пользовательскую задачу rake, используя настраиваемую конфигурацию, чтобы определить определенные активы для создания непереваренных версий и использовать манифест Sprockets, чтобы найти переваренные активы и скопировать их с непереваренными именами.
# Rails4 doesn't create un-fingerprinted assets anymore, but we
# need a couple for umlaut API. Let try to hook in and make
# symlinks.
#
# list of what file(globs) need non-digest-named copies is kept in
# Umlaut::Engine.config.non_digest_named_assets
# defined in lib/umlaut.rb, but app can modify it if desired.
require 'umlaut'
require 'pathname'
# Every time assets:precompile is called, trigger umlaut:create_non_digest_assets afterwards.
Rake::Task["assets:precompile"].enhance do
Rake::Task["umlaut:create_non_digest_assets"].invoke
end
namespace :umlaut do
# This seems to be basically how ordinary asset precompile
# is logging, ugh.
logger = Logger.new($stderr)
# Based on suggestion at https://github.com/rails/sprockets-rails/issues/49#issuecomment-20535134
# but limited to files in umlaut namespaced asset directories.
task :create_non_digest_assets => :"assets:environment" do
manifest_path = Dir.glob(File.join(Rails.root, 'public/assets/manifest-*.json')).first
manifest_data = JSON.load(File.new(manifest_path))
manifest_data["assets"].each do |logical_path, digested_path|
logical_pathname = Pathname.new logical_path
if Umlaut::Engine.config.non_digest_named_assets.any? {|testpath| logical_pathname.fnmatch?(testpath, File::FNM_PATHNAME) }
full_digested_path = File.join(Rails.root, 'public/assets', digested_path)
full_nondigested_path = File.join(Rails.root, 'public/assets', logical_path)
logger.info "(Umlaut) Copying to #{full_nondigested_path}"
# Use FileUtils.copy_file with true third argument to copy
# file attributes (eg mtime) too, as opposed to FileUtils.cp
# Making symlnks with FileUtils.ln_s would be another option, not
# sure if it would have unexpected issues.
FileUtils.copy_file full_digested_path, full_nondigested_path, true
end
end
end
end
Ответ 5
Спасибо Дилан Марков, я следую его ответу, но я обнаружил, что при использовании Capistrano существует несколько версий актива (например, application-0a *.css, application-9c *.css,...), чтобы последний должен быть не переваривается. Здесь логика:
namespace :my_app do
task non_digested: :environment do
assets = Dir.glob(File.join(Rails.root, 'public/assets/**/*'))
regex = /(?<!manifest)(-{1}[a-z0-9]{32}\.{1}){1}/
candidates = {}
# gather files info
assets.each do |file|
next if File.directory?(file) || file !~ regex
source = file.split('/')
source.push(source.pop.gsub(regex, '.'))
non_digested = File.join(source)
file_mtime = File.stat(file).mtime
c = candidates[non_digested]
if c.blank? || file_mtime > c[:mtime]
candidates[non_digested] = {orig: file, mtime: file_mtime}
end
end
# genearate
for non_digested, val in candidates do
FileUtils.cp(val[:orig], non_digested)
end
end
end
Rake::Task['assets:precompile'].enhance do
Rake::Task['my_app:non_digested'].invoke
end
Как и в качестве, я применил 907-й комментарий к регулярному выражению и добавил hook, чтобы эта задача выполнялась после прекомпиляции.
Ответ 6
Задайте это свойство config.assets.digest = false
в файле `development.rb '