Skip to content

Latest commit

 

History

History
823 lines (564 loc) · 28.5 KB

user-handbook.md

File metadata and controls

823 lines (564 loc) · 28.5 KB

Manuel utilisateur de Babel

Ce document couvre tout ce que vous avez toujours voulu savoir sur l'utilisation de Babel et des outils associés.

cc-by-4.0

Ce manuel est disponible dans d'autres langues, voir le README pour une liste complète.

Sommaire

Introduction

Babel est un compilateur générique et multi-usage pour JavaScript. L'utilisation de Babel, vous permet d'utiliser (et de créer) la prochaine génération de JavaScript, aussi bien que la prochaine génération des outils JavaScript.

JavaScript est un langage en constante évolution, avec sans cesse de nouvelles spécifications, propositions et fonctionnalités. L'usage de Babel vous permettra d'utiliser un grand nombre de ces fonctionnalités des années avant qu'elles ne soient disponibles partout.

Babel fait cela en compilant le code JavaScript écrit avec le dernier standard dans une version fonctionnant partout aujourd'hui. Ce processus est connu comme de la compilation de source à source, aussi connu sous le nom de transpilation.

Par exemple, Babel pourrait transformer la syntaxe de la nouvelle fonction fléchée, de ceci :

const square = n => n * n;

En cela :

const square = function square(n) {
   return n * n;
};

Cependant, Babel peut faire beaucoup plus, comme le support des extensions de syntaxe telles que JSX pour React et le support de Flow pour la vérification de type statique.

De plus, dans Babel tout est composé de module, et n'importe qui peut créer le sien en utilisant toute la puissance de Babel pour en faire ce qu'il souhaite.

Bien plus encore, Babel est décomposé en un certain nombre de modules de base que n'importe qui peut utiliser pour construire la prochaine génération d'outils pour JavaScript.

Beaucoup de gens l'ont déjà fait, et l'écosystème qui a surgi autour de Babel est massif et très diversifié. Tout au long de ce guide, que je vais couvrir ces deux aspects, comment les outils intégrés de Babel fonctionnent ainsi que des choses utiles provenant de la communauté.

Pour les prochaines mises à jour, suivez @thejameskyle sur Twitter.


Mise en place de Babel

Puisque la communauté JavaScript dispose d'une multitude d'outils de construction, de frameworks, de plateformes, etc., Babel fournit des intégrations officielles pour la majorité des outils. Peu importe votre configuration, en allant de Gulp à Browserify, ou bien d'Ember à Meteor, il y a probablement une intégration officielle.

Dans le cadre de ce guide, nous allons seulement couvrir les méthodes par défaut pour configurer Babel, mais vous pouvez également visiter la page de configuration interactive pour les autres intégrations.

Remarque : Ce guide va se référer à des outils de ligne de commande comme node et npm. Avant d'aller plus loin, vous devez être à l'aise avec ces outils.

babel-cli

Babel's CLI is a simple way to compile files with Babel from the command line.

Let's first install it globally to learn the basics.

$ npm install --global babel-cli

We can compile our first file like so:

$ babel my-file.js

This will dump the compiled output directly into your terminal. To write it to a file we'll specify an --out-file or -o.

$ babel example.js --out-file compiled.js
# or
$ babel example.js -o compiled.js

If we want to compile a whole directory into a new directory we can do so using --out-dir or -d.

$ babel src --out-dir lib
# or
$ babel src -d lib

Exécution du CLI de Babel dans un projet

While you can install Babel CLI globally on your machine, it's much better to install it locally project by project.

There are two primary reasons for this.

  1. Different projects on the same machine can depend on different versions of Babel allowing you to update one at a time.
  2. It means you do not have an implicit dependency on the environment you are working in. Making your project far more portable and easier to setup.

We can install Babel CLI locally by running:

$ npm install --save-dev babel-cli

Note: Since it's generally a bad idea to run Babel globally you may want to uninstall the global copy by running:

