ํ”„๋ก ํŠธ์—”๋“œ ๊ฐœ๋ฐœํ™˜๊ฒฝ - Babel

200912 babel icon

ํ”„๋ก ํŠธ์—”๋“œ ๊ฐœ๋ฐœํ™˜๊ฒฝ - Babel

์ •๋ณด : ๊น€์ •ํ™˜๋‹˜์˜ ํ”„๋ก ํŠธ์—”๋“œ ๊ฐœ๋ฐœํ™˜๊ฒฝ์˜ ์ดํ•ด์™€ ์‹ค์Šต์„ ๊ณต๋ถ€ํ•˜๊ณ  ์ •๋ฆฌํ•œ ๋‚ด์šฉ.
ํ•ด๋‹น ๋‚ด์šฉ์€ ๊น€์ •ํ™˜๋‹˜์˜ ๋ธ”๋กœ๊ทธ ๋‚ด์šฉ์„ ํ† ๋Œ€๋กœ ์žฌ์ž‘์„ฑ๋˜์—ˆ์œผ๋ฉฐ ๋‚ด์šฉ์„ ์ถ”๊ฐ€ํ•˜๊ฑฐ๋‚˜ ์ผ๋ถ€ ๋ณ€๊ฒฝํ–ˆ์Šต๋‹ˆ๋‹ค.

1. ๋ฐฐ๊ฒฝ ๐Ÿš€

1.1. ํฌ๋กœ์Šค ๋ธŒ๋ผ์šฐ์ง•

ECMAScript(์ดํ•˜ ES)์˜ ๋ฒ„์ „์ด ์˜ฌ๋ผ๊ฐˆ ๋•Œ๋งˆ๋‹ค ์ƒˆ๋กœ์šด ๋ฌธ๋ฒ•์ด ์ถ”๊ฐ€๋˜๋Š”๋ฐ ๊ฐ ๋ธŒ๋ผ์šฐ์ €์˜ ์ŠคํŽ™์ด ๋”ฐ๋ผ ์ง€์›์ด ๋˜๋Š” ๋ถ€๋ถ„์ด ๋‹ค๋ฅด๋‹ค.

๋ฐ”๋ฒจ์€ ์ด๋Ÿฐ ํฌ๋กœ์Šค๋ธŒ๋ผ์šฐ์ง•์˜ ๋ฌธ์ œ์ ์„ ํ•ด๊ฒฐํ•  ์ˆ˜ ์žˆ๋„๋ก ๋„์™€์ค€๋‹ค.

ES6(2015) ์ด์ƒ์œผ๋กœ ์ž‘์„ฑํ•œ ์ฝ”๋“œ๋ฅผ ๋ชจ๋“  ๋ธŒ๋ผ์šฐ์ €์—์„œ ๋™์ž‘ํ•˜๋„๋ก ํ˜ธํ™˜์„ฑ์„ ์ง€์ผœ์ค€๋‹ค.

ํƒ€์ž…์Šคํฌ๋ฆฝํŠธ, JSX์ฒ˜๋Ÿผ ๋‹ค๋ฅธ ์–ธ์–ด๋กœ ๋ถ„๋ฅ˜๋˜๋Š” ๊ฒƒ๋„ ํฌํ•จํ•œ๋‹ค.

1.2. ํŠธ๋žœ์ŠคํŒŒ์ผ๊ณผ ๋นŒ๋“œ

์ด๋ ‡๊ฒŒ ์–ธ์–ด๋กœ ์ž‘์„ฑ๋œ ์†Œ์Šค ์ฝ”๋“œ๋ฅผ ๋น„์Šทํ•œ ์ˆ˜์ค€์˜ ์ถ”์ƒํ™”๋ฅผ ๊ฐ€์ง„ ๋‹ค๋ฅธ ์–ธ์–ด๋กœ ๋ณ€ํ™˜ํ•˜๋Š” ๊ฒƒ์„ ํŠธ๋žœ์ŠคํŒŒ์ผ์ด๋ผ๊ณ  ํ‘œํ˜„ํ•œ๋‹ค.

๋ณ€ํ™˜ ์ „ํ›„์˜ ์ถ”์ƒํ™” ์ˆ˜์ค€์ด ๋‹ค๋ฅธ ๋นŒ๋“œ์™€๋Š” ๋‹ฌ๋ฆฌ ํŠธ๋žœ์ŠคํŒŒ์ผ์€ ์ถ”์ƒํ™” ์ˆ˜์ค€์„ ์œ ์ง€ํ•œ ์ƒํƒœ๋กœ ์ฝ”๋“œ๋ฅผ ๋ณ€ํ™˜ํ•œ๋‹ค.

ํƒ€์ž…์Šคํฌ๋ฆฝํŠธ โ†’ ์ž๋ฐ”์Šคํฌ๋ฆฝํŠธ, JSX โ†’ ์ž๋ฐ”์Šคํฌ๋ฆฝํŠธ์ฒ˜๋Ÿผ ํŠธ๋žœ์ŠคํŒŒ์ผ ํ›„์—๋„ ์—ฌ์ „ํžˆ ์ฝ”๋“œ๋ฅผ ์ฝ์„ ์ˆ˜ ์žˆ๋‹ค.

2. ๋ฐ”๋ฒจ์˜ ๊ธฐ๋ณธ๋™์ž‘ ๐Ÿ—ผ

๋ฐ”๋ฒจ์˜ ์ฃผ๋œ ์‚ฌ์šฉ ์šฉ๋„๋Š” ES6(2015) ์ด์ƒ์˜ ์ฝ”๋“œ๋ฅผ ์ ๋‹นํ•œ ํ•˜์œ„ ๋ฒ„์ „์œผ๋กœ ๋ฐ”๊พธ๋Š” ๊ฒƒ์ด๋‹ค.

