분류 javascript

JavaScript Transpilers : 왜 그것이 필요로 하는가?

컨텐츠 정보

  • 조회 231 (작성일 )

본문

소개 


Transpilers 또는 source-to-source 컴파일러는 하나의 프로그래밍 언어로 작성된 소스 코드를 읽고 다른 언어로 동일한 코드를 생성하는 도구입니다. JavaScript로 번역 된 언어는 종종 JSF (compile-to-JS) 언어라고 하며 JavaScript를 target으로 합니다.


아, 그리고 사람들이 "compile/r"과 "transpile/r"을 같은 의미로 사용하는 경향이 있지만,이 기사에서 후자를 선호 할 것입니다.


CoffeeScriptTypeScript에 대해 들어 보셨을 것입니다. CoffeeScript는 아직 자바 스크립트가 아닌 여러 기능에 대해 통 신적 설탕을 제공하지만 일부 자바 스크립트의 "불량 부품"은 차단합니다. TypeScript는 근본적으로 다른 언어에 고전적인 객체 지향 의미를 더하여 과감합니다.


JavaScript로 작성할 수 있는 모든 것은 CoffeeScript 또는 TypeScript로 작성할 수 있습니다.


"use strict";

// Good 'ol JS
function printSecret ( secret ) {
    console.log(`${secret}. But don't tell anyone.`);
}

printSecret("I don't like CoffeeScript"); 
"use strict"

# CoffeeScript
printSecret (secret) =>
    console.log '#{secret}. But don't tell anyone.'

printSecret "I don't like JavaScript." 
"use strict";

// TypeScript -- JavaScript, with types and stuff
function printSecret ( secret : string ) {
    console.log("${secret}. But don't tell anyone.");
}

printSecret("I don't like CoffeeScript.");

문제는 자바스크립트 환경만 이해한다는 것입니다. . . 글쎄, 자바 스크립트. 콘솔에서 마지막 두 예제를 사용하면 오류가 발생합니다. 사실, 이전 브라우저에서 순수 JavaScript 예제를 사용하면 여전히 오류가 발생합니다. 템플릿 리터럴에는 여전히 안정적인 브라우저 지원이 없습니다.


그것이 transpilers가 들어오는 곳입니다. 그들은 CoffeeScript, TypeScript 및 ES2015를 읽고 어디에서나 작동하도록 보장 된 JavaScript를 방출합니다.


Transpilers의 방위에서 


워크 플로우에 트랜스퍼러가 아직 포함되어 있지 않은 경우, 왜 귀찮게 하는지 궁금해 할 수 있습니다. 새로운 구문을 배우고 새로운 도구를 선택하는 이유는 결국 우리가 처음에 작성한 JavaScript 일 것입니다.


자바 스크립트를 대상으로 하는 언어의 경우 주로 환경 설정이나 배경의 문제입니다. 당신이 하는 방식을 "생각하는"언어로 글을 쓰면 생산성이 향상됩니다. OOP에서 배경을 가진 사람들은 익숙한 영역이기 때문에 종종 TypeScript를 좋아합니다. Pythonistas는 CoffeeScript를 좋아합니다. Clojurists는 ClojureScript를 작성합니다. 당신은 아이디어를 얻습니다.


그러나 평범한 JavaScript를 작성하는 것으로 완벽하게 괜찮은 우리 중 나머지는 여전히 transpiler를 사용합니다. ES2015 이상의 기능을 사용할 수 있는 유일한 방법이기 때문입니다.


내일의 JavaScript, 오늘 


이전에 브라우저 호환성 문제를 처리해야 했던 사람이라면 어디에서나 사용할 수 있는 JavaScript를 작성하는 것만 큼 쉽지는 않습니다. 모든 브라우저가 다른 자바 스크립트 엔진을 사용하기 때문입니다. Chrome은 V8을 실행하고 FirefoxSpiderMonkey를 실행하고 Interet Explorer는 Chakra를 실행합니다. 각각은 서로 다른 성능 특성을 가지며 각각은 ES2015 기능의 다른 서브 세트를 구현하며 각각은 다른 속도로 스펙을 완전히 준수하게 됩니다.


즉, 템플릿 리터럴 예제는 가장 최근의 Chrome, Firefox 또는 Safari를 실행하는 사용자에게 적합하지만 이전 버전을 실행하는 사용자에게는 효과가 없습니다. 또는 Internet Explorer를 사용하는 모든 사용자에게 적합합니다. . . 명백하게.


