js0616 2024. 8. 11. 17:25

https://epiphany0421.tistory.com/186

 

Babel, Webpack이란? 쓰는 이유 요약 정리

📌 Babel이란? 바벨(Babel)이란, 입력과 출력이 모두 자바스크립트 코드인 컴파일러입니다. 바벨은 최신 버전의 자바스크립트가 실행되지 않는 구 버전의 브라우저에서도 정상적으로 실행되도록

epiphany0421.tistory.com

 

babel을 쓰는 이유

  • 크로스 브라우징
    • JavaScript (ES6) -> JavaScript(ES5)로 변환해줍니다. (브라우저 하위 호환성을 생각)
    • 각 브라우저마다 JavaScript 엔진이 다르지만, 모든 브라우저에서 동작하도록 호환성을 지켜줍니다.
  • 폴리필(polyfill)
    • 폴리필은 개발자가 특정 기능이 지원되지 않는 브라우저를 위해 사용할 수 있는 코드 조각이나 플러그인을 의미합니다.
    • 폴리필은 프로그램이 처음에 시작될 때 현재 브라우저에서 지원하지 않는 함수를 검사해서 각 object의 prototype에 붙여주는 역할을 합니다.

 

babel은 최신 문법을 하위 기기나 브라우저에서 사용하도록 도와주는 역할을 함 

 


 

https://poiemaweb.com/es6-babel-webpack-1

 

Babel | PoiemaWeb

현재 브라우저는 ES6를 완전하게 지원하지 않는다. ES6+(ES6 이상의 버전)를 사용하여 프로젝트를 진행하려면 ES6+로 작성된 코드를 IE를 포함한 모든 브라우저에서 문제 없이 동작시키기 위한 개발

poiemaweb.com

 

 

// ES6 화살표 함수와 ES7 지수 연산자
[1, 2, 3].map(n => n ** n);


// ES5
"use strict";

[1, 2, 3].map(function (n) {
  return Math.pow(n, n);
});

 

Babel 은 최신 문법을 ES5 이하의 코드로 변환(트랜스파일링)할 수 있다.

 

1. npm 설치

npm init -y

package.json 파일 생성됨

 

 

2. babel 설치

// 지역설치
npm install {패키지명}

// 전역설치
npm install {패키지명} --global

 

npm install --save-dev @babel/core @babel/cli

// --save-dev : 개발 단계만 사용 -D : 축약
// babel/core : 트랜스파일링, 핵심 모듈
// babel/cli : CLI 에서 babel 실행

node_modules 과 package-lock.json 생성

 

package.json 

{
  "name": "es6_setting",
  "version": "1.0.0",
  "main": "index.js",
  "scripts": {
    "test": "echo \"Error: no test specified\" && exit 1"
  },
  "keywords": [],
  "author": "",
  "license": "ISC",
  "description": "",
  "devDependencies": {
    "@babel/cli": "^7.24.8",
    "@babel/core": "^7.25.2"
  }
}

 

plugin : 실제로 코드를 변환하는 기능
ex) @babel/plugin-transfrom-arrow-functions   // ES6 화살표 함수 문법
필요한걸 하나씩 다 설치하기 힘드므로 preset 을 사용

npm install --save-dev @babel/preset-env

 

 

루트 디렉터리에 .babelrc 파일 생성

설치한 @babel/preset-env를 사용하겠다는 코드 작성

{
    "presets": ["@babel/preset-env"]
}

 

 

트랜스파일링

Babel을 사용하여 ES6+ 코드를 ES5 이하의 코드로 트랜스파일링하기 위해

Babel CLI 명령어를 사용하거나, npm script를 사용하여 트랜스파일링

 

package.json 파일에 scripts를 추가한다. 

  "scripts": {
    "build": "babel src/js -w -d dist/js"
  },

 

src/js 폴더(타깃 폴더)에 있는 모든 ES6+ 파일들을 트랜스파일링한 후, 그 결과물을 dist/js 폴더에 저장한다. 

 