์ด๋Š” ์ธํ„ฐ๋„ท ์ต์Šคํ”Œ๋กœ๋Ÿฌ(IE)๊ฐ€ ES5๊นŒ์ง€๋งŒ ์ง€์›ํ•˜๋Š” ๋ถ€๋ถ„์ด ํฌ๋‹ค.

๊ทธ๋Ÿผ ๋ฐ”๋ฒจ์„ ์ด์šฉํ•ด ์•„๋ž˜ ์ฝ”๋“œ๋ฅผ ์ธํ„ฐ๋„ท ์ต์Šคํ”Œ๋กœ๋Ÿฌ๊ฐ€ ์ดํ•ดํ•  ์ˆ˜ ์žˆ๋Š” ์ฝ”๋“œ๋กœ ๋ฐ”๊ฟ” ๋ณด์ž.

// ./src/app.js
const alert = (msg) => window.alert(msg);

๋จผ์ € ๋ฐ”๋ฒจ ์ตœ์‹  ๋ฒ„์ „์„ ์„ค์น˜ํ•œ๋‹ค. ํ„ฐ๋ฏธ๋„ ๋„๊ตฌ๋ฅผ ์‚ฌ์šฉํ•˜๊ธฐ ์œ„ํ•ด ์ปค๋งจ๋“œ๋ผ์ธ ๋„๊ตฌ๋„ ํ•จ๊ป˜ ์„ค์น˜ํ•˜์ž.

$ npm install -D @babel/core @babel/cli

์„ค์น˜๋ฅผ ์™„๋ฃŒ ํ›„ node_modules/.bin ํด๋”์— ์ถ”๊ฐ€๋œ ๋ฐ”๋ฒจ ๋ช…๋ น์–ด๋ฅผ ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ๋‹ค.

$ npx babel app.js
const alert = msg => window.alert(msg);

๋ฐ”๋ฒจ์€ ์„ธ ๋‹จ๊ณ„๋กœ ๋นŒ๋“œ๋ฅผ ์ง„ํ–‰ํ•œ๋‹ค.

  1. ํŒŒ์‹ฑ(Parsing)
  2. ๋ณ€ํ™˜(Transforming)
  3. ์ถœ๋ ฅ (Printing)

์ฝ”๋“œ๋ฅผ ์ฝ๊ณ  ์ถ”์ƒ ๊ตฌ๋ฌธ ํŠธ๋ฆฌ(AST)๋กœ ๋ณ€ํ™˜ํ•˜๋Š” ๋‹จ๊ณ„๋ฅผ ํŒŒ์‹ฑ์ด๋ผ๊ณ  ํ•œ๋‹ค.

์ด๊ฒƒ์€ ๋นŒ๋“œ ์ž‘์—…์„ ์ฒ˜๋ฆฌํ•˜๊ธฐ์— ์ ํ•ฉํ•œ ์ž๋ฃŒ๊ตฌ์กฐ์ธ๋ฐ ์ปดํŒŒ์ผ๋Ÿฌ ์ด๋ก ์— ์‚ฌ์šฉ๋˜๋Š” ๊ฐœ๋…์ด๋‹ค.

์ถ”์ƒ ๊ตฌ๋ฌธ ํŠธ๋ฆฌ๋ฅผ ๋ณ€๊ฒฝํ•˜๋Š” ๊ฒƒ์ด ๋ณ€ํ™˜๋‹จ๊ณ„์ด๋‹ค.

์‹ค์ œ๋กœ ์ฝ”๋“œ๋ฅผ ๋ณ€๊ฒฝํ•˜๋Š” ์ž‘์—…์„ ํ•œ๋‹ค.

๋ณ€๊ฒฝ๋œ ๊ฒฐ๊ณผ๋ฌผ์„ ์ถœ๋ ฅํ•˜๋Š” ๊ฒƒ์„ ๋งˆ์ง€๋ง‰์œผ๋กœ ๋ฐ”๋ฒจ์€ ์ž‘์—…์„ ์™„๋ฃŒํ•œ๋‹ค.

๊ทธ๋Ÿฐ๋ฐ ๊ฒฐ๊ณผ๋ฅผ ๋ณด๋ฉด ๋นŒ๋“œ ์ด์ „๊ณผ ๋ณ€ํ•œ ๊ฒŒ ํ•˜๋‚˜๋„ ์—†๋‹ค.

3. ํ”Œ๋Ÿฌ๊ทธ์ธ ๐Ÿ—๏ธ

๊ธฐ๋ณธ์ ์œผ๋กœ ๋ฐ”๋ฒจ์€ ์ฝ”๋“œ๋ฅผ ๋ฐ›์•„์„œ ์ฝ”๋“œ๋ฅผ ๋ฐ˜ํ™˜ํ•œ๋‹ค.

๋ฐ”๋ฒจ ํ•จ์ˆ˜๋ฅผ ์ •์˜ํ•œ๋‹ค๋ฉด ์ด๋Ÿฐ ๋ชจ์Šต์ด ๋  ๊ฒƒ์ด๋‹ค.

const babel = (code) => code;

๋ฐ”๋ฒจ์€ ํŒŒ์‹ฑ๊ณผ ์ถœ๋ ฅ๋งŒ ๋‹ด๋‹นํ•˜๊ณ  ๋ณ€ํ™˜ ์ž‘์—…์€ ๋‹ค๋ฅธ ๋…€์„์ด ์ฒ˜๋ฆฌํ•˜๋Š”๋ฐ ์ด๊ฒƒ์„ ํ”Œ๋Ÿฌ๊ทธ์ธ์ด๋ผ๊ณ  ๋ถ€๋ฅธ๋‹ค.

3.1. ์ปค์Šคํ…€ ํ”Œ๋Ÿฌ๊ทธ์ธ

