markdown 资产管道

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了markdown 资产管道相关的知识,希望对你有一定的参考价值。

## Asset Pipeline
* Rails way of managing stylesheets, Javascript files and images.
* How does Rails know where to look for our files?
    * There is a path called the ASSET PATH: combination of folder paths for Rails to look into.
```ruby
Rails.application.config.assets.path => ['/Users/parm/assets...', '...', '...']
```
* If you require additional folders for Rails to search, you can include them in the `config/initializers/assets.rb`:
```ruby
Rails.application.config.assets.path << "NewPath"
```
* Now that there is a way to include stuff in to our rails project, how do we include them in our web page?
    * The Asset Pipeline (AP) uses a manifest file to tell Rails what to load.
    * The manifest file is a central location where you can list all the CSS or JS files your app needs (this is a feature of the AP!). 
* Here is an example:
```ruby
# app/assets/javascript/application.js
  //= require jquery
  //= require calendar
```
* YOU WILL NEED TO INCLUDE THE MANIFEST FILE IN THE LAYOUT FILE WITH THE SYNTAX: `javascript_include_tag`
* The AP will look for all of the files within its directories.
* Ex. The `require calendar` is a file located in `app/assets/javascripts/calendar.js`
* The manifest files configured in Rails will automatically add all the files into one file big file during production.
* PREPROCESSING
    * AP allows files to be combined and loaded from a predefined location in our app. 
    * We can also allow some of our files to be preprocessed (CSS uses SASS and JS uses CoffeeScript) which allows us to write better CSS and cleaner JS. 
    * Files with the extention .scss and .coffee tells Rails to use SASS and COFFEESCRIPT to preprocess those files before combining it into the one large file.
* CACHING
    * Keep a local copy of a time consuming operation so that you don't have to redo it again if the inputs are the same. 
    * Caches are usually key/value stores. Caching saves bandwidth and provides a speed boost for the user. 
    * So we load a page and then a few moments later, we load the same page. 
        * The browser can load it for you by keeping a local copy on hand. 
        * Browsers cache the responses they get from the requests they recieve by the headers that get sent with the response. 
        * The header tells the browser how long the page remains fresh before it expires and a new request is made to refresh the page.
  
    * But what happens when you have changed the file and want all of your users to get the new one instead of the one they have stored in their cache? 
        * The new version has the same name as the old version, so it will continue to reload the old version.
    * We need a way to change the filename when the contents change, so that the browser can render the new stuff.
### FINGERPRINTING
* is a technique that makes the name of a file dependent on the contents of a file (so when the the content
  changes, the filename is also changed). 
    * CACHE BUSTING occurs when clients request a new copy of the content when the fingerprint is updated.
* Fingerprinting is enabled by default for production and disabled for all other environments, you can change this in the:
```ruby
config.assests.digest option
```
### JAVASCRIPT MANIFEST FILES
* Your javascript manifest file == `app/assets/javascripts/application.js`
* Each line starts with `//= ` which tells sprockets that this is not a normal JS comment
* `//= require ` is called a **directive** and it tells sprockets that this file should be loaded
* IT DOES NOT REQUIRE THE .js EXTENSTION, IT KNOWS WHAT FILE THIS IS! 
    * EX) a `main.js` file can be referenced as `//= require main`
* the `//= require_tree` directive tells sprockets to load all the files in the given folder where application.js resides in
    * If you decide to keep this directive, you should know that it **loads all the files in alphabetical order**
* You can remove this directive BUT you will have to list each file in the desired order
* REMEMBER: the asset path for a file in the javascripts folder is just require filename, if your file is located in another folder within the javascripts folder, you must specify the path: require folder_name/.../file_name
* YOU HAVE TO INCLUDE THIS LINE IN YOUR LAYOUT FILE (application.html.erb)
```ruby
  <%= javascript_include_tag "application" %>
```
* Sprockets will then take care of loading each asset
* As our project expands, using a single file for all our JS can be troublesome as it can be harder to find things.
* It is better to organize our js into different files based on their functionailty:
    * **Page Specific JS**: JS that pertains to a resource specific to a page
        * ex) `app/assets/javascripts/blog.js.coffee` (Coffeescript is the default way to create JS for Rails) 
        * in the manifest file: `//= require blog `
    * **Controller Specific JS**: When the browser loads our JS, if the file is large, it may contain code that may influence other behaviors we didn't intend to have. 
        * To allow JS files to be loaded with the pages we want, is to use the name of the controller: 
        * ex) `<%= javascript_include_tag params[:controller] %>`
        * A request made to `blogs#index` will produce the following `params: { controller: 'blogs', action: 'index' }` and including the js_include_tag in the head or below the body of the layout will load the JS files that matches the name of the controller, and you DO NOT HAVE TO INCLUDE this file in the manifest file!!
        * DOWNSIDE TO THIS: No more benefits of asset concatenation or caching. Separate requests will be made for this file and the manifest file.
    * **Class Based Targeting**: A more elegant solution is to wrap all your pages in a div with a specific class:

```erb
# app/views/layouts/application.html.erb
<body class="<%= controller_name %> <%= action_name %>"> </body>

<body class="pages contact" %> </body>
    PagesController with an action called contact
      You can then write some JS:
      $(".pages.contact")...
```
### Loading JS Into Rails App
* HTML script tags for files located on another server
    * ex) Loading JS from a CDN: `<script src="https://..." />`
