You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Copy file name to clipboardExpand all lines: _posts/2021-04-18-Babel-01.md
+276Lines changed: 276 additions & 0 deletions
Original file line number
Diff line number
Diff line change
@@ -216,3 +216,279 @@ module.exports = {
216
216
}
217
217
```
218
218
219
+
커맨드라인에서 사용한 block-scoping, arrow-functions 플러그인을 설정 파일로 옮겼는데 plugins 배열에 추가하는 방식이다. strict-mode 플러그인을 마지막 줄에 추가 하였다.
220
+
221
+
다시 빌드 해보자
222
+
223
+
```bash
224
+
npx babel app.js
225
+
"use strict";
226
+
227
+
var alert = function(msg) {
228
+
return window.alert(msg);
229
+
};
230
+
```
231
+
232
+
상단에 "use strict" 구문이 추가되어 엄격모드가 활성화 되었다. 이제야 비로소 인터넷 익스플로러에서ㅗ 안전하게 동작하는 코드로 트랜스파일 하였다.
233
+
234
+
이처럼 변환을 위한 플러그인 목록은 공식 문서의 [Plugins](https://babeljs.io/docs/en/plugins)에서 확인 가능하다.
235
+
236
+
237
+
238
+
### 프리셋
239
+
240
+
ECMAScript2015+으로 코딩할 때 필요한 플러그인을 일일이 설정하는 일은 무척 오래된 일이다. 코드 한 줄 작성하는데도 세 개 플러그인 셋팅을 했으니 말이다. 여기 목적에 맞게 플러그인을 모아둔 것이 있다 그것이 바로 "**프리셋**"!
241
+
242
+
#### 커스텀 프리셋
243
+
244
+
우선 위에서 사용한 세 개 플러그인을 하나의 프리셋으로 만들어 보자. mypreset.js 파일을 다음과 같이 작성하자.
245
+
246
+
- mypreset.js
247
+
248
+
```javascript
249
+
module.exports=functionmypreset() {
250
+
return {
251
+
plugins: [
252
+
"@babel/plugin-transform-arrow-functions",
253
+
"@babel/plugin-transform-block-scoping",
254
+
"@babel/plugin-transform-strict-mode",
255
+
]
256
+
}
257
+
}
258
+
```
259
+
260
+
plugins 배열에 사용한 세 개 플러그인을 담았다.
261
+
262
+
프리셋을 사용하기 위해 바벨 설정을 바꾸자
263
+
264
+
- babel.config.js
265
+
266
+
```javascript
267
+
module.exports= {
268
+
presets: ["./mypreset.js"],
269
+
}
270
+
```
271
+
272
+
**babel.config.js**에 `plugins`배열을 제거하고 `presets`에 방금 만든 **mypreset.js**를 추가하였다. 실행을 해보면 plugins와 동일한 결과를 출력할 것이다.
273
+
274
+
#### 프리셋 사용하기
275
+
276
+
이처럼 바벨은 목적에 따라 몇 가지 <u>프리셋</u>을 제공한다.
277
+
278
+
- preset-env
279
+
- preset-flow
280
+
- preset-react
281
+
- preset-typescript
282
+
283
+
preset-env는 ECMAScript2015+를 변환할 때 사용된다. 바벨 7 이전 버전에는 연도별로 각 프리셋을 제공 하였지만(babel-reset-es2015, babel-reset-es2016, babel-reset-es2017, babel-reset-latest) 지금은 env 하나로 합쳐졌다.
284
+
285
+
preset-flow, preset-react, preset-typescript는 flow, react, typescript를 변환시키기 위한 프리셋이다.
286
+
287
+
인터넷 익스플로러 지원을 위해 env 프리셋을 사용해보자. 먼저 패키지를 다운로드 한다.
288
+
289
+
```bash
290
+
npm i -D @babel/preset-env
291
+
```
292
+
293
+
**babel.config.js**의 `presets`값을 바꾸자.
294
+
295
+
- babel.config.js
296
+
297
+
```bash
298
+
module.exports = {
299
+
presets: ["@babel/preset-env"],
300
+
}
301
+
```
302
+
303
+
그리고 빌드를하면
304
+
305
+
```bash
306
+
npx babel app.js
307
+
"use strict";
308
+
309
+
var alert = functionalert(msg) {
310
+
return window.alert(msg);
311
+
};
312
+
```
313
+
314
+
우리가 만든 mypreset.js와 같은 결과를 출력한다.
315
+
316
+
317
+
318
+
### env 프리셋 설정과 폴리필(polyfill)
319
+
320
+
과거에 제공했던 연도별 프리셋을 사용해 본 경험이 있다면 까다롭고 헷갈리는 설정 때문에 애를 먹었을지도 모르겠다. 그에 비해 env 프리셋은 무척 단순하고 직관적인 사용법을 제공한다.
321
+
322
+
#### 타겟 브라우저
323
+
324
+
우리 코드가 크롬 최신 버전(2021년 4월 기준)만 지원한다 하자. 그렇다면 인터넷 익스플로러를 위한 코드 변환은 불필요하다. target 옵션에 브라우저, 버전명만 지정하면 env 프리셋은 이에 맞는 플러그인들을 찾아 최적의 코드를 출력해 낸다.
325
+
326
+
- babel.config.js
327
+
328
+
```javascript
329
+
module.exports= {
330
+
presets: [
331
+
[
332
+
"@babel/preset-env",
333
+
{
334
+
targets: {
335
+
chrome:"90",
336
+
},
337
+
},
338
+
],
339
+
],
340
+
}
341
+
```
342
+
343
+
```bash
344
+
npx babel app.js
345
+
"use strict";
346
+
347
+
const alert = msg => window.alert(msg);
348
+
```
349
+
350
+
크롬은 블록 스코핑과 화살표 함수를 지원하기 때문에 코드를 변환하지 않고 이러한 결과물을 만들어냈다.
351
+
만약 인터넷 익스플로러도 지원해야 한다면 바벨 설정에 브라우저 정보 하나 더 추가하면 된다.
352
+
353
+
- babel.config.js
354
+
355
+
```
356
+
module.exports = {
357
+
presets: [
358
+
[
359
+
"@babel/preset-env",
360
+
{
361
+
targets: {
362
+
chrome: "90",
363
+
ie: "11", // ie 11까지 지원하는 코드를 만든다
364
+
},
365
+
},
366
+
],
367
+
],
368
+
}
369
+
```
370
+
371
+
인터넷 익스플로러에 대응하는 코드로 변환 된다.
372
+
373
+
#### 폴리필(polyfill)
374
+
375
+
이번엔 변환과 조금 다른 폴리필(polyfill)에 대해 알아보자
376
+
377
+
Polyfill : 직역하면 충전솜이라는 의미가 된다. → 솜이 꺼졋을때 메꿔주는 역활을 한다.
378
+
379
+
ECMAScript2015의 Promise 객체를 사용한 코드이다.
380
+
381
+
- app.js
382
+
383
+
```javascript
384
+
newPromise()
385
+
```
386
+
387
+
바벨로 처리하면 어떤 결과가 나올까?
388
+
389
+
```bash
390
+
npx babel app.js
391
+
"use strict";
392
+
393
+
new Promise();
394
+
```
395
+
396
+
env 프리셋으로 변환을 시도했지만 Promise는 그대로 변함이 없다. target에 ie 11을 설정하고 빌드한 것인데 인터넷 익스플로러는 여전히 프러미스를 해석하지 못하고 에러를 던진다.
397
+
398
+
브라우저는 현재 스코프부터 시작해 전역까지 Promise라는 이름을 찾으려고 시도할 것이다. 그러나 스코프 어디에도 Promise란 이름이 없기 때문에 레퍼런스 에러를 발생하고 프로그램이 죽은 것이다.
399
+
400
+
플러그인이 프러미스를 ECMAScript5 버전으로 변환할 것으로 기대했는데 예상과 다르다. 바벨은 ECMAScript2015+를 ECMAScript5 버전으로 변환할 수 있는 것만 빌드한다. 그렇지 못한 것들은 폴리필(polyfill)이라고 부르는 코드조각을 추가해서 해결한다.
401
+
402
+
가령 ECMAScript2015의 블록 스코핑은 ECMAScript5의 함수 스코핑으로 대체할 수 있다. 화살표 함수 또한 일반 함수로 대체할 수 있다. 이런 것들은 바벨이 변환해서 ECMAScript5 버전으로 결과물을 만든다.
403
+
404
+
한편 프러미스는 ECMAScript5 버전으로 대체할 수 없다. 다만 ECMAScript5 버전으로 구현할 수는 있다.(참고: [core-js promise](https://github.com/zloirock/core-js/blob/master/packages/core-js/modules/es.promise.js)).
405
+
406
+
env 프리셋은 폴리필을 지정할 수 있는 옵션을 제공한다.
407
+
408
+
- babel.config.js
409
+
410
+
```javascript
411
+
module.exports= {
412
+
presets: [
413
+
[
414
+
"@babel/preset-env",
415
+
{
416
+
useBuiltIns:"usage", // 폴리필 사용 방식 지정
417
+
corejs: {
418
+
// 폴리필 버전 지정
419
+
version:2,
420
+
},
421
+
},
422
+
],
423
+
],
424
+
}
425
+
```
426
+
427
+
`useBuiltIns`는 어떤 방식으로 폴리필을 사용할지 설정하는 옵션이다. `usage`, `entry`, `false` 세가지 값을 사용하는데 기본값이 `false` 이므로 폴리필이 동작하지 않았던 것이다. 반면 `usage`나 `entry`를 설정하면 폴리필 패키지 중 core-js를 모듈로 가져온다(이전에 사용하던 babel/polyfill은 바벨 7.4.0부터 사용하지 않음).
428
+
429
+
core-js 모듈의 버전도 명시하는데 기본값은 2다. 버전 3과 차이는 확실히 잘 모르겠다. 이럴 땐 그냥 기본값을 사용하는 편이 좋다.
430
+
431
+
자세한 폴리필 옵션은 바벨 문서의 [useBuiltIns](https://babeljs.io/docs/en/babel-preset-env#usebuiltins)와 [corejs](https://babeljs.io/docs/en/babel-preset-env#corejs) 섹션을 참고하자.
Core-js 패키지로부터 프러미스 모듈을 가져오는 임포트 구문이 상단에 추가되었다. 이제야 비로소 인터넷 익스플로러에서 안전하게 돌아가는 결과물을 만들었다.!!
447
+
448
+
449
+
450
+
### 웹팩으로 통합
451
+
452
+
실무 환경에서는 바벨을 직접 사용하는 것보다는 웹팩으로 통합해서 사용하는 것이 일반적이다. 로더 형태로 제공하는데 **babel-loader**이 그것이다.
453
+
454
+
먼저 패키지를 설치하자.
455
+
456
+
```bash
457
+
npm i -D babel-loader
458
+
```
459
+
460
+
웹팩 설정에 로더를 추가한다.
461
+
462
+
- webpack.config.js
463
+
464
+
```javascript
465
+
module.exports= {
466
+
module: {
467
+
rules: [
468
+
{
469
+
test:/\.js$/,
470
+
exclude:/node_modules/,
471
+
loader:"babel-loader", // 바벨 로더를 추가한다
472
+
},
473
+
],
474
+
},
475
+
}
476
+
```
477
+
478
+
.js 확장자로 끝나는 파일은 babel-loader가 처리하도록 설정했다. 사용하는 써드파티 라이브러리가 많을 수록 바벨 로더가 느리게 동작할 수 있는데 node_modules 폴더를 로더가 처리하지 않도록 예외 처리를 했다. ([참고](https://github.com/babel/babel-loader#babel-loader-is-slow))
479
+
480
+
폴리필 사용 설정을 했다면 core-js도 설치해야한다. 웹팩은 바벨 로더가 만든 아래 코드를 만나면 core-js를 찾을 것이기 때문이다.
0 commit comments