ํ”Œ๋Ÿฌ๊ทธ์ธ์„ ์ง์ ‘ ๋งŒ๋“ค๋ฉด์„œ ๋™์ž‘์ด ์›๋ฆฌ๋ฅผ ์‚ดํŽด๋ณด์ž.

myplugin.js ํŒŒ์ผ์„ ์•„๋ž˜์ฒ˜๋Ÿผ ๋งŒ๋“ค์–ด ๋ณด์ž.

// ./myplugin.js
module.exports = function myplugin() {
  return {
    visitor: {
      Identifier(path) {
        const name = path.node.name;

        // ๋ฐ”๋ฒจ์ด ๋งŒ๋“  AST ๋…ธ๋“œ๋ฅผ ์ถœ๋ ฅํ•œ๋‹ค.
        console.log('Identifier() name:', name);

        // ๋ณ€ํ™˜์ž‘์—…: ์ฝ”๋“œ ๋ฌธ์ž์—ด์„ ์—ญ์ˆœ์œผ๋กœ ๋ณ€ํ™˜ํ•œ๋‹ค.
        path.node.name = name.split('').reverse().join('');
      },
    },
  };
};

ํ”Œ๋Ÿฌ๊ทธ์ธ ํ˜•์‹์€ visitor ๊ฐ์ฒด๋ฅผ ๊ฐ€์ง„ ํ•จ์ˆ˜๋ฅผ ๋ฐ˜ํ™˜ํ•ด์•ผ ํ•œ๋‹ค.

์ด ๊ฐ์ฒด๋Š” ๋ฐ”๋ฒจ์ด ํŒŒ์‹ฑํ•˜์—ฌ ๋งŒ๋“  ์ถ”์ƒ ๊ตฌ๋ฌธ ํŠธ๋ฆฌ(AST)์— ์ ‘๊ทผํ•  ์ˆ˜ ์žˆ๋Š” ๋ฉ”์†Œ๋“œ๋ฅผ ์ œ๊ณตํ•œ๋‹ค.

๊ทธ์ค‘ Identifier() ๋ฉ”์†Œ๋“œ์˜ ๋™์ž‘ ์›๋ฆฌ๋ฅผ ์‚ดํŽด๋ณด๋Š” ์ฝ”๋“œ๋‹ค.

ํ”Œ๋Ÿฌ๊ทธ์ธ ์‚ฌ์šฉ๋ฒ•์„ ์•Œ์•„๋ณด์ž.

$ npx babel --help

--plugins [list] A comma-separated list of plugin names.

--plugins ์˜ต์…˜์— ํ”Œ๋Ÿฌ๊ทธ์ธ์„ ์ถ”๊ฐ€ํ•˜๋ฉด ๋œ๋‹ค.

$ npx babel app.js --plugins ./myplugin.js

Identifier() name: alert
Identifier() name: msg
Identifier() name: window
Identifier() name: alert
Identifier() name: msg

const trela = gsm => wodniw.trela(gsm);

Identifier() ๋ฉ”์†Œ๋“œ๋กœ ๋“ค์–ด์˜จ ์ธ์ž path์— ์ ‘๊ทผํ•˜๋ฉด ์ฝ”๋“œ ์กฐ๊ฐ์— ์ ‘๊ทผํ•  ์ˆ˜ ์žˆ๋Š” ๊ฒƒ ๊ฐ™๋‹ค.

path.node.name์˜ ๊ฐ’์„ ๋ณ€๊ฒฝํ•˜๋Š”๋ฐ ๋ฌธ์ž๋ฅผ ๋’ค์ง‘๋Š” ์ฝ”๋“œ๋‹ค.

๊ฒฐ๊ณผ์˜ ๋งˆ์ง€๋ง‰ ์ค„์—์„œ ๋ณด๋Š” ๊ฒƒ์ฒ˜๋Ÿผ ์ด ์ฝ”๋“œ์˜ ๋ฌธ์ž์—ด ์ˆœ์„œ๊ฐ€ ์—ญ์ „๋˜์—ˆ๋‹ค.

ES6(2015)๋กœ ์ž‘์„ฑํ•œ ์ฝ”๋“œ๋ฅผ ์ธํ„ฐ๋„ท ์ต์Šคํ”Œ๋กœ๋Ÿฌ์—์„œ ๋Œ๋ฆด ์ˆ˜ ์žˆ๋„๋ก ํ•ด๋ณด์ž.

๋จผ์ € const๋ฅผ var๋กœ ๋ณ€๊ฒฝํ•˜๋Š” ํ”Œ๋Ÿฌ๊ทธ์ธ์„ ๋งŒ๋“ค์–ด ๋ณด์ž.

// ./myplugin.js
module.exports = function myplugin() {
  return {
    visitor: {
      // https://github.com/babel/babel/blob/master/packages/babel-plugin-transform-block-scoping/src/index.js#L26
      VariableDeclaration(path) {
        console.log('VariableDeclaration() kind:', path.node.kind); // const

        if (path.node.kind === 'const') {
          path.node.kind = 'var';
        }
      },
    },
  };
};

์ด๋ฒˆ์—๋Š” vistor ๊ฐ์ฒด์— VariableDeclaration() ๋ฉ”์†Œ๋“œ๋ฅผ ์ •์˜ํ–ˆ๋‹ค.

path์— ์ ‘๊ทผํ•ด ๋ณด๋ฉด ํ‚ค์›Œ๋“œ๊ฐ€ ์žกํžˆ๋Š” ๊ฑธ ์•Œ ์ˆ˜ ์žˆ๋‹ค.

path.node.kind๊ฐ€ const์ผ ๊ฒฝ์šฐ var๋กœ ๋ณ€ํ™˜ํ•˜๋Š” ์ฝ”๋“œ๋‹ค.

