RailsでSwiperを導入する方法（Swiperは2020年7月にバージョンアップし、従来と設定方法が変わりました！）

# はじめに

この記事は、以下のような方を対象としています。

- これからRailsでSwiperを導入しようとされている方
- Swiperを導入せよという課題が与えられたけど、そもそもSwiperが何かよく分からない初学者
- 他のQiitaやブログ等の記事を見たけれどなかなか上手く設定できず、Swiperを動かすことができない方

Swiperではメジャーバージョンアップが行われ、いくつか大きな変更がありました。
その点を踏まえて、本記事で解説していこうと思います。

また、導入環境については末尾に記すので、そちらを参照してください。


## Swiperのバージョンアップについて

### Swiperのリリース情報

- 2020年7月3日にv6.0.0をリリース
- 以前のバージョンである v5.4.5 から大きく仕様が変更
- 詳細については、公式で確認できる（変更点も記載されている）
  - [GitHub：SwiperのRelease情報](https://github.com/nolimits4web/swiper/blob/master/CHANGELOG.md) 

### 変更点

***ディレクトリ構造の変更やファイル名の変更などがあり、従来どおりの設定のままだと動かなくなりました！
（煽り気味に書きましたが、NPMやYarnなどのパッケージマネージャを使って設定している場合の話です）***

詳細については、設定方法を紹介する中で併せて紹介していきます。

## Swiperとは

![84c66e482b652c5be609ffb0c3fe909d.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/429155/eff34474-4ade-fe0c-2c84-2b197c840f48.gif)

CSSとJSを適用することで、画像などをスライドできる機能を実装するものです。  

公式サイトにてどのような機能を実装できるか詳細に紹介されています。

また、ガリガリコードさんというサイトでサンプル付きで詳細に紹介されているので、
そちらをまず見てみるとイメージがつくかと思います。

> [Swiper公式サイトのデモ](https://swiperjs.com/demos/)
> [ガリガリコード](https://garigaricode.com/swiper/)

# Swiperの実装方法

投げやりなことを言うと、公式サイトにまとめられています。
イメージさえつかめれば、英語がさほど分からなくても、実装できるかと思います。

> [Swiper公式サイトで紹介されている実装方法（Getting Started With Swiper）](https://swiperjs.com/get-started/)

とはいえ、いきなり見ても分かりづらい部分があるかもしれないので、
概要について簡単にまとめてみました。

## 1. HTMLの実装

イメージだけお伝えしますが、HTMLの構造は以下のようにする必要があります。
あまりよくないような気もしますが、公式サイトからコピペしています。

```html
<!-- Slider main container -->
<div class="swiper-container">
    <!-- Additional required wrapper -->
    <div class="swiper-wrapper">
        <!-- Slides -->
        <div class="swiper-slide">Slide 1</div>
        <div class="swiper-slide">Slide 2</div>
        <div class="swiper-slide">Slide 3</div>
        ...
    </div>
    <!-- If we need pagination -->
    <div class="swiper-pagination"></div>

    <!-- If we need navigation buttons -->
    <div class="swiper-button-prev"></div>
    <div class="swiper-button-next"></div>

    <!-- If we need scrollbar -->
    <div class="swiper-scrollbar"></div>
</div>
```

なぜこのような構造にするかというと、Swiperの方で`swiper-wrapper`クラスや
`swiper-slide`クラスなどに適用するためのコードが用意されているためです。

Swiperの導入が無事終われば、該当のクラスにSwiperのCSSとJSが適用されるので、
「あら不思議！」という感じで、いい感じにスライド機能を実装してくれるという訳です。

念のため補足すると、`<!-- If we need...`と書かれているところは、
必要なければHTML上に記載する必要はありません。

## 2. CSS、JSの適用方法

公式サイトで紹介されているとおりですが、
CSS及びJSの適用方法には３種類あります。

- CDN（クラウド上に公開されているCSSとJSを適用させる）
- ファイルをダウンロードして、愚直にCSSとJSを適用させる
- NPMというJSのパッケージマネージャ（RubyでいうところのGemを管理するBundlerのようなもの）
    - Yarnという類似のパッケージマネージャーを使うことも可能です

## 2.1 CDNでの設定方法

### CDNとは

詳細については全く詳しくないため、気になる方はググっていただきたいのですが、
Content Delivery Networkの略です。

以前は、クラウド上に公開したファイルにアクセスが集中してしまうと困るので、
「各自ダウンロードして、自分が公開しているサーバーにCSSとJSをアップロードして！」
という感じでおそらくやっていました。

ただ、大量配信できる仕組みが整い、アクセスが集中しても耐えうる体制を構築できたので、
「もうクラウド上のファイルを使ってしまってかまへんで〜」となりました。
この大量配信できる仕組みが、CDNです。

誤解が多分に含まれていそうなのですが、 大枠の理解は間違ってないかと思います。。。

### 設定方法

HTMLのheadタグ内に以下のコードを貼り付ければCSSとJSが適用できるかと思います。
公式サイトにバッチリ書いてあるので、そちらを参照してください。

> [Swiper公式サイトで紹介されている実装方法（Getting Started With Swiper）](https://swiperjs.com/get-started/)

```html:application.htmlなどに適用
<!-- Swiperの全ての機能を使いたい方はこちらを使用 -->
<link rel="stylesheet" href="https://unpkg.com/swiper/swiper-bundle.css">
<script src="https://unpkg.com/swiper/swiper-bundle.js"></script>

<!-- 最小限の機能で構わない！ CSSやJSのファイルが小さい方がいい！ という方はこちらを使用 -->
<!-- 最小限の機能が何かは調べられていないので、公式を参照するなり、通常版と比較考慮するなどしてみてください -->
<link rel="stylesheet" href="https://unpkg.com/swiper/swiper-bundle.min.css">
<script src="https://unpkg.com/swiper/swiper-bundle.min.js"></script>
```

```slim:application.html.slimなどに適用
/Swiperの全ての機能を使いたい方はこちらを使用
= stylesheet_link_tag "https://unpkg.com/swiper/swiper-bundle.css"
= javascript_include_tag "https://unpkg.com/swiper/swiper-bundle.min.css"

/最小限の機能で構わない！ CSSやJSのファイルが小さい方がいい！ という方はこちらを使用
/最小限の機能が何かまでは調べられていないので、公式を参照するなり、通常版と比較考慮するなどしてみてください
= stylesheet_link_tag "https://unpkg.com/swiper/swiper-bundle.min.css"
= javascript_include_tag "https://unpkg.com/swiper/swiper-bundle.min.js"
```

Swiperだから特別なことをしているという訳ではないので、
CSSやJSの適用方法の基本について調べれば、すぐ理解できるかと思います。

なお、その他のQiita記事等を参考にする場合、注意が必要です。

参照しているSwiperのバージョンが古いものである可能性が高いので、
その旨を踏まえて作業を進めてください。

## 2.2 ファイルをダウンロードして、愚直にCSSとJSを適用させる方法

ここでは触れません！
おそらくあえて選択する方はいないかと思いますし。

「CSSとJSをダウンロードして、HTMLに適用してあげればスライダー実装できるよ！」
という当たり前の話です。

それをローカルのファイルでやるか、クラウドのファイルでやるかだけの違いです。

## 2.3 NPMもしくはYarnで設定する方法

ここではYarnを使った設定方法について取り上げます。

NPMについても基本的には同じような考え方になるかと思いますし、
公式サイトで設定方法について紹介されているので、そちらを参照してください。

- [Swiper公式サイトで紹介されている実装方法（Getting Started With Swiper）](https://swiperjs.com/get-started/)

### Yarnの導入からCSS・JSの適用まで

既によくまとめられたQiita記事があるので、まずはそちらを参照ください。
Yarnとは何かということについても触れています。

> [swiperをyarnで導入して、画像をスライダー形式にする！ \- Qiita](https://qiita.com/kenkentarou/items/bdf04d8ecab6a855e50f)

### 注意点1（ディレクトリ構造やファイル名が変更しました）

先ほどの記事について、一点だけ注意していただきたいことがあります。

***それは、node_modulesディレクトリ配下に作成されるswiperというフォルダ内に
インストールされるファイルやディレクトリ構成が変更されたため、
このQiita記事のとおり設定をしても上手くいかないということです。***

なので、導入したファイルの読み込み設定は以下のとおり行いましょう。

```js:【Ver6】assets/javascript/application.js
//= require swiper/swiper-bundle.js
//= require swiper.js

# ちなみに、この順番を間違えると上手く動かないらしいです
```

```scss:【Ver６】assets/stylesheets/application.scss
@import 'swiper/swiper-bundle';
```

参考までに、Swiper（Ver5）の場合の設定について以下に掲載します。
参照ファイルが変更されていことが分かるかと思います。

```js:【Ver5】assets/javascript/application.js
//= require swiper/js/swiper.js
//= require swiper.js
```

```scss:【Ver5】assets/stylesheets/application.scss
@import 'swiper/css/swiper';
```

参考までに、nodes_modules配下のディレクトリ構造のスクリーンショットを貼っておきます。
「あー、だいぶ変わったな」ということが分かるかと思います。

|Ver6 |Ver5  |
|-----|------|
|![スクリーンショット 2020-07-06 16.15.56.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/429155/7868171b-f195-aabd-8c92-f5e66d0e57a2.png)|![スクリーンショット 2020-07-06 16.16.11.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/429155/f0a321a2-cc94-caf2-c1db-1a2b176ba50b.png)|

### 注意点２（`config/initializers/assets.rb`の設定）

なお、以上については、あくまで`config/initializers/assets.rb`を
以下のとおり設定している前提での話となります。ご注意ください。

こちらについては、先ほど紹介したQiita記事にも書かれている内容になります。

```rb:config/initializers/assets.rb
Rails.application.config.assets.paths << Rails.root.join('node_modules')
```

## 3. JSファイルの作成（先ほどのJSとは別！）

個人的にはここが分かりづらかったのですが、***CDNから持ってくるJSファイル、
もしくはYarnでインストールしてnode_modules配下に置かれるJSファイルとは別に、
新しくJSファイルを自分で作成する必要があります。***

ここで作成するJSファイルが、先ほど設定した`swiper/js/swiper.js`を参照し、
スライダー機能を各クラスに適用させるような仕組みとなっています。

作成するJSファイルですが、以下を参考にしてください。
公式に書かれているとおりです。

> [Swiper公式サイトで紹介されている実装方法（Getting Started With Swiper）](https://swiperjs.com/get-started/)

```js:app/assets/javascripts/任意の名前.js
var mySwiper = new Swiper('.swiper-container', {
  // Optional parameters
  direction: 'vertical',
  loop: true,

  // If we need pagination
  pagination: {
    el: '.swiper-pagination',
  },

  // Navigation arrows
  navigation: {
    nextEl: '.swiper-button-next',
    prevEl: '.swiper-button-prev',
  },

  // And if we need scrollbar
  scrollbar: {
    el: '.swiper-scrollbar',
  },
})
```

多くの場合、全てのコードは必要になりません。
また、逆に以上には書かれていないコードが必要となる場合もあります。

公式のデモサイトを参照し、該当のスライダー機能においてどのようなソースコードが
使用されているか確認してみるとよいでしょう。

例えば、Fraction Paginationという機能においては、以下のようなJSが使われています。

```js:FractionPaginationで使用するJS
var swiper = new Swiper('.swiper-container', {
  pagination: {
    el: '.swiper-pagination',
    type: 'fraction',
  },
  navigation: {
    nextEl: '.swiper-button-next',
    prevEl: '.swiper-button-prev',
  },
});
```

このことは、公式サイトで紹介されているデモの一覧ページから確認することができます。

> [Swiper公式サイトのデモ（Fraction Pagination）](https://swiperjs.com/demos/#fraction_pagination)
> [ソースコード（先ほどのデモサイトにリンクあり）](https://github.com/nolimits4web/Swiper/blob/master/demos/060-pagination-fraction.html)

### JSが発火するタイミングを考えよう

私の場合は以上のコードで動かなかったので、導入しているjQueryを活用して、
以下のとおり書き換えました。（JSむずかしい。。。）

```js:app/assets/javascripts/任意の名前.js
// var swiper = と始めるのではなく、$(function(){ で始める

$(function() {
    new Swiper('.swiper-container', {

        // Optional parameters
        direction: 'vertical',
        loop: true,

        pagination: {
            el: '.swiper-pagination',
        },

〜 以下省略 〜

```

よくよく調べていくと、どうやらJSのスクリプトを置く場所が悪かったようです。

私の場合、HEADタグ内にJSのスクリプトを置くように設定していたので、
BODYタグ内のDOM（HTMLの構造、どこに何クラスがあるかなど）を読み込む前に
Swiperが発動してしまい、上手くJSを適用することができなかったようです。

文章だけでは分かりづらいので、HTMLのコードを使って解説します。

```html:Swiperがなぜ読み込めないのか
<html>
<head>
    <!-- ここでSwiperのJSを読み込むとする -->
    <!-- ここでJSが発火すると、<body>タグ内にあるswiper-containerクラスなどのDOM構造をまだ検知していない -->
    <!-- SwiperのJSの適用先が分からないので、Swiperによるスライド機能は当然実装されない -->
    <!-- ここにSwiperのJSのファイルを置く場合、発火のタイミングを指定してあげる必要がある -->
    <!-- jQueryを導入していると $(function() {...}) を活用して、簡単に発火のタイミングを指定してあげることができる -->
    <!-- jQueryを導入していなくても、JSのコードを書けば発火のタイミングを指定できる -->
</head>

<body>
  <div class="swiper-container">
    <!--  Swiperの構造を示すdivタグが延々と続く -->
  </div>

  <!-- ここで発火させれば、既にswiper-containerクラスなどのDOM構造を検知した後なので、上手く作動する -->
  <script src="../package/swiper-bundle.js"></script>

  <script>
    var swiper = new Swiper('.swiper-container', {
      pagination: {
        el: '.swiper-pagination',
        〜 省略 〜
      }
    });
  </script>

</body>
</html>

```

改めてSwiperの公式デモサイトをみると、たしかにBODYタグ内の末尾に
JSのスクリプトが置かれています。

> [Swiper公式サイトのデモ（Fraction Pagination）](https://swiperjs.com/demos/#fraction_pagination)
> [ソースコード（先ほどのデモサイトにリンクあり）](https://github.com/nolimits4web/Swiper/blob/master/demos/060-pagination-fraction.html)

なお、`$(function() {...})`の話については、jQuery日本語リファレンスに書かれています。
また、以下のQiita記事などでも解説されています。

> [jQuery\(callback\) \- jQuery 日本語リファレンス](http://semooh.jp/jquery/api/core/jQuery/callback/)
> [jQueryの基本 \- $\(document\)\.ready \- Qiita](https://qiita.com/8845musign/items/88a8c693c84ba63cea1d)
> [【jQuery】$\(function\(\) \{\.\.\.\}\) について　「意味や実行されるタイミング」 \- Qiita](https://qiita.com/bakatono_super/items/fcbc828b21599568a597)

「jQueryを使いたくない！」という方は、英語ですが、以下が参考になるのではないでしょうか。
（JS周りは本当に不勉強なのでトンチンカンなことを言っているかもしれません。。。）

> [what is the $\(document\)\.ready equivalent without jQuery? \| Edureka Community](https://www.edureka.co/community/65872/what-is-the-document-ready-equivalent-without-jquery)

## 4. CSSの追加設定

こちらも公式に書いてある内容をそのまま書いているだけなのですが、
適宜Swiperのサイズなどを設定してください。

> [Swiper公式サイトで紹介されている実装方法（Getting Started With Swiper）](https://swiperjs.com/get-started/)

公式で紹介されている事例を以下に貼っておきます。

```css:application.scssなど任意のcssファイル
.swiper-container {
    width: 600px;
    height: 300px;
}
```

## 参考

本記事内で紹介した公式サイト・ブログ・Qiita記事ですが、以下のとおりです。
公式サイトをぜひ一度は見てみてください。

- [GitHub：SwiperのRelease情報](https://github.com/nolimits4web/swiper/blob/master/CHANGELOG.md) 
- [Swiper公式サイトのデモ](https://swiperjs.com/demos/)
- [Swiper公式サイトで紹介されている実装方法（Getting Started With Swiper）](https://swiperjs.com/get-started/)
- [ガリガリコード](https://garigaricode.com/swiper/)
- [swiperをyarnで導入して、画像をスライダー形式にする！ \- Qiita](https://qiita.com/kenkentarou/items/bdf04d8ecab6a855e50f)
- [jQuery\(callback\) \- jQuery 日本語リファレンス](http://semooh.jp/jquery/api/core/jQuery/callback/)
- [【jQuery】$\(function\(\) \{\.\.\.\}\) について　「意味や実行されるタイミング」 \- Qiita](https://qiita.com/bakatono_super/items/fcbc828b21599568a597)
- [what is the $\(document\)\.ready equivalent without jQuery? \| Edureka Community](https://www.edureka.co/community/65872/what-is-the-document-ready-equivalent-without-jquery)


なお、本記事では紹介していませんが、細かいカスタマイズをする場合、
以下の記事などを参照するとよいかと思います！

- [Swiperのオプションを一覧でご紹介します \| WEBコーダーBLOG](https://coder-memo.com/swiper-option/)
- [スライダープラグイン Swiper（v5）の使い方 / Web Design Leaves](https://www.webdesignleaves.com/pr/plugins/swiper_js.html)

## 導入環境

バージョンとうるさいくせに、Railsのバージョンが5系なのは見逃してください。

また、初学者であるため、不足・過剰に書きすぎている部分があるかもしれません。
とりあえず、CSS・JS周りのものをざっと書き連ねてみました。

### 全般

- MacOS X 10.15.5 （Catalina）
- ruby '2.6.4'

### Yarn関係

- swiper (6.0.0)
- bootstrap-material-design（4.1.3）
- bootstrap（4.5.0）
- dom7(3.0.0-alpha.5)
- jquery(３.5.1)
- popper.js(1.16.1)
- ssr-window(3.0.0-alpha.4)

### Gem関係

- gem 'rails' （5.2.3）
- gem 'sass-rails' （5.0）
- gem 'uglifier' (4.2.0)
- gem 'jquery-rails'(4.4.0)
- gem 'popper_js'(1.16.0)