$ npm uninstall --global babel-cli


After that finishes installing, your `package.json` file should look like this:

```json
{
  "name": "my-project",
  "version": "1.0.0",
  "devDependencies": {
    "babel-cli": "^6.0.0"
  }
}

Now instead of running Babel directly from the command line we're going to put our commands in npm scripts which will use our local version.

Simply add a "scripts" field to your package.json and put the babel command inside there as build.

  {
    "name": "my-project",
    "version": "1.0.0",
+   "scripts": {
+     "build": "babel src -d lib"
+   },
    "devDependencies": {
      "babel-cli": "^6.0.0"
    }
  }

Now from our terminal we can run:

npm run build

This will run Babel the same way as before, only now we are using a local copy.

babel-register

The next most common method of running Babel is through babel-register. This option will allow you to run Babel just by requiring files, which may integrate with your setup better.

Note that this is not meant for production use. It's considered bad practice to deploy code that gets compiled this way. It is far better to compile ahead of time before deploying. However this works quite well for build scripts or other things that you run locally.

First let's create an index.js file in our project.

console.log("Hello world!");

If we were to run this with node index.js this wouldn't be compiled with Babel. So instead of doing that, we'll setup babel-register.

First install babel-register.

$ npm install --save-dev babel-register

Next, create a register.js file in the project and write the following code:

require("babel-register");
require("./index.js");

What this does is registers Babel in Node's module system and begins compiling every file that is require'd.

Now, instead of running node index.js we can use register.js instead.

$ node register.js

Note: You can't register Babel in the same file that you want to compile. As node is executing the file before Babel has a chance to compile it.

require("babel-register"); // not compiled: console.log("Hello world!");


## <a id="toc-babel-node"></a>`babel-node`

If you are just running some code via the `node` CLI the easiest way to integrate Babel might be to use the `babel-node` CLI which largely is just a drop in replacement for the `node` CLI.

Note that this is not meant for production use. It's considered bad practice to deploy code that gets compiled this way. It is far better to compile ahead of time before deploying. However this works quite well for build scripts or other things that you run locally.

First make sure that you have `babel-cli` installed.

```sh
$ npm install --save-dev babel-cli

Note: If you are wondering why we are installing this locally, please read the Running Babel CLI from within a project section above.

Then replace wherever you are running node with babel-node.

If you are using npm scripts you can simply do:

  {
    "scripts": {
-     "script-name": "node script.js"
+     "script-name": "babel-node script.js"
    }
  }

Otherwise you'll need to write out the path to babel-node itself.

- node script.js
+ ./node_modules/.bin/babel-node script.js

Tip: You can also use npm-run.

babel-core

If you need to use Babel programmatically for some reason, you can use the babel-core package itself.

First install babel-core.

$ npm install babel-core
var babel = require("babel-core");

If you have a string of JavaScript you can compile it directly using babel.transform.

babel.transform("code();", options);
// => { code, map, ast }

If you are working with files you can use either the asynchronous api:

babel.transformFile("filename.js", options, function(err, result) {
  result; // => { code, map, ast }
});

Or the synchronous api:

babel.transformFileSync("filename.js", options);
// => { code, map, ast }

If you already have a Babel AST for whatever reason you may transform from the AST directly.

babel.transformFromAst(ast, code, options);
// => { code, map, ast }

For all of the above methods, options refers to http://babeljs.io/docs/usage/options/.


Configuration de Babel

You may have noticed by now that running Babel on its own doesn't seem to do anything other than copy JavaScript files from one location to another.

This is because we haven't told Babel to do anything yet.

Since Babel is a general purpose compiler that gets used in a myriad of different ways, it doesn't do anything by default. You have to explicitly tell Babel what it should be doing.

You can give Babel instructions on what to do by installing plugins or presets (groups of plugins).

.babelrc

Before we start telling Babel what to do. We need to create a configuration file. All you need to do is create a .babelrc file at the root of your project. Start off with it like this:

{
  "presets": [],
  "plugins": []
}