* Place 3rd party JS files into vendor folder
    * After adding multiple JS libraries to our app, pages will begin to load slowly.
    * You don't want to clutter the assets/javascript folder with JS written by other people,
    * Rails provides a way to place these files: vendor/assets/javascripts
    * We can place third party files and libraries in here and also add them to our JS manifest file
* Use gems to load JS libraries
    * Easier to keep track of newer versions of JS libraries
    * These gems package the JS files, when installed, adds them to our asset path allowing us to require the JS inside of the manifest file
    * ex) adding `gem jquery`, then run `bundle install`, and then add ` //= require jquery `.
        * jQueury is now loaded into Rails
  
### CSS MANIFEST
* Similar to our JS files, CSS files can also become quickly difficult to manage once we have many files.
* The **application.css** is THE CSS MANIFEST FILE 
* To require a file to be used in the manifest file, use the syntax:

```css
  /*
   *= require name_of_file
   */
```
* Keep in mind that if you add more folders within app/assets/stylesheets, you must provide the appropriate path when requiring the file to be loaded in the manifest file
    * ex) `*= require blogs/main` is a file located in `app/assets/stylesheets/blogs/main.css`
* Again, same setup, load the manifest css file in the application layout file

```erb
<%= stylesheet_link_tag 'application' %>
```

* In development mode, each CSS file will get its own link tag, while in production mode, sprockets will take all the files and create one large CSS file
    * ex) `<link rel="stylesheet" href="/assets/application-3478376473898743843.css />`
    * Notice the long number, that is fingerprinting at work!
### LOADING STYLESHEETS IN RAILS
* You can load css files through your asset directory, or:
    * External stylesheets: which are placed in link tags within the head of the application file.
    * Vendor assets: You can place 3rd party css files that are managed by other users in the vendor folder and then add them to the manifest file
    * GEMS!!!: add the gem to the Gemfile, run bundle install and then add the required gem to the manifest file
* WHY PREPROCESSORS?
    * They are able to convert our different syntaxes of css and js into proper css and js that is compatible for all browsers reading our code!
### IMAGES IN THE AP
* images will placed in app/assets/images (this path is by default, already included in the assets path)
* If you need to add more paths to the assets path:
```
  Rails.application.assets.paths << 
```
* The cool thing about this is that you can access all your image files using one URL: `/assets`
    * ex) `/assets/logo.png`, Rails will look into all the paths in the assets path for this file
* Head in to `rails c`:
    * `Rails.application.assets.path `
    * hit enter and then you will see an array the paths that Rails considers to be asset paths
* the asset_path helper
    * provides a way for us to get a relative path to an image file
    * ex) `asset_path('logo.png')`
    * Rails will look in `/assets/logo.png`
        * if there is a sub directory within the images directory, ex. `banner/logo.png`, you will need to be more specific:
            * `asset_path('banner/logo.png')`
    * Using this helper in our **css.erb** files:
    * ex) `background-image: url(<%= asset_path('logo') %>);`
  
    * If instead you need to generate an HTML image tag for the image, use the image_tag helper:
    * `<%= image_tag "logo.png" %> which creates <img src="/assets/logo.png" />`
    * In your .css files, you can use url("logo.png"), if the image is located in `app/assets/images/logo.png` 
### INTEGRATING BOOTSTRAP INTO RAILS USING THE AP:
* gem `bootstrap-sass`
* `bundle install`
* In the css manifest file: 
```css
@import "bootstrap-sprockets";
@import "bootstrap";
```
* In the js manifest file: `//= require bootstrap-sprockets`
* `bundle update`

---

## Rails 4 Asset Pipeline
## Stylesheet link tag
* html link that references your `application.css` manifest!

```html
<link href="/assets/stylesheets/application.css" rel="stylesheet" type="text/css" medial="all" />

<!--Rails provides a helper-->
<%= stylesheet_link_tag('application') %>

<!--You'll need to provide the option for media, default is screen-->
<%= stylesheet_link_tag('application', :media => 'all') %>
```

* this LOC gets added to your `layout/application.html.erb` file, within the html `<head>` element!

---

## Javascript link tag
* html link that references your `application.js` manifest file!

```html
<script src="assets/javascripts/application.js" type="text/javascript"></script>

<!--Rails helper-->
<%= javascript_include_tag('application') %>

<!--Need a simple string of js code in your VIEW TEMPLATES?-->
<%= javascript_tag("alert('Are you sure?');") %>

<!--OR, need multiple lines of js?-->
<%= javascript_tag do %>
  alert("Are you sure?");
<% end %>

<!--Attach an 'onclick' event to a link_to-->
<%= link_to("Link", "#", :onclick => "alert('hi'); return true;") %>
```

* Add the `include_tag` within the `<head>` element of `layouts/application.html.erb`!

---

## Image in the Asset Pipleline
* using an image that is located in the path of the asset pipleline:

```html
<image src='/assets/logo.png' />

<!--can also be written using rails helper-->
<%= image_tag('logo.png') %>

<!--specify size and alt (recommended) as follows-->
<%= image_tag('logo.png', :size => '11x11', :alt => 'image') %>
<!--could have also used height and width-->
```

以上是关于markdown 资产管道的主要内容,如果未能解决你的问题,请参考以下文章

Rails 3:资产管道+许多布局

资产管道中不存在资产“logo.png”

Rails 资产管道挂起

Rails 5 - 如何在资产管道中包含所有供应商资产?

带有资产管道的背景图像

Rails 3.1 资产管道供应商/资产文件夹组织