初めてのwebpack - ライブラリ編

やっとこさwebpackを使うたる所以です。
例として、なんだかんだまだ離れられないjQueryのライブラリをwebpackでバンドルしてみます。

## jQueryのインストール
なんだかんだ離れられない点も踏まえて、まだまだ汎用的なライブラリになるかと思いますので、npmでインストールする際もローカルではなく、グローバルにインストールしようと思います。

```sh
npm i jquery
```

これだけで使用できるようになりました。

## jQueryの読み込み
読み込みには、`require`と`import`のふた通りあります。

| 読み込み方法       | 備考       |
|:-----------------|:------------------|
| require             | node.jsの機能ですが、Babelもnode.jsで動作するため、その影響で使用できます。             |
| import             | ECMAScript 2015にて採用されたJavaScriptの機能です。ただし、IEには採用されていないため、Babelにて変換が必要となります。（※下記の参考をご参照ください）             |

[> 参考 :  import - JavaScript | MDN](https://developer.mozilla.org/ja/docs/Web/JavaScript/Reference/Statements/import) 

ここではimportを使用して作業を続けます。

```js:index.js
import $ from 'jquery'
```

モジュールの読み込みは、下記で可能なのですが、

```js
import 'モジュール名'
```

jqueryの場合は、通常`$('body')`などのように、`$`を使用していたかと思います。
単純に読み込んだだけでは、そのような使い方ができないため、読み込んだ内容を`$`として使用できるようにするため、前述のような内容になっています。


## slick.jsを使ってみる
割とよく使うものとして、slick.jsがあるかと思います。（キービジュアルのスライドとか）
これも一緒にできると便利です。

### インストール
とりあえず、モジュール名を探してみます。
[github](https://github.com/kenwheeler/slick/)にありました。

> NPM
npm install slick-carousel

みたいですので、`npm install slick-carousel`を実行します。

### 読み込み
ここまででインストールできましたので、importすれば使えるようになります。

```js:index.js
import $ from 'jquery'
import 'slick-carousel'
```

ただ、これだけだと動作しないですよね。
`slick.css`と`slick-theme.css`の存在がネックです。

たださすがです。
`node_modules`の中にバッチリありました。

```sh
 ls -1 node_modules/slick-carousel/slick/
ajax-loader.gif
config.rb
fonts
slick-theme.css
slick-theme.less
slick-theme.scss
slick.css
slick.js
slick.less
slick.min.js
slick.scss
```

`jquery`や`slick-carousel`のようなモジュールは、そのモジュール名だけでパスも解決してしまうのですが、cssとなるとそうもいきませんので、entryファイルからのパスをしっかり書いてあげます。

```js:index.js
import $ from 'jquery'
import 'slick-carousel'
import '***entryファイルからのパス***/node_modules/slick-carousel/slick/slick.css'
import '***entryファイルからパス***/node_modules/slick-carousel/slick/slick-theme.css'
```

※`***entryファイルからのパス***`の部分は、ご自身の環境にあわせて書き換えてください。すみません。

### 実行
このまま実行したいところですが、実行するとエラーが発生します。
まあ当然なのですが、JSファイルからCSSファイルを参照しようとしているので、webpack当人はよくわからない状況になってます。

これを解決するため（webpackでCSSを扱えるようにするため）に、CSS用のローダーをインストールします。

### CSS用のローダーをインストール
`css-loader`というローダーをインストールします。

[前回](https://qiita.com/yarimo/items/e0dcdac1615ecadcb07a)までのwebpack.config.jsは、こういう状態なのですが、ここにルールを付け足していきます。

```js:webpack.config.js
module.exports = {
  entry : './src/js/index.js',
  module: {
    rules: [
      {
        test: /\.js$/,
        use: {
          loader: 'babel-loader',
          options: {
            presets: ['@babel/preset-env']
          }
        }
      }
    ]
  }
}
```

`rules`を増やしていきます。


```js:webpack.config.js
module.exports = {
  entry: './src/js/index.js',
  module: {
    rules: [
      {
        test: /\.js$/,
        use: {
          loader: 'babel-loader',
          options: {
            presets: ['@babel/preset-env']
          }
        }
      },
      {
        test: /\.css$/,
        use: ['css-loader']
      }
    ]
  }
}
```

そして忘れてはいけないのが、読み込みのはCSSだけでなく、そのCSS内で、フォントやgif画像も含まれています。
次に、その解決をします。

それらをJSで扱うには一旦、文字データしないといけないので、それ用のモジュールをインストールします。

### フォントや画像用のローダーをインストール
`url-loader`というローダーをインストールします。

```sh
npm i -D url-loader
```

`rules`を再度増やして設定します。

```js:webpack.config.js
module.exports = {
  entry: './src/js/index.js',
  module: {
    rules: [
      {
        test: /\.js$/,
        use: {
          loader: 'babel-loader',
          options: {
            presets: ['@babel/preset-env']
          }
        }
      },
      {
        test: /\.css$/,
        use: ['css-loader']
      },
      {
        test: /\.png|jpg|svg|gif|eot|wof|woff|ttf$/,
        use: ['url-loader']
      }
    ]
  }
}
```

抜粋すると下記のエリアですが、`|`はどれかにマッチという意味合いのため、いずれかの拡張にマッチするファイルが条件になります。

```js:webpack.config.js
{
  test: /\.png|jpg|svg|gif|eot|wof|woff|ttf$/,
  use: ['url-loader']
}
```


### style要素書き出し用のローダーをインストール
このままだとCSSはただ読み込んだだけになるので、実際にHTMLファイルにstyle要素として書き出すようにします。

必要なローダーは、`style-loader`です。
これをインストールします。

```sh
npm i -D style-loader
```

あとは、css-loaderの前に追記すれば、無事HTMLに出力されます。

```js:webpack.config.js
module.exports = {
  entry: './src/js/index.js',
  module: {
    rules: [
      {
        test: /\.js$/,
        use: {
          loader: 'babel-loader',
          options: {
            presets: ['@babel/preset-env']
          }
        }
      },
      {
        test: /\.css$/,
        use: ['style-loader', 'css-loader']
      },
      {
        test: /\.png|jpg|svg|gif|eot|wof|woff|ttf$/,
        use: ['url-loader']
      }
    ]
  }
}
```

抜粋するとこの部分です。

```js:webpack.config.js
{
  test: /\.css$/,
  use: ['style-loader', 'css-loader']
},
```

`css-loader`の前に記載したのは、このローダーの部分は、後に書いたものから順番に実行するためです。
先にCSSを読み込んだ後でないとおかしくなるので、この順序となります。


これでwebpackを実行し、出力されたJSファイルを読み込んだHTMLファイルにはもれなく、style属性も追加されjqueryやslickも動作します。