This file is how you configure Babel to do what you want.

Note: While you can also pass options to Babel in other ways the .babelrc file is convention and is the best way.

babel-preset-es2015

Let's start by telling Babel to compile ES2015 (the newest version of the JavaScript standard, also known as ES6) to ES5 (the version available in most JavaScript environments today).

We'll do this by installing the "es2015" Babel preset:

$ npm install --save-dev babel-preset-es2015

Next we'll modify our .babelrc to include that preset.

  {
    "presets": [
+     "es2015"
    ],
    "plugins": []
  }

babel-preset-react

Setting up React is just as easy. Just install the preset:

$ npm install --save-dev babel-preset-react

Then add the preset to your .babelrc file:

  {
    "presets": [
      "es2015",
+     "react"
    ],
    "plugins": []
  }

babel-preset-stage-x

JavaScript also has some proposals that are making their way into the standard through the TC39's (the technical committee behind the ECMAScript standard) process.

This process is broken through a 5 stage (0-4) process. As proposals gain more traction and are more likely to be accepted into the standard they proceed through the various stages, finally being accepted into the standard at stage 4.

These are bundled in babel as 4 different presets:

  • babel-preset-stage-0
  • babel-preset-stage-1
  • babel-preset-stage-2
  • babel-preset-stage-3

Note that there is no stage-4 preset as it is simply the es2015 preset above.

Each of these presets requires the preset for the later stages. i.e. babel-preset-stage-1 requires babel-preset-stage-2 which requires babel-preset-stage-3.

Simply install the stage you are interested in using:

$ npm install --save-dev babel-preset-stage-2

Then you can add it to your .babelrc config.

  {
    "presets": [
      "es2015",
      "react",
+     "stage-2"
    ],
    "plugins": []
  }

Exécution de code généré par Babel

So you've compiled your code with Babel, but this is not the end of the story.

babel-polyfill

Almost all futuristic JavaScript syntax can be compiled with Babel, but the same is not true for APIs.

For example, the following code has an arrow function that needs to be compiled:

function addAll() {
  return Array.from(arguments).reduce((a, b) => a + b);
}

Which turns into this:

function addAll() {
  return Array.from(arguments).reduce(function(a, b) {
    return a + b;
  });
}

However, this still won't work everywhere because Array.from doesn't exist in every JavaScript environment.

Uncaught TypeError: Array.from is not a function

To solve this problem we use something called a Polyfill. Simply put, a polyfill is a piece of code that replicates a native api that does not exist in the current runtime. Allowing you to use APIs such as Array.from before they are available.

Babel uses the excellent core-js as its polyfill, along with a customized regenerator runtime for getting generators and async functions working.

To include the Babel polyfill, first install it with npm:

$ npm install --save babel-polyfill

Then simply include the polyfill at the top of any file that requires it:

import "babel-polyfill";

babel-runtime

In order to implement details of ECMAScript specs, Babel will use "helper" methods in order to keep the generated code clean.

Since these helpers can get pretty long, and they get added to the top of every file you can move them into a single "runtime" which gets required.

Start by installing babel-plugin-transform-runtime and babel-runtime:

$ npm install --save-dev babel-plugin-transform-runtime
$ npm install --save babel-runtime

Then update your .babelrc:

  {
    "plugins": [
+     "transform-runtime",
      "transform-es2015-classes"
    ]
  }

Now Babel will compile code like the following:

class Foo {
  method() {}
}

Into this:

import _classCallCheck from "babel-runtime/helpers/classCallCheck";
import _createClass from "babel-runtime/helpers/createClass";

let Foo = function () {
  function Foo() {
    _classCallCheck(this, Foo);
  }

  _createClass(Foo, [{
    key: "method",
    value: function method() {}
  }]);

  return Foo;
}();

Rather than putting the _classCallCheck and _createClass helpers in every single file where they are needed.


Configuration de Babel (Avancé)

Most people can get by using Babel with just the built-in presets, but Babel exposes much finer-grained power than that.

