babel初学者がBabel 7を使ってみたメモ。
初babelなので認識違いなどあればご指摘ください。 (Qiitaも初めてなので文化的暗黙のルールとかもわかってないです
docs: https://babeljs.io/docs/
node: "10.4.0"
@babel/cli: "7.1.5"
@babel/core: "7.1.6"
@babel/preset-env: "7.1.6"
@babel/polyfill: "7.0.0"
install
$ yarn add --dev @babel/core @babel/cli @babel/preset-env
babel7からはパッケージ名が@babel/xxxに変更になっている。
config
$ touch babel.config.js
babel.config.js
const presets = [
["@babel/preset-env"]
};
module.exports = { presets }
パッケージ名が変更になってるので、"env"とか"preset-env"とかを指定しているとエラーになる
targets
browserslistはtargetプロパティに直接渡す。
babel.config.js
const presets = [
["@babel/preset-env", {
"targets": [">0.25% in JP", "not ie <= 10", "not op_mini all"],
}]
};
targets.browsersでの指定は廃止予定
const presets = [
["@babel/preset-env", {
"targets": {
"browsers": [">0.25% in JP", "not ie <= 10", "not op_mini all"],
},
}]
};
babel 7 で動作するけど、browsersでの指定は将来的に廃止予定っぽい
fc. https://babeljs.io/docs/en/babel-preset-env#targetsbrowsers
Note: this will be removed in later version in favor of just setting "targets" to a query directly.
動作チェク
package.jsonにバベるコマンドを作成
"scripts": {
"babel": "./node_modules/.bin/babel src --out-dir dist/js",
}
src/index.js
import { foo, bar } from './test.js'
console.log( foo() );
const countup = (x) => x + 1;
console.log( countup(1) )
Promise.resolve().then(res => console.log("Promise end") );
バベる
$ yarn run babel
👇 dist/js/index.js
var _test = require("./test.js");
console.log((0, _test.foo)());
var countup = function countup(x) {
return x + 1;
};
console.log(countup(1));
Promise.resolve().then(function (res) {
return console.log("Promise end");
});
@babel/polyfill
PromiseやWeakMap, Array.from, Object.assign, Array.prototype.includesなど文法ではなく、機能を対応していないブラウザ用に変換する
=> つまり、コードを直接変換する機能
install
$ yarn add @babel/polyfill
Usage
babel.config.jsにuseBuiltIns: "usage"を指定すれば、必要に合わせてプラグインを選び変換してくれるっぽい
Now luckily for us, we're using the
envpreset which has a"useBuiltIns"option that when set to"usage"will practically apply the last optimization mentioned above where you only include the polyfills you need.
babel.config.js
const presets = [
["@babel/preset-env", {
"targets": [">0.25% in JP", "not ie <= 10", "not op_mini all"],
"useBuiltIns": "usage",
}]
};
動作チェク
Promise.resolve().then(res => console.log("Promise end") );
👇 バベる
require("core-js/modules/es6.promise");
Promise.resolve().then(function (res) {
return console.log("Promise end");
});
core-js/modules/es6.promiseが追加されている。
async/await
const asyncSampleFunc = () => {
return new Promise((resolve, reject) => {
setTimeout(resolve, 100, "resolve");
});
}
async function getAsyncVal() {
const val = await asyncSampleFunc();
return `Complete Async: ${val}`
}
getAsyncVal().then((res) => {
console.log(res);
}).catch((err) => {
console.log(err);
});
👇 バベる
require("regenerator-runtime/runtime");
require("core-js/modules/es6.promise");
function asyncGeneratorStep(gen, resolve, reject, _next, _throw, key, arg) { try { var info = gen[key](arg); var value = info.value; } catch (error) { reject(error); return; } if (info.done) { resolve(value); } else { Promise.resolve(value).then(_next, _throw); } }
function _asyncToGenerator(fn) { return function () { var self = this, args = arguments; return new Promise(function (resolve, reject) { var gen = fn.apply(self, args); function _next(value) { asyncGeneratorStep(gen, resolve, reject, _next, _throw, "next", value); } function _throw(err) { asyncGeneratorStep(gen, resolve, reject, _next, _throw, "throw", err); } _next(undefined); }); }; }
var asyncSampleFunc = function asyncSampleFunc() {
return new Promise(function (resolve, reject) {
setTimeout(resolve, 100, "resolve");
});
};
function getAsyncVal() {
return _getAsyncVal.apply(this, arguments);
}
function _getAsyncVal() {
_getAsyncVal = _asyncToGenerator(
/*#__PURE__*/
regeneratorRuntime.mark(function _callee() {
var val;
return regeneratorRuntime.wrap(function _callee$(_context) {
while (1) {
switch (_context.prev = _context.next) {
case 0:
_context.next = 2;
return asyncSampleFunc();
case 2:
val = _context.sent;
return _context.abrupt("return", "Complete Async: ".concat(val));
case 4:
case "end":
return _context.stop();
}
}
}, _callee, this);
}));
return _getAsyncVal.apply(this, arguments);
}
getAsyncVal().then(function (res) {
console.log(res);
}).catch(function (err) {
console.log(err);
});
変換できたっぽい。 (以前async/await使ってるプロダクト作ってる人にasync/awaitはバベれないって言われたのでダメなのかと思ってた...
import -> require 問題
デフォルトだと、importがrequire(CommonJS?)に変換されてしまう。
modules: falseを指定するとimportのままになる
babel.config.js
const presets = [
["@babel/preset-env", {
"modules": false,
"targets": [">0.25% in JP", "not ie <= 10", "not op_mini all"],
"useBuiltIns": "usage",
}]
};
動作チェク
src/index.js
import { foo, bar } from './test.js'
console.log( foo() );
const countup = (x) => x + 1;
console.log( countup(1) )
Promise.resolve().then(res => console.log("Promise end") );
👇 バベる
dist/js/index.js
import "core-js/modules/es6.promise";
import { foo, bar } from './test.js';
console.log(foo());
var countup = function countup(x) {
return x + 1;
};
console.log(countup(1));
Promise.resolve().then(function (res) {
return console.log("Promise end");
});
import文のまましゅつりょくされた。
cf. https://babeljs.io/docs/en/babel-preset-env#modules
modules
"amd"|"umd"|"systemjs"|"commonjs"|"cjs"|"auto"|false, defaults to"auto".
Enable transformation of ES6 module syntax to another module type.
Setting this to false will not transform modules.
Also note thatcjsis just an alias forcommonjs.
[WIP]
-
.babelrcとbabel.config.jsの使い分けがイマイチわかってない。
https://babeljs.io/docs/en/configuration - 時々見かける
looseオプションが何をするのかイマイチわかっていない。
https://babeljs.io/docs/en/babel-preset-env#loose
英語ちからが足りていない...