Babel 플러그인
차세대 JavaScript 컴파일 확장
클래스 필드 선언
ES 표준에 제안 된 클래스 필드 선언(class field declarations) 구문을 사용하면 클래스 문법 사용 시 편리하게 스태틱, 인스턴스 멤버를 추가해 사용할 수 있습니다. 하지만 이 기능을 현재 제안된 기술로 @babel/preset-env 사전 설정에는 포함되어 있지 않아 사용할 수 없습니다.
class Button {
constructor(props) {
this.props = { ...this.constructor.defaultProps, ...props };
}
// 클래스 멤버
static defaultProps = {
type: 'button'
};
// 인스턴스 멤버
displayProps = () => {
console.log(this.props);
};
}
클래스 필드 선언을 사용하기 위해 @babel/plugin-proposal-class-properties 플러그인 패키지를 설치합니다.
npm i -D @babel/plugin-proposal-class-properties
설치한 플러그인을 사용하기 위한 설정을 babel.config.json
파일에 추가합니다.
{
"plugins": [
"@babel/plugin-proposal-class-properties"
]
}
start
명령을 실행해 컴파일 하면, 클래스 필드 선언 구문을 호환 가능한 코드로 출력해줍니다.
npm start
"use strict";
function ownKeys(object, enumerableOnly) { var keys = Object.keys(object); if (Object.getOwnPropertySymbols) { var symbols = Object.getOwnPropertySymbols(object); if (enumerableOnly) symbols = symbols.filter(function (sym) { return Object.getOwnPropertyDescriptor(object, sym).enumerable; }); keys.push.apply(keys, symbols); } return keys; }
function _objectSpread(target) { for (var i = 1; i < arguments.length; i++) { var source = arguments[i] != null ? arguments[i] : {}; if (i % 2) { ownKeys(Object(source), true).forEach(function (key) { _defineProperty(target, key, source[key]); }); } else if (Object.getOwnPropertyDescriptors) { Object.defineProperties(target, Object.getOwnPropertyDescriptors(source)); } else { ownKeys(Object(source)).forEach(function (key) { Object.defineProperty(target, key, Object.getOwnPropertyDescriptor(source, key)); }); } } return target; }
function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }
function _defineProperty(obj, key, value) { if (key in obj) { Object.defineProperty(obj, key, { value: value, enumerable: true, configurable: true, writable: true }); } else { obj[key] = value; } return obj; }
var Button = function Button(props) {
var _this = this;
_classCallCheck(this, Button);
_defineProperty(this, "displayProps", function () {
console.log(_this.props);
});
this.props = _objectSpread(_objectSpread({}, this.constructor.defaultProps), props);
};
_defineProperty(Button, "defaultProps", {
type: 'button'
});
비공개 멤버
ES 표준에 제안 된 비공개 멤버(private methods) 구문을 사용하면 클래스 문법 사용 시 편리하게 비공개 멤버를 추가해 (JAVA의 private 접근 제어자처럼) 사용할 수 있습니다. 하지만 이 기능을 현재 제안된 기술로 @babel/preset-env 사전 설정에는 포함되어 있지 않아 사용할 수 없습니다.
class Button {
constructor(props) {
this.props = props ?? { ...this.constructor.defaultProps, ...props };
}
// 비공개 멤버 (클래스 외부에서 접근 불가능)
#API_TOKEN = 'token-fkjw2jicjx8kjvwdijf3';
static defaultProps = {
type: 'button'
};
fetchData() {
// 클래스 또는 인스턴스 멤버는 비공개 멤버에 접근 가능
fetch(`https://api.dev?token=${this.apiToken}`)
.then((res) => console.log(res))
.catch((error) => console.error(error.message));
}
displayProps = () => {
console.log(this.props);
};
}
클래스 필드 선언을 사용하기 위해 @babel/plugin-proposal-private-methods 플러그인 패키지를 설치합니다.
npm i -D @babel/plugin-proposal-private-methods
설치한 플러그인을 사용하기 위한 설정을 babel.config.json
파일에 추가합니다.
{
"plugins": [
"@babel/plugin-proposal-private-methods"
]
}
start
명령을 실행해 컴파일 하면, 클래스 필드 선언 구문을 호환 가능한 코드로 출력해줍니다.
npm start
"use strict";
function ownKeys(object, enumerableOnly) { var keys = Object.keys(object); if (Object.getOwnPropertySymbols) { var symbols = Object.getOwnPropertySymbols(object); if (enumerableOnly) symbols = symbols.filter(function (sym) { return Object.getOwnPropertyDescriptor(object, sym).enumerable; }); keys.push.apply(keys, symbols); } return keys; }
function _objectSpread(target) { for (var i = 1; i < arguments.length; i++) { var source = arguments[i] != null ? arguments[i] : {}; if (i % 2) { ownKeys(Object(source), true).forEach(function (key) { _defineProperty(target, key, source[key]); }); } else if (Object.getOwnPropertyDescriptors) { Object.defineProperties(target, Object.getOwnPropertyDescriptors(source)); } else { ownKeys(Object(source)).forEach(function (key) { Object.defineProperty(target, key, Object.getOwnPropertyDescriptor(source, key)); }); } } return target; }
function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a 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); } }
function _createClass(Constructor, protoProps, staticProps) { if (protoProps) _defineProperties(Constructor.prototype, protoProps); if (staticProps) _defineProperties(Constructor, staticProps); return Constructor; }
function _defineProperty(obj, key, value) { if (key in obj) { Object.defineProperty(obj, key, { value: value, enumerable: true, configurable: true, writable: true }); } else { obj[key] = value; } return obj; }
function _classPrivateFieldGet(receiver, privateMap) { var descriptor = privateMap.get(receiver); if (!descriptor) { throw new TypeError("attempted to get private field on non-instance"); } if (descriptor.get) { return descriptor.get.call(receiver); } return descriptor.value; }
var _API_TOKEN = new WeakMap();
var Button = /*#__PURE__*/function () {
function Button(props) {
var _this = this;
_classCallCheck(this, Button);
_API_TOKEN.set(this, {
writable: true,
value: 'token-fkjw2jicjx8kjvwdijf3'
});
_defineProperty(this, "displayProps", function () {
console.log(_this.props);
});
this.props = props !== null && props !== void 0 ? props : _objectSpread(_objectSpread({}, this.constructor.defaultProps), props);
}
_createClass(Button, [{
key: "apiToken",
get: function get() {
return _classPrivateFieldGet(this, _API_TOKEN);
}
}, {
key: "fetchData",
value: function fetchData() {
fetch("https://api.dev?token=".concat(this.apiToken)).then(function (res) {
return console.log(res);
}).catch(function (error) {
return console.error(error.message);
});
}
}]);
return Button;
}();
_defineProperty(Button, "defaultProps", {
type: 'button'
});
참고
살펴본 Babel 플러그인 외에도 다양한 플러그인을 사용할 수 있습니다.
Last updated