从Rails 5.1升级到7.1时出现SassC语法错误
Rails 5.1升级后SassC语法错误处理方案
我的应用已从Rails 5.1升级完成,本地服务器基础功能运行正常。运行旧系统测试时(原本想检查paperclip是否失效,最终会切换到Active Storage),推测factory_bot_rails初始化用户时触发了邮件发送,设置headless=false后,浏览器短暂出现以下Sass语法错误:
SassC::SyntaxError in Pages#home 在 /home/dave/bananashack/app/views/user_mailer/welcome_email.html.erb 中触发错误: 错误:"calc(100vh - 110px)" 不是 `min` 函数可用的数值类型 在 stdin 的第1行第33074列,`min` 函数内 来自 stdin 的第1行第33074列 >> x;flex:1;flex-direction:column;max-height:min(650px,calc(100vh - 110px));ove ------------------------------------------^ 提取的相关代码(第50行附近): 48 line = Native.context_get_error_line(context) 49 50 raise SyntaxError.new(message, filename: filename, line: line) 51 end 52 53 css = Native.context_get_output_string(context) 提示:你可以在Gemfile中添加 gem 'error_highlight', '>= 0.4.0',它会显示更精确的错误位置。 Rails根目录: /home/dave/bananashack 应用调用栈 | 框架调用栈 | 完整调用栈 sassc (2.4.0) lib/sassc/engine.rb:50:in `render' sassc-rails (2.1.2) lib/sassc/rails/compressor.rb:29:in `call' sprockets (4.2.1) lib/sprockets/sass_compressor.rb:30:in `call' sprockets (4.2.1) lib/sprockets/processor_utils.rb:84:in `call_processor' sprockets (4.2.1) lib/sprockets/processor_utils.rb:66:in `block in call_processors' sprockets (4.2.1) lib/sprockets/processor_utils.rb:65:in `reverse_each' sprockets (4.2.1) lib/sprockets/processor_utils.rb:65:in `call_processors' sprockets (4.2.1) lib/sprockets/loader.rb:184:in `load_from_unloaded' sprockets (4.2.1) lib/sprockets/loader.rb:59:in `block in load' sprockets (4.2.1) lib/sprockets/loader.rb:339:in `fetch_asset_from_dependency_cache' sprockets (4.2.1) lib/sprockets/loader.rb:43:in `load' sprockets (4.2.1) lib/sprockets/cached_environment.rb:44:in `block in load' concurrent-ruby (1.3.3) lib/concurrent-ruby/concurrent/map.rb:207:in `block in fetch_or_store' concurrent-ruby (1.3.3) lib/concurrent-ruby/concurrent/map.rb:187:in `fetch' concurrent-ruby (1.3.3) lib/concurrent-ruby/concurrent/map.rb:206:in `fetch_or_store' sprockets (4.2.1) lib/sprockets/cached_environment.rb:44:in `load' sprockets (4.2.1) lib/sprockets/bundle.rb:32:in `block in call' /home/dave/.rbenv/versions/3.1.4/lib/ruby/3.1.0/set.rb:511:in `each_key' /home/dave/.rbenv/versions/3.1.4/lib/ruby/3.1.0/set.rb:511:in `each' sprockets (4.2.1) lib/sprockets/bundle.rb:31:in `call' sprockets (4.2.1) lib/sprockets/processor_utils.rb:84:in `call_processor' sprockets (4.2.1) lib/sprockets/processor_utils.rb:66:in `block in call_processors' sprockets (4.2.1) lib/sprockets/processor_utils.rb:65:in `reverse_each' sprockets (4.2.1) lib/sprockets/processor_utils.rb:65:in `call_processors' sprockets (4.2.1) lib/sprockets/loader.rb:184:in `load_from_unloaded' sprockets (4.2.1) lib/sprockets/loader.rb:59:in `block in load' sprockets (4.2.1) lib/sprockets/loader.rb:339:in `fetch_asset_from_dependency_cache' sprockets (4.2.1) lib/sprockets/loader.rb:43:in `load' sprockets (4.2.1) lib/sprockets/cached_environment.rb:44:in `block in load' concurrent-ruby (1.3.3) lib/concurrent-ruby/concurrent/map.rb:207:in `block in fetch_or_store' concurrent-ruby (1.3.3) lib/concurrent-ruby/concurrent/map.rb:187:in `fetch' concurrent-ruby (1.3.3) lib/concurrent-ruby/concurrent/map.rb:206:in `fetch_or_store' sprockets (4.2.1) lib/sprockets/cached_environment.rb:44:in `load' sprockets (4.2.1) lib/sprockets/base.rb:81:in `find_asset' sprockets (4.2.1) lib/sprockets/base.rb:88:in `find_all_linked_assets' sprockets (4.2.1) lib/sprockets/manifest.rb:125:in `each' sprockets (4.2.1) lib/sprockets/manifest.rb:125:in `to_a' sprockets (4.2.1) lib/sprockets/manifest.rb:125:in `block (2 levels) in find' concurrent-ruby (1.3.3) lib/concurrent-ruby/concurrent/executor/safe_task_executor.rb:24:in `block in execute' concurrent-ruby (1.3.3) lib/concurrent-ruby/concurrent/synchronization/mutex_lockable_object.rb:48:in `block in synchronize' concurrent-ruby (1.3.3) lib/concurrent-ruby/concurrent/synchronization/mutex_lockable_object.rb:48:in `synchronize' concurrent-ruby (1.3.3) lib/concurrent-ruby/concurrent/synchronization/mutex_lockable_object.rb:48:in `synchronize' concurrent-ruby (1.3.3) lib/concurrent-ruby/concurrent/executor/safe_task_executor.rb:22:in `execute' concurrent-ruby (1.3.3) lib/concurrent-ruby/concurrent/promise.rb:564:in `block in realize' concurrent-ruby (1.3.3) lib/concurrent-ruby/concurrent/executor/ruby_thread_pool_executor.rb:359:in `run_task' concurrent-ruby (1.3.3) lib/concurrent-ruby/concurrent/executor/ruby_thread_pool_executor.rb:350:in `block (3 levels) in create_worker' concurrent-ruby (1.3.3) lib/concurrent-ruby/concurrent/executor/ruby_thread_pool_executor.rb:341:in `loop' concurrent-ruby (1.3.3) lib/concurrent-ruby/concurrent/executor/ruby_thread_pool_executor.rb:341:in `block (2 levels) in create_worker' concurrent-ruby (1.3.3) lib/concurrent-ruby/concurrent/executor/ruby_thread_pool_executor.rb:340:in `catch' concurrent-ruby (1.3.3) lib/concurrent-ruby/concurrent/executor/ruby_thread_pool_executor.rb:340:in `block in create_worker'
问题原因
你使用的sassc版本(2.4.0)基于旧版LibSass,不支持在min()函数中直接传入calc()表达式——它要求min()的参数必须是纯数值,不能包含动态计算逻辑。
解决方法
升级sassc依赖
在Gemfile中更新sassc到3.0及以上版本,运行bundle update sassc。新版会自动将Sass的min()编译为CSS原生min(),原生CSS支持calc()作为参数。兼容写法替换
如果暂时无法升级依赖,可把出错的代码替换为Sass兼容的逻辑:max-height: if(100vh - 110px > 650px, 650px, calc(100vh - 110px));或者用CSS变量先存储计算值:
--container-max-height: calc(100vh - 110px); max-height: min(650px, var(--container-max-height));测试场景临时规避
如果你只是为了测试paperclip功能,可直接在测试环境禁用邮件发送,避免触发模板编译错误。在config/environments/test.rb中添加:config.action_mailer.perform_deliveries = false
内容的提问来源于stack exchange,提问作者daveasdf_2
相关产品推荐
相关产品推荐

