Webpackのexternalsを一部試してみた


## 結論

外部依存させる場合はこう書く。

```webpack.config.jsのexternals
externals: [
  {
    _: true,
    jQuery: true
  }
]
```

### 注意！！！！！
[公式](https://webpack.github.io/docs/configuration.html#externals)のサンプルにある `a` と `b` しか試してません。

## 公式のexternalsの説明

エントリーポイントとなるファイルが複数欲しいので、ライブラリ系のファイルを外部依存としたかった（前に外部依存にせずにやった事があるが、ビルドするのがめちゃくちゃ遅かった）。
externalsに指定すれば良さそうだったので[公式](https://webpack.github.io/docs/configuration.html#externals)を確認。

```js:公式に書いてあるeternalsの指定例
{
    output: { libraryTarget: "commonjs" },
    externals: [
        {
            a: false, // a is not external
            b: true, // b is external (require("b"))
            "./c": "c", // "./c" is external (require("c"))
            "./d": "var d" // "./d" is external (d)
        },
        // Every non-relative module is external
        // abc -> require("abc")
        /^[a-z\-0-9]+$/,
        function(context, request, callback) {
            // Every module prefixed with "global-" becomes external
            // "global-abc" -> abc
            if(/^global-/.test(request))
                return callback(null, "var " + request.substr(7));
            callback();
        },
        "./e" // "./e" is external (require("./e"))
    ]
}
```

よく分からん...

## 環境とか設定とか

### package.json

```json:package.json
{
  "name": "lifegame",
  "version": "1.0.0",
  "description": "ライフゲームを書いてみる",
  "main": "index.js",
  "scripts": {
    "test": "echo \"Error: no test specified\" && exit 1"
  },
  "repository": {
    "type": "git",
    "url": "git+https://github.com/youkaiantena/lifegame.git"
  },
  "author": "",
  "license": "ISC",
  "bugs": {
    "url": "https://github.com/youkaiantena/lifegame/issues"
  },
  "homepage": "https://github.com/youkaiantena/lifegame#readme",
  "devDependencies": {
    "babel-core": "^6.7.4",
    "babel-loader": "^6.2.4",
    "babel-preset-es2015": "^6.6.0",
    "gulp": "^3.9.1",
    "gulp-babel": "^6.1.2",
    "gulp-webpack": "^1.5.0",
    "lodash": "^4.8.2",
    "webpack": "^1.12.14",
    "webpack-stream": "^3.1.0"
  }
}
```

### gulpfile.babel.js

```javascript:gulpfile.babel.js
'use strict'

import gulp from 'gulp'
import webpack from 'webpack-stream'
import config from './webpack.config.js'

gulp.task('build', () => {
  return gulp.src('')
    .pipe(webpack(config()))
    .pipe(gulp.dest('./dest'))
})
```

### webpack.config.js

```
const exports = () => {
  return {
    cache: true,
    entry: {
      'test': './src/test.js'
    },
    output: {
      filename: "[name]/app.js"
    },
    resolve: {
      extensions: ['', '.js']
    },
    module: {
      loaders: [
        {
          test: /\.js$/,
          exclude: /node_modules/,
          loader: 'babel',
          query: {
            presets: ['es2015']
          }
        }
      ]
    },
    externals: {
    }
  }
}

export default exports
```

### src/test.js

```javascript:src/test.js
// ここでimportとかやってみる
```

### dest/test/app.js

ビルドされたらこの名前で吐き出される様にしてある

### test.html

```html:test.html
<!DOCTYPE html>
<html>
  <head>
    <meta charset="utf-8">
    <title>lifegametest</title>
  </head>
  <body>
    <!-- 外部依存のファイルはここで読み込むよ -->
    <script src="./dest/test/app.js"></script>
  </body>
</html>
```

## いざ実践

lodashで試す

```javascript:src/test.js
import _ from 'lodash'
console.log(_.isUndefined)
```

### a: false, // a is not external

#### lodashって指定してみる

```webpack.config.jsのexternals
externals: [
  {
    lodash: false
  }
]
```

##### 結果

- ビルド通った
- `console.log(_.isUndefined)` も問題なし

#### _って指定してみる

```webpack.config.jsのexternals
externals: [
  {
    _: false
  }
]
```

##### 結果

- ビルド通った
- `console.log(_.isUndefined)` も問題なし

#### 結論

外部依存させない場合、`lodash`って指定しようが`_`って指定しようが特に問題なし。
分かりやすい方で書けば良さそう。

### b: true, // b is external (require("b"))

htmlで、下記を読みこませる

`<script src="https://cdnjs.cloudflare.com/ajax/libs/lodash.js/4.8.2/lodash.min.js"></script>`

#### lodashって指定してみる

```webpack.config.jsのexternals
externals: [
  {
    lodash: true
  }
]
```

##### 結果

- ビルド通った
- `console.log(_.isUndefined)`を呼び出してる箇所で、lodashなんて知らないって叱られる。
- `app.js:67 Uncaught ReferenceError: lodash is not defined`

#### _って指定してみる

```webpack.config.jsのexternals
externals: [
  {
    _: true
  }
]
```

##### 結果

- ビルド通った
- `console.log(_.isUndefined)` も問題なし

#### 結論

外部依存させる場合、`_`って指定しないとエラー発生。
なぜなら、`lodash`なんてオブジェクトは存在しないから。

#### おまけ
`jQuery`を外部依存にする場合は `$: true`って指定すると`$`なんて知らねってエラーがビルド時に発生する。
外部依存しない場合は試してないので分かりません。