이 방법을 사용하면 현재 선택하고 있는 선택기로 지원되는 모든 기능을 사용할 수 있으며, 사이트를 방문하는 모든 사람들에게 효과적이라는 것을 알고 있습니다. 공용 직원은 IE8을 사용하는 해커 유형에 FireFox 야간.


내일의 JavaScript, 길을 따라 


Transpilers는 또한 ECMAScript 표준을 디자인하는 TC39위원회의 결정을 이끌어내는 데 중요한 역할을 합니다.


하나의 경우, transpryer는 표준에 기능을 포함시키는 데 직접적으로 기여할 수 있습니다. 잠재 기능이 1 단계 (제안서)에서 2 단계 (초안)로 이동하려면 다음 단계를 따르세요.


이 기능에 대한 두 가지 실험 구현이 필요하지만 그 중 하나는 Babel과 같은 변환기에 있을 수 있습니다. 


아마도 이 기여보다 더 중요한 것은 바벨 (Babel)이나 트레이서 (Traceur)와 같은 변환기의 사용자와 구현 자의 피드백이 TC39가 구문과 제안을 반복하는 데 도움이 된다는 것입니다. TC39 회의에서 종종 나옵니다. TC39 회의 노트의 모든 라인을 읽거나 알 수 있듯이 rgrep 만 있으면 36 번 언급 된 Babel을 발견 할 수 있습니다. 2015 년 3 월 25 일 회의에서 이 구속력 있는 구문은 "바벨 사용자로부터 더 많은 의견을 얻으십시오!"였습니다!


TC39 Meeting Notes: "Get more feedback from users of Babel! 


요약 설명 :

  1. CoffeeScript, TypeScript 또는 ClojureScript와 같은 JavaScript에서 컴파일 언어로 작성할 수 있습니다.
  2. 새롭고 잠재적 인 JavaScript 기능을 안정적으로 사용합시다. 
  3. ECMAScript 사양 개발에 기여하십시오.

이제는 transpilers가 무엇인지 알아야 할 모든 것을 알았으므로 사용 방법을 파헤 치자.


Transpilers 사용 


많은 ES2015-ES-5 변환기가 있지만 바벨에 집중할 것입니다.


이 섹션에서는 다음 내용을 다룹니다.

  1. ES2015 출처와 출력물의 비교
  2. 바벨 (Babel) 명령 줄 인터페이스 (CLI) 설정; 
  3. Webpack, JSPM 및 Babelify와 같은 빌드 도구가 프로세스를 간소화하는 방법을 살펴보십시오.


나의 근원은 당신의 근원입니다 


시작하려면 Babel의 라이브 transpiler로 향하십시오. 아래 코드를 JavaScript 편집기 (왼쪽 상자)에 복사하십시오.


"use strict";

class Planet {

  constructor (mass, moons) {
    this.mass  = mass;
    this.moons = moons || 0;
  }

  reportMoons () {
    console.log(`I have ${this.moons} moons.`)
  }

}

// Yeah, Jupiter really does have (at least) 67 moons.
const jupiter = new Planet('Pretty Big', 67);
jupiter.reportMoons();

결과물을 봅니다 (편의상 아래에 재현). ES2015 기능이 없음을 알 수 있습니다. const 변수는 주의 깊게 범위 지정된 var 선언으로 변환됩니다. 클래스는 구식 함수 생성자로 변환됩니다. 템플리트 문자열은 간단한 문자열 연결로 간주됩니다.


// Everything below is Babel's output.
'use strict';

var _createClass = function () { function defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; }();

function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }

var Planet = function () {
  function Planet(mass, moons) {
    _classCallCheck(this, Planet);

    this.mass = mass;
    this.moons = moons || 0;
  }

  _createClass(Planet, [{
    key: 'reportMoons',
    value: function reportMoons() {
      console.log('I have ' + this.moons + ' moons.');
    }
  }]);

  return Planet;
}();

이것은 언어가 처음부터 가진 특징입니다. 이를 사용하여 ES2015의 기능을 에뮬레이션하는 것은 정확하게 표준화 되지 않은 기능을 사용하여 부팅하고 안전하게 수행하는 방법입니다.


재미있는 작은 참고로 catch 절은 JavaScript에서 범위를 만듭니다. 이 동작은 ES3에서 다시 표준화 되었습니다. Traceur는 블록 스코핑 (block-scoping)을 에뮬레이트하기 위해 이것을 다음과 같이 만들어 냈다.


"use strict";

// ES2015
{
    let name = "Never woulda thunk.";
}

// ES3/5 output
try { throw void 0; } catch(name) {
    name = "Never woulda thunk.";
    console.log(name);
}

polyfill은 어떤가요?