์ด ํ”Œ๋Ÿฌ๊ทธ์ธ์œผ๋กœ ๋‹ค์‹œ ๋นŒ๋“œํ•ด๋ณด์ž.

$ npx babel app.js --plugins ./myplugin.js

VariableDeclaration() kind: const
var alert = msg => window.alert(msg);

๋งˆ์ง€๋ง‰ ์ค„์— ๋ณด๋ฉด const๊ฐ€ var๋กœ ๋ณ€๊ฒฝ๋˜์—ˆ๋‹ค.

3.2. ํ”Œ๋Ÿฌ๊ทธ์ธ ์‚ฌ์šฉํ•˜๊ธฐ

์ด๋Ÿฌํ•œ ๊ฒฐ๊ณผ๋ฅผ ๋งŒ๋“œ๋Š” ๊ฒƒ์ด block-scoping ํ”Œ๋Ÿฌ๊ทธ์ธ์ด๋‹ค.

const, let์ฒ˜๋Ÿผ ๋ธ”๋ก ์Šค์ฝ”ํ•‘์„ ๋”ฐ๋ฅด๋Š” ์˜ˆ์•ฝ์–ด๋ฅผ var๋กœ ๋ณ€๊ฒฝํ•œ๋‹ค.

NPM ํŒจํ‚ค์ง€๋กœ ์ œ๊ณตํ•˜๋Š” ํ”Œ๋Ÿฌ๊ทธ์ธ์„ ์„ค์น˜ํ•˜๊ณ ,

$ npm install -D @babel/plugin-transform-block-scoping

์„ค์น˜ํ•œ ํ”Œ๋Ÿฌ๊ทธ์ธ์„ ์‚ฌ์šฉํ•ด๋ณด๋ฉด,

npx babel app.js --plugins @babel/plugin-transform-block-scoping

var alert = msg => window.alert(msg);

์ปค์Šคํ…€ ํ”Œ๋Ÿฌ๊ทธ์ธ๊ณผ ๊ฐ™์€ ๊ฒฐ๊ณผ๋ฅผ ๋‚˜ํƒ€๋‚ธ๋‹ค.

์ธํ„ฐ๋„ท ์ต์Šคํ”Œ๋กœ๋Ÿฌ๋Š” ํ™”์‚ดํ‘œ ํ•จ์ˆ˜๋„ ์ง€์›ํ•˜์ง€ ์•Š๋Š”๋ฐ arrow-functions ํ”Œ๋Ÿฌ๊ทธ์ธ์„ ์ด์šฉํ•ด์„œ ์ผ๋ฐ˜ ํ•จ์ˆ˜๋กœ ๋ณ€๊ฒฝํ•  ์ˆ˜ ์žˆ๋‹ค.

$ npm install -D @babel/plugin-transform-arrow-functions

$ npx babel app.js \
 --plugins @babel/plugin-transform-block-scoping \
 --plugins @babel/plugin-transform-arrow-functions

var alert = function (msg) {
return window.alert(msg);
};

ES5์—์„œ๋ถ€ํ„ฐ ์ง€์›ํ•˜๋Š” ์—„๊ฒฉ ๋ชจ๋“œ๋ฅผ ์‚ฌ์šฉํ•˜๋Š” ๊ฒƒ์ด ์•ˆ์ „ํ•˜๊ธฐ ๋•Œ๋ฌธ์— โ€œuse strictโ€ ๊ตฌ๋ฌธ์„ ์ถ”๊ฐ€ํ•ด๋ณด์ž.

strict-mode ํ”Œ๋Ÿฌ๊ทธ์ธ์„ ์‚ฌ์šฉํ•˜์ž.

$ npm install -D @babel/plugin-transform-strict-mode

๊ทธ์ „์— ์ปค๋งจ๋“œ๋ผ์ธ ๋ช…๋ น์–ด๊ฐ€ ์ ์  ๊ธธ์–ด์ง€๊ธฐ ๋•Œ๋ฌธ์— ์„ค์ • ํŒŒ์ผ๋กœ ๋ถ„๋ฆฌํ•˜๋Š” ๊ฒƒ์ด ๋‚ซ๊ฒ ๋‹ค.

์›นํŒฉ webpack.config.js๋ฅผ ๊ธฐ๋ณธ ์„ค์ •ํŒŒ์ผ๋กœ ์‚ฌ์šฉํ•˜๋“ฏ ๋ฐ”๋ฒจ๋„ babel.config.js๋ฅผ ์‚ฌ์šฉํ•œ๋‹ค.

ํ”„๋กœ์ ํŠธ ๋ฃจํŠธ์— babel.config.js ํŒŒ์ผ์„ ์•„๋ž˜์™€ ๊ฐ™์ด ์ž‘์„ฑํ•˜์ž.

// ./babel.config.js
module.exports = {
  plugins: [
    '@babel/plugin-transform-block-scoping',
    '@babel/plugin-transform-arrow-functions',
    '@babel/plugin-transform-strict-mode',
  ],
};

์ปค๋งจ๋“œ๋ผ์ธ์—์„œ ์‚ฌ์šฉํ•œ block-scoping, arrow-functions ํ”Œ๋Ÿฌ๊ทธ์ธ์„ ์„ค์ • ํŒŒ์ผ๋กœ ์˜ฎ๊ฒผ๋Š”๋ฐ plugins ๋ฐฐ์—ด์— ์ถ”๊ฐ€ํ•˜๋Š” ๋ฐฉ์‹์ด๋‹ค.

strict-mode ํ”Œ๋Ÿฌ๊ทธ์ธ์„ ๋งˆ์ง€๋ง‰ ์ค„์— ์ถ”๊ฐ€ํ–ˆ๋‹ค.

๋‹ค์‹œ ๋นŒ๋“œํ•ด๋ณด์ž.

$ npx babel app.js

"use strict";