-w
타깃 폴더에 있는 모든 파일들의 변경을 감지하여 자동으로 트랜스파일한다. (--watch 옵션의 축약형)


-d
트랜스파일링된 결과물이 저장될 폴더를 지정한다. (--out-dir 옵션의 축약형)

 


여기까지 결과 테스트

프로젝트 루트에 src/js 폴더를 생성한 후 lib.js와 main.js를 추가한다.

// src/js/lib.js
// ES6 모듈
export const pi = Math.PI;

export function power(x, y) {
  // ES7: 지수 연산자
  return x ** y;
}

// ES6 클래스
export class Foo {
  // stage 3: 클래스 필드 정의 제안
  #private = 10;

  foo() {
    // stage 4: 객체 Rest/Spread 프로퍼티
    const { a, b, ...x } = { ...{ a: 1, b: 2 }, c: 3, d: 4 };
    return { a, b, x };
  }

  bar() {
    return this.#private;
  }
}
// src/js/main.js
// ES6 모듈
import { pi, power, Foo } from './lib';

console.log(pi);
console.log(power(pi, pi));

const f = new Foo();
console.log(f.foo());
console.log(f.bar());

 

npm run build

 

 

기존 글에서는 preset-env 가  Class 문법에 대한 plugin 을 지원하지 않아서 추가로 해당 플러그인을 설치하여 다시 빌드한다. 해당 글에 비해 시간이 많이 지나 오류 없이 성공하는것을 볼 수 있음.

 


만약 오류가 있다면 해당 문법에 대한 plugin 을 따로 설치해야함..! 

npm install --save-dev @babel/plugin-proposal-class-properties

 

 package.json 파일에 추가 된 것을 확인

 

 .babelrc 파일에 추가

{
    "presets": ["@babel/preset-env"],
    "plugins": ["@babel/plugin-proposal-class-properties"]
}

 

트랜스파일링에 성공하면 프로젝트 루트에 dist/js 폴더가 자동 생성되고 트랜스파일링된 main.js와 lib.js가 저장된다.

"use strict";

var _lib = require("./lib");
// src/js/main.js
// ES6 모듈

console.log(_lib.pi);
console.log((0, _lib.power)(_lib.pi, _lib.pi));
var f = new _lib.Foo();
console.log(f.foo());
console.log(f.bar());

 

node dist/js/main.js 로 실행이 가능해짐!

 


기존에 node main.js 로 실행이 안되었나? 확인 

// src/js/main.js
// ES6 모듈
import { pi, power, Foo } from './lib';

console.log(pi);
console.log(power(pi, pi));

const f = new Foo();
console.log(f.foo());
console.log(f.bar());

 

gpt 한테 물어봤는데

이 오류는 ES 모듈을 사용하려는데 Node.js가 이를 인식하지 못하기 때문에 발생합니다.

package.json에 "type": "module"을 추가하거나 파일 확장자를 .mjs로 변경해 보세요.

--> 해봐도 안됨 


 

1.6 브라우저에서 모듈 로딩 테스트

main.js와 lib.js 모듈을 트랜스파일링하여 ES5로 변환된 main.js을 실행한 결과, 문제없이 실행되는 것을 확인

 

하지만 모듈 기능은 node.js 환경에서 동작한 것이고 Babel이 모듈을 트랜스파일링한 것도 node.js가 기본 지원하는 CommonJS 방식의 module loading system에 따른 것이다. 

브라우저는 CommonJS 방식의 module loading system(require 함수)을 지원하지 않으므로 위에서 트랜스파일링된 결과를 그대로 브라우저에서 실행하면 에러가 발생한다.

 

프로젝트 루트 폴더에 아래와 같이 index.html을 작성

<!DOCTYPE html>
<html>
<body>
  <script src="dist/js/lib.js"></script>
  <script src="dist/js/main.js"></script>
</body>
</html>

 

실행시 다음과 같은 오류 발생

 

 

Webpack 을 이용하여 해결 가능 하다. !

 

 

 

 

이외 출처

 

https://juyami.tistory.com/91