webpackとBabelの役割を混同していた

[webpack 4 入門](https://qiita.com/soarflat/items/28bf799f7e0335b68186)の「ローダー」まで進んで気づいたことです。
色々いじったことや調べたことをそのままメモしていきます。

# webpack, Babelを使用しないとどうなるか

```html:public/index.html
...
<script src="../src/js/app.js"></script>
...
```

他のコードはそのままで、バンドルしたファイルではなく、バンドルされる前の ``src/js/app.js`` を直接指定します。
すると、``index.html``を表示しようとしても、下記のエラーでブラウザに表示できません。

```
Uncaught SyntaxError: Cannot use import statement outside a module
```

これは、下記のようにしてHTML にモジュールを適用することで解決できます。
https://developer.mozilla.org/ja/docs/Web/JavaScript/Guide/Modules

```html:public/index.html
...
<script type="module" src="../src/js/app.js"></script>
...
```

しかし、下記のエラーが発生します。

```
Access to script at 'file:///Users/tagawahirotaka/Desktop/webpack-tutorial/src/js/app.js' from origin 'null' has been blocked by CORS policy: Cross origin requests are only supported for protocol schemes: http, data, chrome, chrome-extension, https.
```

これは、 ブラウザに表示している

```
file:///Users/tagawahirotaka/Desktop/webpack-tutorial/public/index.html
```
と、呼び出し元である

```
file:///Users/tagawahirotaka/Desktop/webpack-tutorial/src/js/app.js
```

が同一オリジンポリシーの制限に引っかかっているからです。
https://developer.mozilla.org/ja/docs/Web/Security/Same-origin_policy
https://developer.mozilla.org/ja/docs/Archive/Misc_top_level/Same-origin_policy_for_file:_URIs


webpackを使用すると、指定されたファイル(``src/js/app.js``)を起点として、そこからimport文を頼りに芋づる式にファイルを繋げてゆき、一つにまとめたJavaScriptファイル(``public/js/bundle.js``)を出力します。
そのファイルではimport文が使われていないため、

```
Uncaught SyntaxError: Cannot use import statement outside a module
```
このエラーが起きずに内容が表示されるのです。


# webpackを使用してBabelを使用しないとどうなるか

結論から言うと、自分の環境(Chrome)では、使用しなくても全く問題はありませんでした。
先ほど、webpackはimport文を頼りに芋づる式にファイルを繋げてゆくという解説をしましたが、一つ疑問がありました。
``import``はES6の記法のはずなのにBabelなしでなぜ動くんだろう、という疑問です。
https://www.ecma-international.org/ecma-262/6.0/#sec-imports

それは、webpackは、``import``の依存関係も解決してくれるからです。
https://webpack.js.org/concepts/modules/
>In contrast to Node.js modules, webpack modules can express their dependencies in a variety of ways. A few examples are:
・An ES2015 import statement
・A CommonJS require() statement
・An AMD define and require statement
・An @import statement inside of a css/sass/less file.
・An image url in a stylesheet url(...) or HTML <img src=...> file.

つまり、babelで``import``を``require``に書き換えるまでもないということです。
https://babeljs.io/repl#?browsers=defaults%2C%20not%20ie%2011%2C%20not%20ie_mob%2011&build=&builtIns=false&spec=false&loose=false&code_lz=JYWwDg9gTgLgBACwgcwKZwGZQiOByAOgHok0CArAZzyA&debug=false&forceAllTransforms=false&shippedProposals=false&circleciRepo=&evaluate=false&fileSize=false&timeTravel=false&sourceType=module&lineWrap=true&presets=env%2Creact%2Cstage-2%2Cenv&prettier=false&targets=&version=7.10.4&externalPlugins=


また、以下のようにEC6の記法のアロー関数に書き換えても、動きます。

```js:src/js/modules/addition-calculator.js
const additionCalculator = (number1 ,number2) => {
    return number1 + number2;
}

export default additionCalculator
```

これは、ChromeがES6の記法のアロー関数に対応しているからです。
https://developer.mozilla.org/ja/docs/Web/JavaScript/Reference/Functions/Arrow_functions

# まとめ

webpackとBabelが同時に取り上げられることが多く、それぞれが何をしているのかは曖昧でしたが、今回きちんとまとめられて良かったです。

- webpackは散らばっているmoduleを一つのファイルにまとめてくれる
- BabelはEC6の記法をそれより前の記法に書き換えてくれるが、``import``はwebpackが対応してるし、ChromeもEC6に対応しているので、恩恵を感じることはIE対応を強いられない限りほとんどない