var alert = function (msg) {
return window.alert(msg);
};

์ƒ๋‹จ์— โ€œuse strictโ€ ๊ตฌ๋ฌธ์ด ์ถ”๊ฐ€๋˜์–ด ์—„๊ฒฉ๋ชจ๋“œ๊ฐ€ ํ™œ์„ฑํ™”๋˜์—ˆ๋‹ค.

์ด์ œ์•ผ ๋น„๋กœ์†Œ ์ธํ„ฐ๋„ท ์ต์Šคํ”Œ๋กœ๋Ÿฌ์—์„œ ์•ˆ์ „ํ•˜๊ฒŒ ๋™์ž‘ํ•˜๋Š” ์ฝ”๋“œ๋กœ ํŠธ๋žœ์ŠคํŒŒ์ผํ•˜์˜€๋‹ค.

์ด์ฒ˜๋Ÿผ ๋ณ€ํ™˜์„ ์œ„ํ•œ ํ”Œ๋Ÿฌ๊ทธ์ธ ๋ชฉ๋ก์€ ๊ณต์‹ ๋ฌธ์„œ์˜ Plugins ํŽ˜์ด์ง€์—์„œ ํ™•์ธํ•  ์ˆ˜ ์žˆ๋‹ค.

4. ํ”„๋ฆฌ์…‹ ๐Ÿซ

๋ชฉ์ ์— ๋งž๊ฒŒ ์—ฌ๋Ÿฌ ๊ฐ€์ง€ ํ”Œ๋Ÿฌ๊ทธ์ธ์„ ์„ธํŠธ๋กœ ๋ชจ์•„๋†“์€ ๊ฒƒ์„ โ€œํ”„๋ฆฌ์…‹โ€์ด๋ผ๊ณ  ํ•œ๋‹ค.

4.1. ์ปค์Šคํ…€ ํ”„๋ฆฌ์…‹

์‚ฌ์šฉํ•œ ์„ธ ๊ฐœ ํ”Œ๋Ÿฌ๊ทธ์ธ์„ ํ•˜๋‚˜์˜ ํ”„๋ฆฌ์…‹์œผ๋กœ ๋งŒ๋“ค์–ด ๋ณด์ž.

mypreset.js ํŒŒ์ผ์„ ๋‹ค์Œ๊ณผ ๊ฐ™์ด ์ž‘์„ฑํ•˜์ž.

// mypreset.js
module.exports = function mypreset() {
  return {
    plugins: [
      '@babel/plugin-transform-arrow-functions',
      '@babel/plugin-transform-block-scoping',
      '@babel/plugin-transform-strict-mode',
    ],
  };
};

plugins ๋ฐฐ์—ด์— ์‚ฌ์šฉํ•œ ์„ธ ๊ฐœ ํ”Œ๋Ÿฌ๊ทธ์ธ์„ ๋‹ด์•˜๋‹ค.

ํ”„๋ฆฌ์…‹์„ ์‚ฌ์šฉํ•˜๊ธฐ ์œ„ํ•ด ๋ฐ”๋ฒจ ์„ค์ •์„ ์•ฝ๊ฐ„ ์ˆ˜์ •ํ•œ๋‹ค.

// babel.config.js
module.exports = {
  presets: ['./mypreset.js'],
};

ํ”Œ๋Ÿฌ๊ทธ์ธ ์„ธํŒ… ์ฝ”๋“œ๋ฅผ ์ œ๊ฑฐํ•˜๊ณ  presets์— ๋ฐฉ๊ธˆ ๋งŒ๋“  mypreset.js๋ฅผ ์ถ”๊ฐ€ํ–ˆ๋‹ค.

์‹คํ–‰ํ•ด๋ณด๋ฉด ๋™์ผํ•œ ๊ฒฐ๊ณผ๋ฅผ ์ถœ๋ ฅํ•  ๊ฒƒ์ด๋‹ค.

4.2. ํ”„๋ฆฌ์…‹ ์‚ฌ์šฉํ•˜๊ธฐ

์ด์ฒ˜๋Ÿผ ๋ฐ”๋ฒจ์€ ๋ชฉ์ ์— ๋”ฐ๋ผ ๋ช‡ ๊ฐ€์ง€ ํ”„๋ฆฌ์…‹์„ ์ œ๊ณตํ•œ๋‹ค.

  • preset-env
  • preset-flow
  • preset-react
  • preset-typescript

preset-env๋Š” ES6๋ฅผ ๋ณ€ํ™˜ํ•  ๋•Œ ์‚ฌ์šฉํ•œ๋‹ค.

๋ฐ”๋ฒจ 7 ์ด์ „ ๋ฒ„์ „์—๋Š” ์—ฐ๋„๋ณ„๋กœ ๊ฐ ํ”„๋ฆฌ์…‹์„ ์ œ๊ณตํ–ˆ์ง€๋งŒ(babel-reset-es2015, babel-reset-es2016โ€ฆ) ์ง€๊ธˆ์€ env ํ•˜๋‚˜๋กœ ํ•ฉ์ณ์กŒ๋‹ค.

preset-flow, preset-react, preset-typescript๋Š” flow, ๋ฆฌ์•กํŠธ, ํƒ€์ž…์Šคํฌ๋ฆฝํŠธ๋ฅผ ๋ณ€ํ™˜ํ•˜๊ธฐ ์œ„ํ•œ ํ”„๋ฆฌ์…‹์ด๋‹ค.

์ธํ„ฐ๋„ท ์ต์Šคํ”Œ๋กœ๋Ÿฌ ์ง€์›์„ ์œ„ํ•ด env ํ”„๋ฆฌ์…‹์„ ์‚ฌ์šฉํ•ด ๋ณด์ž.

๋จผ์ € ํŒจํ‚ค์ง€๋ฅผ ๋‹ค์šด๋กœ๋“œํ•œ๋‹ค.

