Rails——如何只在某些页面上包含Javascript文件

时间:2022-05-02 11:00:44

I have a WYSIWYG editor that I have built into the site and customised. There are a lot of Javascript files that only need to be loaded on the pages with the WYSIWYG editor; currently they are loaded on every page (and even break other Javascript on certain pages).

我有一个WYSIWYG编辑器,我在网站中内置并定制。有很多Javascript文件只需要用WYSIWYG编辑器加载到页面上;当前,它们被加载到每个页面上(甚至在某些页面上破坏其他Javascript)。

Currently the Javascript files are in assets/javascript/wysiwyg/ and aren't included as the require files in application.js but are still included on every page because of the assets pipeline (I think).

目前,Javascript文件处于资产/ Javascript /wysiwyg/中,不包括在应用程序中需要的文件。但是由于资产管道(我认为),仍然包含在每个页面中。

I want to know if I can exclude these files from the other pages. Is it possible to move them from the assets pipeline to the public/ directory and import them (in the coffee script files, maybe?) into the appropriate views?

我想知道我是否可以将这些文件从其他页面中排除。是否可能将它们从资产管道移动到公共/目录并将它们(可能是在咖啡脚本文件中)导入到适当的视图中?

1 个解决方案

#1


9  

You can put any Javascript files that you want to load manually in the public/javascripts/lib directory of your application, and they will not be included in the assets pipeline. You can then load them manually on the pages that need them.

您可以将任何您想要手动加载的Javascript文件放入应用程序的公共/ Javascript /lib目录中,它们不会包含在资产管道中。然后,您可以在需要它们的页面上手动加载它们。

For instance, in one project, I use the Chosen jQuery plugin, and I load it like so:

例如,在一个项目中,我使用了选择的jQuery插件,我这样加载:

<script type="text/javascript" src="/javascripts/lib/chosen.jquery.min.js"></script>

Rails will source the public files from public/, so you only need to reference your files from there (remove the public/ bit).

Rails将从public/获取公共文件,因此您只需要从那里引用文件(删除public/ bit)。

This project is fairly large, with 88 controllers, 662 actions, and a total of 38 custom javascript libraries that get used sporadically around the app, including markdown editors, charting libraries, and even jQuery UI.

这个项目相当大,有88个控制器,662个动作,总共有38个定制的javascript库,这些库偶尔会在应用中使用,包括markdown编辑器、绘图库,甚至jQuery UI。

To manage the sprawl and to keep each page as tight as possible, I have done 2 things: 1) in my controller, I set an instance variable,@page_libs, to list the libs to load, and 2) the layout uses the values in @page_libs to include the specialty Javascript when required.

为了管理蔓延,并尽可能地保持每个页面的紧密性,我做了两件事:1)在我的控制器中,我设置了一个实例变量@page_libs,列出要加载的libs;

A controller action might look like this:

控制器动作可以如下所示:

def edit
  @products = products.find(params[:id])
  @page_libs = ['ui', 'textile']
end

And the app/views/layouts/application.html.erb includes this in the correct place:

和app /视图/布局/ 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 -%>

Note that the first include is for jQuery UI, which I load from a CDN, rather than from my app's public. This technique works just as well with external libraries, as well as those that you host. In fact, most pages in my app only depend on 2 external libraries (jQuery and Underscore.js), but have the option of loading up to 16 other Javascript libraries from external sources. Limiting external libraries on the page can significantly reduce your page load times, which is a direct performance boost for your application.

注意,第一个包含是针对jQuery UI的,它是从CDN加载的,而不是从我的应用程序的public加载的。这种技术与外部库以及宿主机一样有效。实际上,我的应用程序中的大多数页面都只依赖于两个外部库(jQuery和Underscore.js),但可以选择从外部源加载最多16个其他Javascript库。限制页面上的外部库可以显著减少页面加载时间,这直接提高了应用程序的性能。

Sometimes, a Javascript library will include CSS components, as well. Or, you may even have page-specific CSS to include. The same approach can be taken with external stylesheet. These are the corresponding page-specific stylesheet "includes" for the above Javascript libraries:

有时,Javascript库也会包含CSS组件。或者,您甚至可以包含页面特定的CSS。外部样式表也可以采用相同的方法。这些是上述Javascript库对应的页面特定样式表“包含”:

<%- 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 -%>

This way, I have a single point in the project to manage the libraries, regardless of how many (or few) are required for a page. I'll probably eventually create a series of custom before_action handlers in the ApplicationController to define which the libraries a page needs included. Something like this:

