# Babel.JS

* [babel-loader](https://github.com/babel/babel-loader):  웹팩(Webpack) 지원을 위해 사용합니다.
* [@babel/core](https://babeljs.io/docs/en/babel-core):  바벨이 실제 동작하는 모듈입니다.
* [@babel/preset-env](https://babeljs.io/docs/en/babel-preset-env):  바벨의 지원 스펙을 지정합니다.

```javascript
//package.json 파일을 생성한다.
npm init -y
```

우리가 **JavaScript ES6버전 이상의 문법을 사용할것 이기때문에** \
바벨을 필수적으로 설치해야 합니다. \
공부하는 과정에서는 바벨이 필요 없습니다. \
하지만 본격적으로 개발을 시작할때는 필수입니다.!

여기서는 바벨 환경설정에 대해서 알아보겠습니다.

```javascript
// Webpack V4는 webpack-cli를 요구한다
$ npm install --save-dev webpack webpack-cli path lodash
```

### babel-loader

Webpack이 모듈을 번들링할 때 Babel을 사용하여 ES6+ 코드를 ES5 코드로 빌드하도록 \
babel-loader를 설치한다.

```javascript
// babel-loader 설치
$ npm install --save-dev babel-loader
```

이제 npm script를 변경하여 Babel 대신 Webpack을 실행하도록 수정하자. 아래와 같이 package.json 파일의 scripts를 변경한다. 완성된 package.json 파일은 아래와 같다.

### min, TreeShaking, Uglify 3가지

Webpack에서

* min파일로 압축해서 내보내기
* TreeShaking (트래시레이킹) = 사용하지 않는 변수를 지워, 메모리 사용양까지 절약한다.
* Uglify (어글리파이) = 코드를 못생기게 만든다. 이는 쉽게 알아보지 못하도록 압축하고 복잡하게 코드를 작성하는 것이다.

```javascript
npm i -D @babel/core @babel/preset-env
```

### babel-polyfill&#x20;

바벨 그 자체로는 ES2015의 새로운 객체(Promise, Map, Set 등등)과 메소드(Array.find, Object.assign 등등)을 사용할 수 없습니다. 왜냐하면 ES2015에서 처음 생긴 거라 구형 자바스크립트에는 그에 상응하는 코드가 없거든요. 그래서 babel-polyfill을 설치해야 새로운 기능을 사용할 수 있습니다.

> 단점: 의존하고 있는 코드가 너무 무겁다. 그래서 프로젝트 전체가 무거워 질수 있습니다. \
> 옛날 구형 브라우저를 꼭 지원해야 하는 프로젝트이면 설치를 하고,\
> 최신 브라우저만 지원하는 프로젝트이면 설치할 필요 없습니다.

```javascript
npm install @babel/polyfill
```

```javascript
import '@babel/polyfill';

const val = Object.assign({ a: '1' }, { a: 'b' });
export default val;
```

웹팩을 사용한다면 파일에 import '@babel/polyfil';하는 대신 웹팩 설정 파일 entry에 적어도 됩니다. \
다음과 같이요.

```javascript
// webpack.config.js
{ entry: ['@babel/polyfill', './app.js'],
```

### babel preset

다양한 babel preset들이 있는데 babel foundadtion에서 제공하는 공식 preset과 Airbnb같은 곳에서 제공하는 비공식 preset이 있다. 심지어 우리가 만들 수도 있&#xB2E4;**.**

#### 공식 preset 종류들 :&#x20;

@babel/preset-env,  @babel/preset-flow,  @babel/preset-react,  @babel/preset-typescript

> **개별 플러그인 대신 사전 설정에서 플러그인 세트를 활성화 할 수도 있습니다.**

**설정방법:** .babelrc 파일 수동으로 만들고 아래와 같이 설정을 해줘야 한다.

```javascript
// package.json

{
  "name": "vue-todo-app",
  "version": "1.0.0",
  "description": "",
  "main": "index.js",
  "scripts": {
     "prod": "webpack --mode=production",  // 배포된 코드를 min으로 압축, TreeShaking, Uglify 3가지를 동시해 한다.
     "dev": "webpack --mode=development"   // 코드를 배포한다.
  },
"author": "",
"license": "MIT",
 "devDependencies": {
    "babel-loader": "^8.0.6",
    "@babel/cli": "^7.7.0",
    "@babel/core": "^7.7.5",
    "@babel/preset-env": "^7.7.6",
    "webpack": "^4.41.2",
    "webpack-cli": "^3.3.10",
    "css-loader":"^3.2.1",
    "lodash": "^4.17.15",
    "path": "^0.12.7"
  },
"dependencies": {
    "@babel/polyfill": "^7.7.0"
  }
}
```

```javascript
// 터미널
npm install
```

### webpack.config.js

webpack.config.js은 Webpack이 실행될 때 참조하는 설정 파일이다. \
프로젝트 루트에 webpack.config.js 파일을 생성하고 아래와 같이 작성한다.

```javascript
// webpack.config.js
const path = require('path')
const VueLoaderPlugin = require('vue-loader/lib/plugin')
const HtmlWebpackPlugin = require('html-webpack-plugin')
const CopyPlugin = require('copy-webpack-plugin')
const { CleanWebpackPlugin } = require('clean-webpack-plugin')
const merge = require('webpack-merge')
require('@babel/polyfill')

module.exports = (_, opts) => {
    const config = {
        // ========= 공통되는 옵션들 =========
        resolve: { // 확장자를 생략할수 있는 옵션(기능)
            extensions: ['.js', '.css']
        },
        entry: {
            app: [
                '@babel/polyfill',
                path.join(__dirname, 'triple_JS/App.js')
            ]
        },
        module: {
            rules: [
                {
                    test: /\.js$/,
                    exclude: /node_modules/,
                    use: 'babel-loader'
                },
                {
                    test: /\.css$/,
                    use: [
                        'vue-style-loader',
                        'css-loader',
                        'postcss-loader'
                    ]
                }
            ]
        },
        plugins: [
            new VueLoaderPlugin(),
            new HtmlWebpackPlugin({
                template: path.join(__dirname, 'public/index.html')
            }),
            new CopyPlugin([
                {
                    from: 'src/imgs/',
                    to: 'imgs/'
                }
            ])
        ],
        output: {
            filename: '[name].js',
            path: path.join(__dirname, 'dist')
        }
    }
    // ========= 개발용 =========
    if (opts.mode === 'development') {
        return merge(config, {
            // 추가 개발용 옵션
            devtool: 'eval',
            devServer: {
                open: false, // 강제로 브라우저로 화면 이동을 할수 있는 옵션
                hot: true // 실시간으로 바로 화면에 수정된것이 반영된것을 뜻한다.
            }
        })
    // ========= 제품용 =========
    } else {
        return merge(config, {
            // 추가 제품용 옵션
            devtool: 'cheap-module-souce-map',
            plugins: [
                new CleanWebpackPlugin()
            ]
        })
    }
}

```

```javascript
// .babelrc

{
  "presets": [
    ["@babel/preset-env", { "targets": { "browsers": ["last 2 versions", ">= 5% in KR"] } }],
    // ["@babel/preset-stage-2", { "decoratorsLegacy": true }]
  ]
}
```

이제 Webpack을 실행하여 번들링을 실행한다. \
트랜스파일링은 Babel이 실행하고 번들링은 Webpack이 실행한다. \
아래 명령을 실행한다.

```javascript
// 터미널
$ npm run prod
```

targets 옵션을 살펴보면, 브라우저들에 대해서는 최신 두 버전(IE는 10과 11, 크롬과 파이어폭스, 사파리, 엣지는 최신 두 버전)과 한국에서 5% 이상 점유율을 차지하는 브라우저를 모두 지원하라고 설정해준 겁니다. 저렇게만 쓰면 babel이 알아서 최신 자바스크립트 코드를 지정한 targets에 맞게 호환되는 자바스크립트 코드로 바꿔줍니다. 정말 편하죠!

##

### Browserslist

[Browserslist](https://github.com/browserslist/browserslist) 참고!! 브라우저 버전 별도로 호환가능하게 할수 있는 코드 정리 사이트입니다.!!&#x20;