$ npm install -D @babel/preset-env

์„ค์น˜ํ•œ ๋ฐ”๋ฒจ ์„ค์ •์„ ์กฐ๊ธˆ๋งŒ ๋” ๋ฐ”๊ฟ”๋ณธ๋‹ค.

// ./babel.config.js
module.exports = {
  presets: ['@babel/preset-env'],
};

๊ทธ๋ฆฌ๊ณ  ๋นŒ๋“œํ•˜๋ฉด,

$ npx babel app.js

"use strict";

var alert = function alert(msg) {
return window.alert(msg);
};

mypreset.js์™€ ๊ฐ™์€ ๊ฒฐ๊ณผ๋ฅผ ์ถœ๋ ฅํ•œ๋‹ค.

5. env ํ”„๋ฆฌ์…‹๊ณผ ์„ค์ •๊ณผ ํด๋ฆฌํ•„ ๐Ÿšฅ

๊ณผ๊ฑฐ์—๋Š” ์—ฐ๋„๋ณ„ ํ”„๋ฆฌ์…‹์„ ์ œ๊ณตํ–ˆ๋‹ค.

๊ทธ๋Ÿฌ๋‚˜ ํ˜„์žฌ๋Š” env ํ”„๋ฆฌ์…‹์œผ๋กœ ๋ฌด์ฒ™ ๋‹จ์ˆœํ•˜๊ณ  ์ง๊ด€์ ์ธ ์‚ฌ์šฉ๋ฒ•์„ ์ œ๊ณตํ•œ๋‹ค.

5.1. ํƒ€๊นƒ ๋ธŒ๋ผ์šฐ์ €

์ฝ”๋“œ๊ฐ€ ํฌ๋กฌ ์ตœ์‹  ๋ฒ„์ „๋งŒ ์ง€์›ํ•œ๋‹ค๊ณ  ํ•˜์ž.

๊ทธ๋ ‡๋‹ค๋ฉด ์ธํ„ฐ๋„ท ์ต์Šคํ”Œ๋กœ๋Ÿฌ๋ฅผ ์œ„ํ•œ ์ฝ”๋“œ ๋ณ€ํ™˜์€ ๋ถˆํ•„์š”ํ•˜๋‹ค.

target ์˜ต์…˜์— ๋ธŒ๋ผ์šฐ์ € ๋ฒ„์ „๋ช…๋งŒ ์ง€์ •ํ•˜๋ฉด env ํ”„๋ฆฌ์…‹์€ ์ด์— ๋งž๋Š” ํ”Œ๋Ÿฌ๊ทธ์ธ๋“ค์„ ์ฐพ์•„ ์ตœ์ ์˜ ์ฝ”๋“œ๋ฅผ ์ถœ๋ ฅํ•ด ๋‚ธ๋‹ค.

// ./babel.config.js
module.exports = {
  presets: [
    [
      '@babel/preset-env',
      {
        targets: {
          chrome: '85', // ํฌ๋กฌ 85๊นŒ์ง€ ์ง€์›ํ•˜๋Š” ์ฝ”๋“œ๋ฅผ ๋งŒ๋“ ๋‹ค.
        },
      },
    ],
  ],
};

npx๋กœ ์ถœ๋ ฅํ•ด๋ณด๋ฉด,

$ npx babel app.js

"use strict";

const alert = msg => window.alert(msg);

ํฌ๋กฌ์€ ๋ธ”๋ก ์Šค์ฝ”ํ•‘๊ณผ ํ™”์‚ดํ‘œ ํ•จ์ˆ˜๋ฅผ ์ง€์›ํ•˜๊ธฐ ๋•Œ๋ฌธ์— ์ฝ”๋“œ๋ฅผ ๋ณ€ํ™˜ํ•˜์ง€ ์•Š๊ณ  ์ด๋Ÿฌํ•œ ๊ฒฐ๊ณผ๋ฌผ์„ ๋งŒ๋“ค์—ˆ๋‹ค.

๋งŒ์•ฝ ์ธํ„ฐ๋„ท ์ต์Šคํ”Œ๋กœ๋Ÿฌ๋„ ์ง€์›ํ•ด์•ผ ํ•œ๋‹ค๋ฉด ๋ฐ”๋ฒจ ์„ค์ •์— ๋ธŒ๋ผ์šฐ์ € ์ •๋ณด๋งŒ ํ•˜๋‚˜ ๋” ์ถ”๊ฐ€ํ•˜๋ฉด ๋œ๋‹ค.

// ./babel.config.js
module.exports = {
  presets: [
    [
      '@babel/preset-env',
      {
        targets: {
          chrome: '85',
          ie: '11', // ie 11๊นŒ์ง€ ์ง€์›ํ•˜๋Š” ์ฝ”๋“œ๋ฅผ ๋งŒ๋“ ๋‹ค.
        },
      },
    ],
  ],
};

5.2. ํด๋ฆฌํ•„

์ด๋ฒˆ์—” ๋ณ€ํ™˜๊ณผ ์กฐ๊ธˆ ๋‹ค๋ฅธ ํ”Œ๋ฆฌํ•„์— ๋Œ€ํ•ด ์•Œ์•„๋ณด์ž.

ES6์˜ Promise ๊ฐ์ฒด๋ฅผ ์‚ฌ์šฉํ•˜๋Š” ์ฝ”๋“œ๋‹ค.

// ./app.js
new Promise();

๋ฐ”๋ฒจ๋กœ ์ฒ˜๋ฆฌํ•˜๋ฉด ์–ด๋–ค ๊ฒฐ๊ณผ๊ฐ€ ๋‚˜์˜ฌ๊นŒ?

$ npx babel app.js

"use strict";

new Promise();

