The idea behind the product is simple: Babel takes in ES6 or ES7 code and replaces new syntactical elements with emulation code. Its output confirms to classic JavaScript syntax and runs on older browsers like Internet Explorer.
These dependencies transformed the release process of the predecessor into a conflict-fraught affair. Version 7, still managed by a small maintainer team, thus tried to be as compatible as possible. Breaking changes are few and far between, while code generation quality remains high.
If you haven't worked with Babel before, let this be your guide. Being able to use advanced JavaScript features without compatibility worries makes life much easier.
01. Version check
Babel usually lives in the Node runtime environment. Let's start out by checking the versions used. The output provides the version state found on the Ubuntu 14.04 workstation used to create the following article. This isn't pedantry – the figure accompanying this step shows that the Babel team dropped support for quite a few Node.js versions.tamhan@tamhan-thinkpad:~$ node --version
v8.14.0
tamhan@tamhan-thinkpad:~$ npm --version
6.4.1
02. Change of package names
One breaking change in version 7 has involved moving the Babel packages into their own namespace. Older packages were not removed from the various repositories. This is important, as the use of legacy package names leads to the situation shown in the figure accompanying this step.tamhan@tamhan-thinkpad:~/workspaceB7$ npm
install --save-dev @babel/core @babel/cli @
babel/preset-env @babel/node
. . .
+ @babel/core@7.2.0
+ @babel/node@7.2.0
+ @babel/cli@7.2.0
+ @babel/preset-env@7.2.0
03. Add a build action
The step above assumes that you work inside of an npm project. In that case, running Babel via the build action is easy. Open package.json and modify it as demonstrated in the code below:{
. . .
"main": "index.js",
"scripts": {
"test": "echo \"Error: no test
specified\" && exit 1",
"build": "babel index.js -d lib"
},
04. Transpile code by hand
Putting Babel to work involves firing off the build action. This is best accomplished via the npm run command. The -d value informs Babel that the results must be placed in the lib folder – the figure accompanying this step shows that the folder gets created on the fly.tamhan@tamhan-thinkpad:~/workspaceB7$ npm
run build
> workspaceb7@1.0.0 build /home/tamhan/
workspaceB7
> babel index.js -d lib
Successfully compiled 1 file with Babel.
05. A question of configuration
Invoking Babel without further configuration options does not enable transpilation. Code can be transpiled only if the framework receives further information about the target environment. This can be done via a command line parameter, or by creating a file called .babelrc in the project root.06. Configure the babelrc
Babel configures itself via a set of plugins, each of which applies transpilation transforms to the code base. We use the preset-env package – it comes with a pre-configured set of transformations intended to cover most bases.{
"presets": ["@babel/preset-env"]
}
07. Time for a test drive
Add a bit of new-age JavaScript to index.js to test the program against some live code. The code accompanying this step would not work on legacy browsers – when done, the implicit function gets replaced with a normal declaration, as shown in the figure.function tamstest(){
[1, 2, 3].map((n) => n + 1);
}
08. Adjust targeting
preset-env applies most transpilations by default: the product's goal is to create universally compatible JavaScript without regard to bandwidth and performance costs. You can change its configuration by passing in a targets object – the example below targets specific versions of Chrome and IE.{
"presets": [
[
"@babel/preset-env",
{
"targets": {
"chrome": "58",
"ie": "11"
}
}
]
]
}
09. Advanced targeting
Babel's browser targeting isn't limited to Chrome and Internet Explorer. Thanks to cooperation with browserslist, developers can mix and match from more than a dozen targets, as shown below.Names are case insensitive:
- Android for Android WebView.
- Baidu for Baidu Browser.
- BlackBerry or bb for Blackberry browser.
- Chrome for Google Chrome.
- ChromeAndroid or and_chr for Chrome for Android.
- Edge for Microsoft Edge.
- Electron for Electron framework. It will be converted to Chrome version.
- Explorer or ie for Internet Explorer.
- ExplorerMobile or ie_mob for Internet Explorer Mobile.
- Firefox or ff for Mozilla Firefox.
- FirefoxAndroid or and_ff for Firefox for Android.
- iOS or ios_saf for iOS Safari.
- Node for Node.js.Opera for Opera.
- OperaMini or op_mini for Opera Mini.
- OperaMobile or op_mob for Opera Mobile.
- QQAndroid or and_qq for QQ Browser for Android.
- Safari for desktop Safari.
- Samsung for Samsung Internet.
- UCAndroid or and_uc for UC Browser for Android.
10. Advanced targeting, part two
Browserlist can also take advanced queries. Its homepage lists the configuration options, almost all of which can also be used inside Babel by modifying babelrc. Queries can be evaluated locally if your workstation has npx installed.{ "targets": "> 0.25%, not dead"
}
11. Automatic transpilation
Having to invoke Babel by hand gets tedious quickly. The nodemon utility monitors filesystem resources and fires off commands as changes get detected. In theory, adding nodemon support is handled via a small change to package.json.{
"name": "workspaceb7",
. . .
"main": "index.js",
"scripts":
{
"start": "nodemon --exec babel-node
index.js",
12. Check for presence
Some workstations have nodemon installed globally. If this is not the case, invoking the program will yield an error message similar to the one shown below. Fortunately, deploying nodemon is easily accomplished via the npm install command.tamhan@tamhan-thinkpad:~/workspaceB7$ npm
install --save-dev nodemon
13. Check functionality
Fire off npm start in a terminal window and proceed to change the content of index.js with an editor like gedit or Visual Studio Code. After saving, nodemonwill output status information.[nodemon] restarting due to changes...
[nodemon] starting `babel-node index.js`
[nodemon] clean exit - waiting for changes
before restart
14. Fix transpilation
While nodemon's detection should work flawlessly at this point, the contents of the index.js file that are found in lib do not update. This is caused by a nicety of babel-node – it does not commit the transpiled files to the disk. It instead fires off a modified version of the Node CLI, which works with the transpiled files.15. Transpile code programmatically
Babel isn't limited to working on the command line. If the correct packages are installed, code can also be transpiled from another program. The snippet accompanying this step applies a set of basic transformations to an input string. Keep in mind that the configuration settings, usually, are obtained from a babelrc file.var babel = require("@babel/core");
import { transform } from "@babel/core";
import * as babel from "@babel/core";
babel.transform("code();", options,
function(err, result) {
result.code;
result.map;
result.ast;
});
16. Transpile entire files
Source code usually does not get stored in string variables. The Babel API accounts for this via a set of file-related functions, which forgo the input string for a variable with a filename. The results, however, get returned as a normal JavaScript variable.babel.transformFile("filename.js", options,
function (err, result) {
result; // => { code, map, ast }
}
);
17. Sync and async
Babel 7 introduced synchronous and asynchronous versions of most API calls. Make sure to pick the right one for your needs – while transpiling small examples can be done on the fly, setting Babel loose on more complex files can easily lead to delays running into dozens of seconds.18. Learn about individual plugins
Should you ever find yourself wondering about what happens in the background, simply visit this page. It provides a list of all plugins currently contained in the Babel distribution, and also contains a few hints for all those seeking to create a plugin of their own.19. Strip out TypeScript specifics
Babel isn't limited to transpiling new-age JavaScript elements. The product contains a feature-constrained TypeScript engine. It strips out typing information and replaces advanced elements. Sadly, Babel does not perform type-checking – this eliminates one of the most significant benefits of the TypeScript language.{
"presets": ["@babel/preset-typescript"]
}
No comments:
Post a Comment