Spécification manuelle des plugins

Babel presets are simply collections of pre-configured plugins, if you want to do something differently you manually specify plugins. This works almost exactly the same way as presets.

First install a plugin:

$ npm install --save-dev babel-plugin-transform-es2015-classes

Then add the plugins field to your .babelrc.

  {
+   "plugins": [
+     "transform-es2015-classes"
+   ]
  }

This gives you much finer grained control over the exact transforms you are running.

For a full list of official plugins see the Babel Plugins page.

Also take a look at all the plugins that have been built by the community. If you would like to learn how to write your own plugin read the Babel Plugin Handbook.

Options du Plugin

Many plugins also have options to configure them to behave differently. For example, many transforms have a "loose" mode which drops some spec behavior in favor of simpler and more performant generated code.

To add options to a plugin, simply make the following change:

  {
    "plugins": [
-     "transform-es2015-classes"
+     ["transform-es2015-classes", { "loose": true }]
    ]
  }

I'll be working on updates to the plugin documentation to detail every option in the coming weeks. Follow me for updates.

Personnalisation de Babel basé sur l'environnement

Babel plugins solve many different tasks. Many of them are development tools that can help you debugging your code or integrate with tools. There are also a lot of plugins that are meant for optimizing your code in production.

For this reason, it is common to want Babel configuration based on the environment. You can do this easily with your .babelrc file.

  {
    "presets": ["es2015"],
    "plugins": [],
+   "env": {
+     "development": {
+       "plugins": [...]
+     },
+     "production": {
+       "plugins": [...]
+     }
    }
  }

Babel will enable configuration inside of env based on the current environment.

The current environment will use process.env.BABEL_ENV. When BABEL_ENV is not available, it will fallback to NODE_ENV, and if that is not available it will default to "development".

Unix

$ BABEL_ENV=production [COMMAND]
$ NODE_ENV=production [COMMAND]

Windows

$ SET BABEL_ENV=production
$ [COMMAND]

Note: [COMMAND] is whatever you use to run Babel (ie. babel, babel-node, or maybe just node if you are using the register hook).

Tip: If you want your command to work across unix and windows platforms then use cross-env.

Faire votre propre preset

Manually specifying plugins? Plugin options? Environment-based settings? All this configuration might seem like a ton of repetition for all of your projects.

For this reason, we encourage the community to create their own presets. This could be a preset for the specific node version you are running, or maybe a preset for your entire company.

It's easy to create a preset. Say you have this .babelrc file:

{
  "presets": [
    "es2015",
    "react"
  ],
  "plugins": [
    "transform-flow-strip-types"
  ]
}

All you need to do is create a new project following the naming convention babel-preset-* (please be responsible with this namespace), and create two files.

First, create a new package.json file with the necessary dependencies for your preset.

{
  "name": "babel-preset-my-awesome-preset",
  "version": "1.0.0",
  "author": "James Kyle <[email protected]>",
  "dependencies": {
    "babel-preset-es2015": "^6.3.13",
    "babel-preset-react": "^6.3.13",
    "babel-plugin-transform-flow-strip-types": "^6.3.15"
  }
}

Then create an index.js file that exports the contents of your .babelrc file, replacing plugin/preset strings with require calls.

module.exports = {
  presets: [
    require("babel-preset-es2015"),
    require("babel-preset-react")
  ],
  plugins: [
    require("babel-plugin-transform-flow-strip-types")
  ]
};

Then simply publish this to npm and you can use it like you would any preset.


Babel et les autres outils

Babel is pretty straight forward to setup once you get the hang of it, but it can be rather difficult navigating how to set it up with other tools. However, we try to work closely with other projects in order to make the experience as easy as possible.

Outils d'analyse statique

Newer standards bring a lot of new syntax to the language and static analysis tools are just starting to take advantage of it.

Linting

One of the most popular tools for linting is ESLint, because of this we maintain an official babel-eslint integration.

