Rob*_*Rob 6 javascript ruby ruby-on-rails asset-pipeline ruby-on-rails-4
我有一个WYSIWYG编辑器,我已在网站中内置并自定义.有许多Javascript文件只需要使用WYSIWYG编辑器加载到页面上; 目前它们被加载到每个页面上(甚至在某些页面上打破其他Javascript).
目前,Javascript文件存在assets/javascript/wysiwyg/并且不包含在需求文件中,application.js但由于资产管道(我认为),它仍然包含在每个页面中.
我想知道我是否可以从其他页面中排除这些文件.是否可以将它们从资产管道移动到public/目录并将它们(在咖啡脚本文件中,可能?)导入相应的视图中?
Mic*_*ill 18
您可以将要手动加载的任何Javascript文件放在public/javascripts/lib应用程序的目录中,它们不会包含在资产管道中.然后,您可以在需要它们的页面上手动加载它们.
例如,在一个项目中,我使用了Chosen jQuery插件,我就像这样加载它:
<script type="text/javascript" src="/javascripts/lib/chosen.jquery.min.js"></script>
Run Code Online (Sandbox Code Playgroud)
Rails将从中获取公共文件public/,因此您只需要从那里引用您的文件(删除该public/位).
这个项目相当庞大,有88个控制器,662个动作,以及总共38个自定义javascript库,它们偶尔会在应用程序中使用,包括降价编辑器,图表库,甚至是jQuery UI.
要管理的扩张,并保留每个页面尽可能紧密,我已经做了两件事情:1)在我的控制,我设置一个实例变量,@page_libs以列出库加载,和2)布局中使用的值@page_libs来在需要时包含专业Javascript.
控制器操作可能如下所示:
def edit
@products = products.find(params[:id])
@page_libs = [:ui, :textile]
end
Run Code Online (Sandbox Code Playgroud)
并将其app/views/layouts/application.html.erb包含在正确的位置:
<%- if @page_libs&.include?(:ui) || @page_libs&.include?(:table) %>
<script type="text/javascript" src="//ajax.googleapis.com/ajax/libs/jqueryui/1.10.4/jquery-ui.min.js"></script>
<script type="text/javascript" src="/javascripts/lib/chosen.jquery.min.js"></script>
<% end -%>
<%- if @page_libs&.include?(:swiper) %>
<script type="text/javascript" src="/javascripts/lib/idangerous.swiper.min.js"></script>
<% end -%>
<%- if @page_libs&.include?(:table) %>
<script type="text/javascript" src="/javascripts/lib/jquery.handsontable.full.js"></script>
<% end -%>
<%- if @page_libs&.include?(:textile) %>
<script type="text/javascript" src="/javascripts/lib/textile.js" charset="utf-8"></script>
<% end -%>
Run Code Online (Sandbox Code Playgroud)
请注意,第一个包含jQuery UI,我从CDN加载,而不是从我的应用程序加载public.此技术与外部库以及您托管的库一样有效.事实上,我的应用程序中的大多数页面仅依赖于2个外部库(jQuery和Underscore.js),但可以选择从外部源加载多达16个其他Javascript库.限制页面上的外部库可以显着减少页面加载时间,这可以直接提升应用程序的性能.
有时,Javascript库也将包含CSS组件.或者,您甚至可以包含特定于页面的CSS.外部样式表可以采用相同的方法.这些是上述Javascript库的相应页面特定样式表"includes":
<%- if @page_libs&.include?(:ui) %>
<link rel="stylesheet" type="text/css" href="//ajax.googleapis.com/ajax/libs/jqueryui/1.10.4/themes/smoothness/jquery-ui.css">
<link rel="stylesheet" type="text/css" href="/stylesheets/lib/chosen.min.css">
<% end -%>
<%- if @page_libs&.include?(:swiper) %>
<link rel="stylesheet" type="text/css" href="/stylesheets/lib/idangerous.swiper.css">
<% end -%>
Run Code Online (Sandbox Code Playgroud)
这样,无论页面需要多少(或几个),我在项目中都有一个点来管理库.我最终可能会before_action在ApplicationController中创建一系列自定义处理程序,以定义页面所需的库.像这样的东西:
before_action: :include_library_ui, only: [:new, :edit]
before_action: :include_library_swiper, only: [:show]
Run Code Online (Sandbox Code Playgroud)
这将更多地清理控制器操作,并使识别依赖项更容易.但是,考虑到我的代码库的大小和剩下的紧迫任务,我还没有采取这种飞跃.也许它会鼓励你这样做才能开始.
现在这已经过时了,我们正处于使用 Rails 6 的 Webpacker 世界中,但是如果您想以老派的 Sprockets 方式使事情更简单,您可能会喜欢下面描述的方法。请注意,它确实是每个视图- 其他答案对于更广泛的每个控制器的东西有很好的方法。
让您的主布局声明一个“内容”部分。例如,在application.htm.erb:
<!DOCTYPE html>
<html>
<head>
<%= csrf_meta_tags %>
<%= csp_meta_tag %>
...etc...
<%= content_for :head %>
</head>
...
</html>
Run Code Online (Sandbox Code Playgroud)
在这里,:head只是一个标签,你可以给它任何你想要的名字。您也可以根据需要在布局中包含任意数量的此类声明。它们只是 Rails 允许视图将额外内容插入外部布局的那些位的方式。所以 - 您可以在各个视图中使用它在布局部分中添加您的 JS 文件<script>标签<head>。
例如,假设我通过将zxcvbn.js库的一个 JavaScript 文件复制到vendor/assets/javascripts/zxcvbn.js. 我有一个edit.html.erb页面需要这样做,所以在该文件的顶部,我添加:
<% content_for :head do %>
<%= javascript_include_tag('zxcvbn', 'data-turbolinks-track': 'reload') %>
<% end %>
Run Code Online (Sandbox Code Playgroud)
...如果您不使用 Turbolinks 属性,请删除它。这意味着当 ERB 编译页面时,它会在布局的“内容为头部”部分替换该标签,因此脚本标签最终会出现在它的位置。这当然意味着页面加载时额外的 HTTP 获取,但仅限于使用它的视图中。在上面的例子中,JS 库非常大,通常只用于与用户更改密码相关的一两个地方;所以这是一个巨大的胜利application.js,尽管它几乎从未使用过,但它被集中到一个编译好的地方并在任何地方提供。
content_for由于在引擎盖下非常简单,这些东西非常聪明。如果您的视图是由多个部分构建的,并且其中有多个进行声明,则它们不会相互覆盖。每个都只是连接到正确的位置,所以最终结果几乎是你所期望的,没有任何令人讨厌的惊喜。
您还需要执行一个步骤来避免 Sprockets 的异常,因为您尝试包含的资产未预编译。你需要告诉链轮它存在;出于某种原因,这不是自动确定的。在 中config/initializers/assets.rb,声明未包含在例如application.js清单文件中的“带外”/未知文件:
<% content_for :head do %>
<%= javascript_include_tag('zxcvbn', 'data-turbolinks-track': 'reload') %>
<% end %>
Run Code Online (Sandbox Code Playgroud)
开箱即用的 Rails-generatedassets.rb有解释这一点的注释和一个注释掉的例子。
这一切都与资产管道正常合作,因此它与管道中的其他任何东西一样(或很糟糕,取决于您的经验!)工作,开发模式下的调试版本和生产中的缩小内容(取决于您的管道配置) .
| 归档时间: |
|
| 查看次数: |
7127 次 |
| 最近记录: |