Rails技术问询:如何通过常规路由提供含Ruby数据的Asset Pipeline JS资源?
我来帮你搞定这个问题!结合Rails的Asset Pipeline和路由机制,完全能实现你要的两个目标,下面一步步来拆解:
第一步:整理共用JS代码结构
首先把Chrome扩展和SPA共用的JS代码单独抽离出来,方便两边复用:
- 在
app/assets/javascripts/下新建shared/目录,把所有共用代码放到这里(比如shared/utils.js、shared/api-client.js等) - 在
app/assets/javascripts/application.js里引入这些共用代码,确保SPA能通过常规Asset Pipeline加载://= require shared/utils //= require shared/api-client // 其他SPA专属代码...
第二步:设置Chrome扩展专属路由
在config/routes.rb里添加一个路由,用于Chrome扩展请求带Ruby数据的共用JS:
get '/chrome-extension/application.js', to: 'chrome_extension#shared_js'
第三步:编写控制器动作注入Ruby数据
接下来需要一个控制器来处理这个路由请求,把Ruby后端数据和Asset Pipeline编译后的JS结合起来:
- 新建控制器文件
app/controllers/chrome_extension_controller.rb:class ChromeExtensionController < ApplicationController def shared_js # 准备要注入到JS里的Ruby数据,这里可以从数据库/配置/当前会话获取 @extension_data = { api_base_url: Rails.application.config.api_base_url, feature_flags: FeatureFlag.all.pluck(:name, :enabled).to_h } # 设置响应类型为JS,确保浏览器正确解析 response.content_type = 'application/javascript' end end - 新建ERB模板文件
app/views/chrome_extension/shared_js.js.erb,这个模板会把Ruby数据注入后,再加载共用JS:// 注入后端传递的Ruby数据,Chrome扩展可以直接访问这个全局变量 window.CHROME_EXTENSION_CONFIG = <%= raw @extension_data.to_json %>; // 加载Asset Pipeline编译后的共用JS代码 <%= javascript_include_tag 'shared' %>
第四步:确保生产环境正常预编译
别忘了在config/initializers/assets.rb里添加共用JS的预编译规则,生产环境才能正确生成编译后的文件:
Rails.application.config.assets.precompile += %w( shared.js )
额外注意事项
- 共用JS代码要保持环境无关性,不要直接依赖SPA的DOM结构或者Chrome扩展的
chrome.*API,避免两边加载时出错 - 如果需要缓存这个JS响应,可以在控制器动作里添加缓存头,比如
expires_in 1.day, public: true,提高加载效率 - 开发环境下可以用
rails server直接测试,访问http://localhost:3000/chrome-extension/application.js就能看到包含Ruby数据和共用JS的完整响应
内容的提问来源于stack exchange,提问作者Pedro Bernardes
相关产品推荐
相关产品推荐