env ํ”„๋ฆฌ์…‹์œผ๋กœ ๋ณ€ํ™˜์„ ์‹œ๋„ํ–ˆ์ง€๋งŒ, Promise ๊ทธ๋Œ€๋กœ ๋ณ€ํ•จ์ด ์—†๋‹ค.

target์— ie: 11์„ ์„ค์ •ํ•˜๊ณ  ๋นŒ๋“œํ•œ ๊ฒƒ์ธ๋ฐ ์ธํ„ฐ๋„ท ์ต์Šคํ”Œ๋กœ๋Ÿฌ๋Š” ์—ฌ์ „ํžˆ ํ”„๋ผ๋ฏธ์Šค๋ฅผ ํ•ด์„ํ•˜์ง€ ๋ชปํ•˜๊ณ  ๐Ÿšจ์—๋Ÿฌ๋ฅผ ๋˜์ง„๋‹ค.

๋ธŒ๋ผ์šฐ์ €๋Š” ํ˜„์žฌ ์Šค์ฝ”ํ”„๋ถ€ํ„ฐ ์‹œ์ž‘ํ•ด ์ „์—ญ๊นŒ์ง€ Promise๋ผ๋Š” ์ด๋ฆ„์„ ์ฐพ์œผ๋ ค๊ณ  ์‹œ๋„ํ•  ๊ฒƒ์ด๋‹ค.

๊ทธ๋Ÿฌ๋‚˜ ์Šค์ฝ”ํ”„ ์–ด๋””์—๋„ Promise๋ž€ ์ด๋ฆ„์ด ์—†๊ธฐ ๋•Œ๋ฌธ์— ๋ ˆํผ๋Ÿฐ์Šค ์—๋Ÿฌ๋ฅผ ๋ฐœ์ƒํ•˜๊ณ  ํ”„๋กœ๊ทธ๋žจ์ด ์ฃฝ์€ ๊ฒƒ์ด๋‹ค.

๋ฐ”๋ฒจ์€ ES6 ์ดํ›„ ๋ฒ„์ „์„ ES5 ๋ฒ„์ „์œผ๋กœ ๋ณ€ํ™˜ํ•  ์ˆ˜ ์žˆ๋Š” ๊ฒƒ๋งŒ ๋นŒ๋“œํ•œ๋‹ค.

๊ทธ๋ ‡์ง€ ๋ชปํ•œ ๊ฒƒ๋“ค์€ ํด๋ฆฌํ•„์ด๋ผ๊ณ  ๋ถ€๋ฅด๋Š” ์ฝ”๋“œ์กฐ๊ฐ์„ ์ถ”๊ฐ€ํ•ด์„œ ํ•ด๊ฒฐํ•œ๋‹ค.

ES6์˜ ํ”„๋ผ๋ฏธ์Šค๋Š” ES5 ๋ฒ„์ „์œผ๋กœ ๋Œ€์ฒดํ•  ์ˆ˜ ์—†๋‹ค.

๋‹ค๋งŒ ES5 ๋ฒ„์ „์œผ๋กœ ๊ตฌํ˜„ํ•  ์ˆ˜๋Š” ์žˆ๋‹ค(์ฐธ๊ณ : core-js promise).

env ํ”„๋ฆฌ์…‹์€ ํด๋ฆฌํ•„์„ ์ง€์ •ํ•  ์ˆ˜ ์žˆ๋Š” ์˜ต์…˜์„ ์ œ๊ณตํ•œ๋‹ค.

// ./babel.config.js
module.exports = {
  presets: [
    [
      '@babel/preset-env',
      {
        useBuiltIns: 'usage', // ํด๋ฆฌํ•„ ์‚ฌ์šฉ ๋ฐฉ์‹ ์ง€์ •.
        corejs: {
          // ํด๋ฆฌํ•„ ๋ฒ„์ „ ์ง€์ •.
          version: 2,
        },
      },
    ],
  ],
};

useBuiltIns๋Š” ์–ด๋–ค ๋ฐฉ์‹์œผ๋กœ ํด๋ฆฌํ•„์„ ์‚ฌ์šฉํ• ์ง€ ์„ค์ •ํ•˜๋Š” ์˜ต์…˜์ด๋‹ค.

usage, entry, false ์„ธ ๊ฐ€์ง€ ๊ฐ’์„ ์‚ฌ์šฉํ•˜๋Š”๋ฐ ๊ธฐ๋ณธ๊ฐ’์ด false์ด๋ฏ€๋กœ ํด๋ฆฌํ•„์ด ๋™์ž‘ํ•˜์ง€ ์•Š์•˜๋‹ค.

๋ฐ˜๋ฉด usage๋‚˜ entry๋ฅผ ์„ค์ •ํ•˜๋ฉด ํด๋ฆฌํ•„ ํŒจํ‚ค์ง€ ์ค‘ core-js๋ฅผ ๋ชจ๋“ˆ๋กœ ๊ฐ€์ ธ์˜จ๋‹ค.

์ž์„ธํ•œ ํด๋ฆฌํ•„ ์˜ต์…˜์€ ๋ฐ”๋ฒจ ๋ฌธ์„œ์˜ useBuiltIns์™€ corejs ์„น์…˜์„ ์ฐธ๊ณ ํ•˜์ž.

ํด๋ฆฌํ•„์ด ์ถ”๊ฐ€๋œ ๊ฒฐ๊ณผ๋ฌผ์„ ํ™•์ธํ•ด ๋ณด์ž.

$ npx babel src/app.js
"use strict";

require("core-js/modules/es6.promise");
require("core-js/modules/es6.object.to-string");

new Promise();

core-js ํŒจํ‚ค์ง€๋กœ๋ถ€ํ„ฐ ํ”„๋ผ๋ฏธ์Šค ๋ชจ๋“ˆ์„ ๊ฐ€์ ธ์˜ค๋Š” import ๊ตฌ๋ฌธ์ด ์ƒ๋‹จ์— ์ถ”๊ฐ€๋˜์—ˆ๋‹ค.