通过这种方式,我在项目中有一个单独的点来管理这些库,不管页面需要多少(或很少)。我可能最终会在ApplicationController中创建一系列自定义before_action处理程序,以定义页面需要包含哪些库。是这样的:

before_action: :include_library_ui,     only: [:new, :edit]
before_action: :include_library_swiper, only: [:show]

This would clean up the controller actions a bit more and make it easier to identify dependencies. However, given the size of my codebase and the pressing tasks remaining, I haven't taken this leap yet. Maybe it will inspire you to do so to start out.

这将进一步清理控制器操作,使其更容易识别依赖项。然而,考虑到我的代码库的大小和剩下的紧迫任务,我还没有实现这个飞跃。也许它会激励你开始这样做。

#1


9  

You can put any Javascript files that you want to load manually in the public/javascripts/lib directory of your application, and they will not be included in the assets pipeline. You can then load them manually on the pages that need them.

您可以将任何您想要手动加载的Javascript文件放入应用程序的公共/ Javascript /lib目录中,它们不会包含在资产管道中。然后,您可以在需要它们的页面上手动加载它们。

For instance, in one project, I use the Chosen jQuery plugin, and I load it like so:

例如,在一个项目中,我使用了选择的jQuery插件,我这样加载:

<script type="text/javascript" src="/javascripts/lib/chosen.jquery.min.js"></script>

Rails will source the public files from public/, so you only need to reference your files from there (remove the public/ bit).

Rails将从public/获取公共文件,因此您只需要从那里引用文件(删除public/ bit)。

This project is fairly large, with 88 controllers, 662 actions, and a total of 38 custom javascript libraries that get used sporadically around the app, including markdown editors, charting libraries, and even jQuery UI.

这个项目相当大,有88个控制器,662个动作,总共有38个定制的javascript库,这些库偶尔会在应用中使用,包括markdown编辑器、绘图库,甚至jQuery UI。

To manage the sprawl and to keep each page as tight as possible, I have done 2 things: 1) in my controller, I set an instance variable,@page_libs, to list the libs to load, and 2) the layout uses the values in @page_libs to include the specialty Javascript when required.

为了管理蔓延,并尽可能地保持每个页面的紧密性,我做了两件事:1)在我的控制器中,我设置了一个实例变量@page_libs,列出要加载的libs;

A controller action might look like this:

控制器动作可以如下所示:

def edit
  @products = products.find(params[:id])
  @page_libs = ['ui', 'textile']
end

And the app/views/layouts/application.html.erb includes this in the correct place:

和app /视图/布局/ 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 -%>

Note that the first include is for jQuery UI, which I load from a CDN, rather than from my app's public. This technique works just as well with external libraries, as well as those that you host. In fact, most pages in my app only depend on 2 external libraries (jQuery and Underscore.js), but have the option of loading up to 16 other Javascript libraries from external sources. Limiting external libraries on the page can significantly reduce your page load times, which is a direct performance boost for your application.

注意,第一个包含是针对jQuery UI的,它是从CDN加载的,而不是从我的应用程序的public加载的。这种技术与外部库以及宿主机一样有效。实际上,我的应用程序中的大多数页面都只依赖于两个外部库(jQuery和Underscore.js),但可以选择从外部源加载最多16个其他Javascript库。限制页面上的外部库可以显著减少页面加载时间,这直接提高了应用程序的性能。

Sometimes, a Javascript library will include CSS components, as well. Or, you may even have page-specific CSS to include. The same approach can be taken with external stylesheet. These are the corresponding page-specific stylesheet "includes" for the above Javascript libraries:

有时,Javascript库也会包含CSS组件。或者,您甚至可以包含页面特定的CSS。外部样式表也可以采用相同的方法。这些是上述Javascript库对应的页面特定样式表“包含”:

<%- 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 -%>

This way, I have a single point in the project to manage the libraries, regardless of how many (or few) are required for a page. I'll probably eventually create a series of custom before_action handlers in the ApplicationController to define which the libraries a page needs included. Something like this:

通过这种方式,我在项目中有一个单独的点来管理这些库,不管页面需要多少(或很少)。我可能最终会在ApplicationController中创建一系列自定义before_action处理程序,以定义页面需要包含哪些库。是这样的:

before_action: :include_library_ui,     only: [:new, :edit]
before_action: :include_library_swiper, only: [:show]

This would clean up the controller actions a bit more and make it easier to identify dependencies. However, given the size of my codebase and the pressing tasks remaining, I haven't taken this leap yet. Maybe it will inspire you to do so to start out.

这将进一步清理控制器操作,使其更容易识别依赖项。然而,考虑到我的代码库的大小和剩下的紧迫任务,我还没有实现这个飞跃。也许它会激励你开始这样做。