First install eslint and babel-eslint.

$ npm install --save-dev eslint babel-eslint

Note: babel-eslint compatibility with Babel 6 is currently in a pre-release version. Install the latest 5.0 beta in order to use it with Babel 6.

Next create or use the existing .eslintrc file in your project and set the parser as babel-eslint.

  {
+   "parser": "babel-eslint",
    "rules": {
      ...
    }
  }

Now add a lint task to your npm package.json scripts:

  {
    "name": "my-module",
    "scripts": {
+     "lint": "eslint my-files.js"
    },
    "devDependencies": {
      "babel-eslint": "...",
      "eslint": "..."
    }
  }

Then just run the task and you will be all setup.

$ npm run lint

For more information consult the babel-eslint or eslint documentation.

Style de code

JSCS is an extremely popular tool for taking linting a step further into checking the style of the code itself. A core maintainer of both the Babel and JSCS projects (@hzoo) maintains an official integration with JSCS.

Even better, this integration now lives within JSCS itself under the --esnext option. So integrating Babel is as easy as:

$ jscs . --esnext

From the cli, or adding the esnext option to your .jscsrc file.

  {
    "preset": "airbnb",
+   "esnext": true
  }

For more information consult the babel-jscs or jscs documentation.

Documentation

Using Babel, ES2015, and Flow you can infer a lot about your code. Using documentation.js you can generate detailed API documentation very easily.

Documentation.js uses Babel behind the scenes to support all of the latest syntax including Flow annotations in order to declare the types in your code.

Frameworks

All of the major JavaScript frameworks are now focused on aligning their APIs around the future of the language. Because of this, there has been a lot of work going into the tooling.

Frameworks have the opportunity not just to use Babel but to extend it in ways that improve their users' experience.

React

React has dramatically changed their API to align with ES2015 classes (Read about the updated API here). Even further, React relies on Babel to compile it's JSX syntax, deprecating it's own custom tooling in favor of Babel. You can start by setting up the babel-preset-react package following the instructions above.

The React community took Babel and ran with it. There are now a number of transforms built by the community.

Most notably the babel-plugin-react-transform plugin which combined with a number of React-specific transforms can enable things like hot module reloading and other debugging utilities.

IDEs et les éditeurs de texte

Introducing ES2015, JSX, and Flow syntax with Babel can be helpful, but if your text editor doesn't support it then it can be a really bad experience. For this reason you will want to setup your text editor or IDE with a Babel plugin.


Support Babel

Babel has a very large and quickly growing community, as we grow we want to ensure that people have all the resources they need to be successful. So we provide a number of different channels for getting support.

Remember that across all of these communities we enforce a Code of Conduct. If you break the Code of Conduct, action will be taken. So please read it and be conscious of it when interacting with others.

We are also looking to grow a self-supporting community, for people who stick around and support others. If you find someone asking a question you know the answer to, take a few minutes and help them out. Try your best to be kind and understanding when doing so.

Forum Babel

Discourse has provided us with a hosted version of their forum software for free (and we love them for it!). If forums are your thing please stop by discuss.babeljs.io.

Tchat Babel

Everyone loves Slack. If you're looking for immediate support from the community then come chat with us at slack.babeljs.io.

Issues (anomalies) de Babel

Babel uses the awesome issue tracker provided by Phabricator an open source software development platform that makes GitHub issues a nightmare of the past.

Babel's Phabricator is available at phabricator.babeljs.io. You can see all the open and closed issues on maniphest.

If you want to open a new issue:

Création d'un génial rapport de bogue

Babel issues can sometimes be very difficult to debug remotely, so we need all the help we can get. Spending a few more minutes crafting a really nice bug report can help get your problem solved significantly faster.

First, try isolating your problem. It's extremely unlikely that every part of your setup is contributing to the problem. If your problem is a piece of input code, try deleting as much code as possible that still causes an issue.

[WIP]


Pour les prochaines mises à jour, suivez @thejameskyle sur Twitter.