์ด์ œ์•ผ ๋น„๋กœ์†Œ ์ธํ„ฐ๋„ท ์ต์Šคํ”Œ๋กœ๋Ÿฌ์—์„œ ์•ˆ์ „ํ•˜๊ฒŒ ๋Œ์•„๊ฐ€๋Š” ๊ฒฐ๊ณผ๋ฌผ์„ ๋งŒ๋“ค์—ˆ๋‹ค.

6. ์›นํŒฉ์œผ๋กœ ํ†ตํ•ฉ ๐Ÿงญ

์‹ค๋ฌด ํ™˜๊ฒฝ์—์„œ๋Š” ๋ฐ”๋ฒจ์„ ์ง์ ‘ ์‚ฌ์šฉํ•˜์ง€ ์•Š๊ณ  ์›นํŒฉ์œผ๋กœ ํ†ตํ•ฉํ•ด์„œ ์‚ฌ์šฉํ•œ๋‹ค.

๋ณดํ†ต ๋กœ๋” ํ˜•ํƒœ๋กœ ์ œ๊ณตํ•˜๋Š”๋ฐ babel-loader๊ฐ€ ์žˆ๋‹ค.

๋จผ์ € ํŒจํ‚ค์ง€๋ฅผ ์„ค์น˜ํ•˜๊ณ ,

$ npm install -D babel-loader

์›นํŒฉ ์„ค์ •์— ๋กœ๋”๋ฅผ ์ถ”๊ฐ€ํ•œ๋‹ค.

// ./webpack.config.js
module.exports = {
  module: {
    rules: [
      {
        test: /\.js$/,
        exclude: /node_modules/,
        loader: 'babel-loader', // ๋ฐ”๋ฒจ ๋กœ๋”๋ฅผ ์ถ”๊ฐ€ํ•œ๋‹ค.
      },
    ],
  },
};

.js ํ™•์žฅ์ž๋กœ ๋๋‚˜๋Š” ํŒŒ์ผ์€ babel-loader๊ฐ€ ์ฒ˜๋ฆฌํ•˜๋„๋ก ์„ค์ •ํ–ˆ๋‹ค.

์‚ฌ์šฉํ•˜๋Š” ์จ๋“œํŒŒํ‹ฐ ๋ผ์ด๋ธŒ๋ผ๋ฆฌ๊ฐ€ ๋งŽ์„์ˆ˜๋ก ๋ฐ”๋ฒจ ๋กœ๋”๊ฐ€ ๋А๋ฆฌ๊ฒŒ ๋™์ž‘ํ•  ์ˆ˜ ์žˆ๋Š”๋ฐ node_modules ํด๋”๋ฅผ ๋กœ๋”๊ฐ€ ์ฒ˜๋ฆฌํ•˜์ง€ ์•Š๋„๋ก ์˜ˆ์™ธ ์ฒ˜๋ฆฌํ–ˆ๋‹ค.

ํด๋ฆฌํ•„ ์‚ฌ์šฉ ์„ค์ •์„ ํ–ˆ๋‹ค๋ฉด core-js๋„ ์„ค์น˜ํ•ด์•ผํ•œ๋‹ค.

์›นํŒฉ์€ ๋ฐ”๋ฒจ ๋กœ๋”๊ฐ€ ๋งŒ๋“  ์•„๋ž˜ ์ฝ”๋“œ๋ฅผ ๋งŒ๋‚˜๋ฉด core-js๋ฅผ ์ฐพ์„ ๊ฒƒ์ด๊ธฐ ๋•Œ๋ฌธ์ด๋‹ค.

# ์›นํŒฉ์ด ์ฐพ๊ณ ์ž ํ•˜๋Š” ๋‘ ๊ฐ€์ง€ ๋ชจ๋“ˆ ์˜ˆ์‹œ.
require("core-js/modules/es6.promise")
require("core-js/modules/es6.object.to-string")

๋ฒ„์ „ 2๋กœ ํŒจํ‚ค์ง€๋ฅผ ์ถ”๊ฐ€ํ•˜์ž.

$ npm i core-js@2

๊ทธ๋ฆฌ๊ณ  ์›นํŒฉ์œผ๋กœ ๋นŒ๋“œํ•˜๋ฉด,

$ npm run build

> webpack

Hash: a30cff5fbf53027423a0
Version: webpack 4.41.2
Time: 718ms
Built at: 2019. 12. 16. ์˜ค์ „ 8:52:05
Asset Size Chunks Chunk Names
main.js 59.7 KiB main [emitted] main
Entrypoint main = main.js
[./src/app.js] 166 bytes {main} [built]

๋ฏธ๋ฆฌ ๋“ฑ๋กํ•ด ๋†“์€ NPM build ์Šคํฌ๋ฆฝํŠธ์˜ webpack ๋ช…๋ น์–ด๊ฐ€ ๋™์ž‘ํ•œ๋‹ค.

./src/app.js์˜ ์—”ํŠธ๋ฆฌ ํฌ์ธํŠธ๊ฐ€ ๋ฐ”๋ฒจ ๋กœ๋”์— ์˜ํ•ด ๋นŒ๋“œ๋˜๊ณ  ๊ฒฐ๊ณผ๋ฌผ์ด ./dist/main.js๋กœ ์˜ฎ๊ฒจ์กŒ๋‹ค.

cat ./dist/main.js | grep 'var alert' -A 5

var alert = function alert(msg) {
return window.alert(msg);
};

new Promise();

7. ์ฐธ์กฐ ๐Ÿ“‹

๐Ÿ‘‹


Written by@davidyang2149 (About me)
Hello World! This is David Yang Dev Blogs.

GitHub