UNPKG

16.1 kBMarkdownView Raw
1[npm]: https://img.shields.io/npm/v/@rollup/plugin-babel
2[npm-url]: https://www.npmjs.com/package/@rollup/plugin-babel
3[size]: https://packagephobia.now.sh/badge?p=@rollup/plugin-babel
4[size-url]: https://packagephobia.now.sh/result?p=@rollup/plugin-babel
5
6[![npm][npm]][npm-url]
7[![size][size]][size-url]
8[![libera manifesto](https://img.shields.io/badge/libera-manifesto-lightgrey.svg)](https://liberamanifesto.com)
9
10# @rollup/plugin-babel
11
12🍣 A Rollup plugin for seamless integration between Rollup and Babel.
13
14## Why?
15
16If you're using Babel to transpile your ES6/7 code and Rollup to generate a standalone bundle, you have a couple of options:
17
18- run the code through Babel first, being careful to exclude the module transformer, or
19- run the code through Rollup first, and _then_ pass it to Babel.
20
21Both approaches have disadvantages – in the first case, on top of the additional configuration complexity, you may end up with Babel's helpers (like `classCallCheck`) repeated throughout your code (once for each module where the helpers are used). In the second case, transpiling is likely to be slower, because transpiling a large bundle is much more work for Babel than transpiling a set of small files.
22
23Either way, you have to worry about a place to put the intermediate files, and getting sourcemaps to behave becomes a royal pain.
24
25Using Rollup with `@rollup/plugin-babel` makes the process far easier.
26
27## Requirements
28
29This plugin requires an [LTS](https://github.com/nodejs/Release) Node version (v10.0.0+) and Rollup v1.20.0+.
30
31## Install
32
33```bash
34npm install @rollup/plugin-babel --save-dev
35```
36
37## Usage
38
39Create a `rollup.config.js` [configuration file](https://www.rollupjs.org/guide/en/#configuration-files) and import the plugin:
40
41```js
42import { babel } from '@rollup/plugin-babel';
43
44const config = {
45 input: 'src/index.js',
46 output: {
47 dir: 'output',
48 format: 'esm'
49 },
50 plugins: [babel({ babelHelpers: 'bundled' })]
51};
52
53export default config;
54```
55
56Then call `rollup` either via the [CLI](https://www.rollupjs.org/guide/en/#command-line-reference) or the [API](https://www.rollupjs.org/guide/en/#javascript-api).
57
58### Using With `@rollup/plugin-commonjs`
59
60When using `@rollup/plugin-babel` with `@rollup/plugin-commonjs` in the same Rollup configuration, it's important to note that `@rollup/plugin-commonjs` _must_ be placed before this plugin in the `plugins` array for the two to work together properly. e.g.
61
62```js
63import { babel } from '@rollup/plugin-babel';
64import commonjs from '@rollup/plugin-commonjs';
65
66const config = {
67 ...
68 plugins: [
69 commonjs(),
70 babel({ babelHelpers: 'bundled' })
71 ],
72};
73```
74
75## Options
76
77This plugin respects Babel [configuration files](https://babeljs.io/docs/en/configuration) by default and they are generally the best place to put your configuration.
78
79You can also run Babel on the generated chunks instead of the input files. Even though this is slower, it is the only way to transpile Rollup's auto-generated wrapper code to lower compatibility targets than ES5, see [Running Babel on the generated code](#running-babel-on-the-generated-code) for details.
80
81All options are as per the [Babel documentation](https://babeljs.io/docs/en/options), plus the following:
82
83### `exclude`
84
85Type: `String | RegExp | Array[...String|RegExp]`<br>
86
87A [minimatch pattern](https://github.com/isaacs/minimatch), or array of patterns, which specifies the files in the build the plugin should _ignore_. When relying on Babel configuration files you can only exclude additional files with this option, you cannot override what you have configured for Babel itself.
88
89### `include`
90
91Type: `String | RegExp | Array[...String|RegExp]`<br>
92
93A [minimatch pattern](https://github.com/isaacs/minimatch), or array of patterns, which specifies the files in the build the plugin should operate on. When relying on Babel configuration files you cannot include files already excluded there.
94
95### `filter`
96
97Type: (id: string) => boolean<br>
98
99Custom [filter function](https://github.com/rollup/plugins/tree/master/packages/pluginutils#createfilter) can be used to determine whether or not certain modules should be operated upon.
100
101Usage:
102
103```js
104import { createFilter } from '@rollup/pluginutils';
105const include = 'include/**.js';
106const exclude = 'exclude/**.js';
107const filter = createFilter(include, exclude, {});
108```
109
110### `extensions`
111
112Type: `Array[...String]`<br>
113Default: `['.js', '.jsx', '.es6', '.es', '.mjs']`
114
115An array of file extensions that Babel should transpile. If you want to transpile TypeScript files with this plugin it's essential to include `.ts` and `.tsx` in this option.
116
117### `babelHelpers`
118
119Type: `'bundled' | 'runtime' | 'inline' | 'external'`<br>
120Default: `'bundled'`
121
122It is recommended to configure this option explicitly (even if with its default value) so an informed decision is taken on how those babel helpers are inserted into the code.
123
124We recommend to follow these guidelines to determine the most appropriate value for your project:
125
126- `'runtime'` - you should use this especially when building libraries with Rollup. It has to be used in combination with `@babel/plugin-transform-runtime` and you should also specify `@babel/runtime` as dependency of your package. Don't forget to tell Rollup to treat the helpers imported from within the `@babel/runtime` module as external dependencies when bundling for `cjs` & `es` formats. This can be accomplished via regex (`external: [/@babel\/runtime/]`) or a function (`external: id => id.includes('@babel/runtime')`). It's important to not only specify `external: ['@babel/runtime']` since the helpers are imported from nested paths (e.g `@babel/runtime/helpers/get`) and [Rollup will only exclude modules that match strings exactly](https://rollupjs.org/guide/en/#peer-dependencies).
127- `'bundled'` - you should use this if you want your resulting bundle to contain those helpers (at most one copy of each). Useful especially if you bundle an application code.
128- `'external'` - use this only if you know what you are doing. It will reference helpers on **global** `babelHelpers` object. Used in combination with `@babel/plugin-external-helpers`.
129- `'inline'` - this is not recommended. Helpers will be inserted in each file using this option. This can cause serious code duplication. This is the default Babel behavior as Babel operates on isolated files - however, as Rollup is a bundler and is project-aware (and therefore likely operating across multiple input files), the default of this plugin is `"bundled"`.
130
131### `skipPreflightCheck`
132
133Type: `Boolean`<br>
134Default: `false`
135
136Before transpiling your input files this plugin also transpile a short piece of code **for each** input file. This is used to validate some misconfiguration errors, but for sufficiently big projects it can slow your build times so if you are confident about your configuration then you might disable those checks with this option.
137
138### External dependencies
139
140Ideally, you should only be transforming your source code, rather than running all of your external dependencies through Babel (to ignore external dependencies from being handled by this plugin you might use `exclude: 'node_modules/**'` option). If you have a dependency that exposes untranspiled ES6 source code that doesn't run in your target environment, then you may need to break this rule, but it often causes problems with unusual `.babelrc` files or mismatched versions of Babel.
141
142We encourage library authors not to distribute code that uses untranspiled ES6 features (other than modules) for this reason. Consumers of your library should _not_ have to transpile your ES6 code, any more than they should have to transpile your CoffeeScript, ClojureScript or TypeScript.
143
144Use `babelrc: false` to prevent Babel from using local (i.e. to your external dependencies) `.babelrc` files, relying instead on the configuration you pass in.
145
146### Helpers
147
148In some cases Babel uses _helpers_ to avoid repeating chunks of code – for example, if you use the `class` keyword, it will use a `classCallCheck` function to ensure that the class is instantiated correctly.
149
150By default, those helpers will be inserted at the top of the file being transformed, which can lead to duplication. This rollup plugin automatically deduplicates those helpers, keeping only one copy of each one used in the output bundle. Rollup will combine the helpers in a single block at the top of your bundle.
151
152You can customize how those helpers are being inserted into the transformed file with [`babelHelpers`](#babelhelpers) option.
153
154### Modules
155
156This is not needed since Babel 7 - it knows automatically that Rollup understands ES modules & that it shouldn't use any module transform with it. Unless you forcefully include a module transform in your Babel configuration.
157
158If you have been pointed to this section by an error thrown by this plugin, please check your Babel configuration files and disable any module transforms when running Rollup builds.
159
160## Running Babel on the generated code
161
162You can run `@rollup/plugin-babel` on the output files instead of the input files by using `getBabelOutputPlugin(...)`. This can be used to perform code transformations on the resulting chunks and is the only way to transform Rollup's auto-generated code. By default, the plugin will be applied to all outputs:
163
164```js
165// rollup.config.js
166import { getBabelOutputPlugin } from '@rollup/plugin-babel';
167
168export default {
169 input: 'main.js',
170 plugins: [
171 getBabelOutputPlugin({
172 presets: ['@babel/preset-env']
173 })
174 ],
175 output: [
176 { file: 'bundle.cjs.js', format: 'cjs' },
177 { file: 'bundle.esm.js', format: 'esm' }
178 ]
179};
180```
181
182If you only want to apply it to specific outputs, you can use it as an output plugin (requires at least Rollup v1.27.0):
183
184```js
185// rollup.config.js
186import { getBabelOutputPlugin } from '@rollup/plugin-babel';
187
188export default {
189 input: 'main.js',
190 output: [
191 { file: 'bundle.js', format: 'esm' },
192 {
193 file: 'bundle.es5.js',
194 format: 'esm',
195 plugins: [getBabelOutputPlugin({ presets: ['@babel/preset-env'] })]
196 }
197 ]
198};
199```
200
201The `include`, `exclude` and `extensions` options are ignored when the when using `getBabelOutputPlugin` and `createBabelOutputPluginFactory` will produce warnings, and there are a few more points to note that users should be aware of.
202
203You can also run the plugin twice on the code, once when processing the input files to transpile special syntax to JavaScript and once on the output to transpile to a lower compatibility target:
204
205```js
206// rollup.config.js
207import babel, { getBabelOutputPlugin } from '@rollup/plugin-babel';
208
209export default {
210 input: 'main.js',
211 plugins: [babel({ presets: ['@babel/preset-react'] })],
212 output: [
213 {
214 file: 'bundle.js',
215 format: 'esm',
216 plugins: [getBabelOutputPlugin({ presets: ['@babel/preset-env'] })]
217 }
218 ]
219};
220```
221
222### Babel configuration files
223
224Unlike the regular `babel` plugin, `getBabelOutputPlugin(...)` will **not** automatically search for [Babel configuration files](https://babeljs.io/docs/en/config-files). Besides passing in Babel options directly, however, you can specify a configuration file manually via Babel's [`configFile`](https://babeljs.io/docs/en/options#configfile) option:
225
226```js
227getBabelOutputPlugin({
228 configFile: path.resolve(__dirname, 'babel.config.js')
229});
230```
231
232### Using formats other than ES modules or CommonJS
233
234As `getBabelOutputPlugin(...)` will run _after_ Rollup has done all its transformations, it needs to make sure it preserves the semantics of Rollup's output format. This is especially important for Babel plugins that add, modify or remove imports or exports, but also for other transformations that add new variables as they can accidentally become global variables depending on the format. Therefore it is recommended that for formats other than `esm` or `cjs`, you set Rollup to use the `esm` output format and let Babel handle the transformation to another format, e.g. via
235
236```
237presets: [['@babel/preset-env', { modules: 'umd' }], ...]
238```
239
240to create a UMD/IIFE compatible output. If you want to use `getBabelOutputPlugin(...)` with other formats, you need to specify `allowAllFormats: true` as plugin option:
241
242```js
243rollup.rollup({...})
244.then(bundle => bundle.generate({
245 format: 'iife',
246 plugins: [getBabelOutputPlugin({
247 allowAllFormats: true,
248 // ...
249 })]
250}))
251```
252
253### Injected helpers
254
255By default, helpers e.g. when transpiling classes will be inserted at the top of each chunk. In contrast to when applying this plugin on the input files, helpers will not be deduplicated across chunks.
256
257Alternatively, you can use imported runtime helpers by adding the `@babel/transform-runtime` plugin. This will make `@babel/runtime` an external dependency of your project, see [@babel/plugin-transform-runtime](https://babeljs.io/docs/en/babel-plugin-transform-runtime) for details.
258
259Note that this will only work for `esm` and `cjs` formats, and you need to make sure to set the `useESModules` option of `@babel/plugin-transform-runtime` to `true` if you create ESM output:
260
261```js
262rollup.rollup({...})
263.then(bundle => bundle.generate({
264 format: 'esm',
265 plugins: [getBabelOutputPlugin({
266 presets: ['@babel/preset-env'],
267 plugins: [['@babel/plugin-transform-runtime', { useESModules: true }]]
268 })]
269}))
270```
271
272```js
273// input
274export default class Foo {}
275
276// output
277import _classCallCheck from '@babel/runtime/helpers/esm/classCallCheck';
278
279var Foo = function Foo() {
280 _classCallCheck(this, Foo);
281};
282
283export default Foo;
284```
285
286And for CommonJS:
287
288```js
289rollup.rollup({...})
290.then(bundle => bundle.generate({
291 format: 'cjs',
292 plugins: [getBabelOutputPlugin({
293 presets: ['@babel/preset-env'],
294 plugins: [['@babel/plugin-transform-runtime', { useESModules: false }]]
295 })]
296}))
297```
298
299```js
300// input
301export default class Foo {}
302
303// output
304('use strict');
305
306var _classCallCheck = require('@babel/runtime/helpers/classCallCheck');
307
308var Foo = function Foo() {
309 _classCallCheck(this, Foo);
310};
311
312module.exports = Foo;
313```
314
315Another option is to use `@babel/plugin-external-helpers`, which will reference the global `babelHelpers` object. It is your responsibility to make sure this global variable exists.
316
317## Custom plugin builder
318
319`@rollup/plugin-babel` exposes a plugin-builder utility that allows users to add custom handling of Babel's configuration for each file that it processes.
320
321`createBabelInputPluginFactory` accepts a callback that will be called with the loader's instance of `babel` so that tooling can ensure that it using exactly the same `@babel/core` instance as the loader itself.
322
323It's main purpose is to allow other tools for configuration of transpilation without forcing people to add extra configuration but still allow for using their own babelrc / babel config files.
324
325### Example
326
327```js
328import { createBabelInputPluginFactory } from '@rollup/plugin-babel';
329
330export default createBabelInputPluginFactory((babelCore) => {
331 function myPlugin() {
332 return {
333 visitor: {}
334 };
335 }
336
337 return {
338 // Passed the plugin options.
339 options({ opt1, opt2, ...pluginOptions }) {
340 return {
341 // Pull out any custom options that the plugin might have.
342 customOptions: { opt1, opt2 },
343
344 // Pass the options back with the two custom options removed.
345 pluginOptions
346 };
347 },
348
349 config(cfg /* Passed Babel's 'PartialConfig' object. */, { code, customOptions }) {
350 if (cfg.hasFilesystemConfig()) {
351 // Use the normal config
352 return cfg.options;
353 }
354
355 return {
356 ...cfg.options,
357 plugins: [
358 ...(cfg.options.plugins || []),
359
360 // Include a custom plugin in the options.
361 myPlugin
362 ]
363 };
364 },
365
366 result(result, { code, customOptions, config, transformOptions }) {
367 return {
368 ...result,
369 code: result.code + '\n// Generated by some custom plugin'
370 };
371 }
372 };
373});
374```
375
376## Meta
377
378[CONTRIBUTING](/.github/CONTRIBUTING.md)
379
380[LICENSE (MIT)](/LICENSE)