UNPKG

12.4 kBMarkdownView Raw
1> This README is for babel-loader v8 + Babel v7
2> If you are using legacy Babel v6, see the [7.x branch](https://github.com/babel/babel-loader/tree/7.x) docs
3
4[![NPM Status](https://img.shields.io/npm/v/babel-loader.svg?style=flat)](https://www.npmjs.com/package/babel-loader)
5[![codecov](https://codecov.io/gh/babel/babel-loader/branch/main/graph/badge.svg)](https://codecov.io/gh/babel/babel-loader)
6
7<div align="center">
8 <a href="https://github.com/babel/babel">
9 <img src="https://rawgit.com/babel/logo/master/babel.svg" alt="Babel logo" width="200" height="200">
10 </a>
11 <a href="https://github.com/webpack/webpack">
12 <img src="https://webpack.js.org/assets/icon-square-big.svg" alt="webpack logo" width="200" height="200">
13 </a>
14</div>
15
16<h1 align="center">Babel Loader</h1>
17
18This package allows transpiling JavaScript files using [Babel](https://github.com/babel/babel) and [webpack](https://github.com/webpack/webpack).
19
20**Note**: Issues with the output should be reported on the Babel [Issues](https://github.com/babel/babel/issues) tracker.
21
22<h2 align="center">Install</h2>
23
24> webpack `4.x || 5.x` | babel-loader 8.x | babel 7.x
25
26```bash
27npm install -D babel-loader @babel/core @babel/preset-env webpack
28```
29
30<h2 align="center">Usage</h2>
31
32webpack documentation: [Loaders](https://webpack.js.org/loaders/)
33
34Within your webpack configuration object, you'll need to add the babel-loader to the list of modules, like so:
35
36```javascript
37module: {
38 rules: [
39 {
40 test: /\.m?js$/,
41 exclude: /node_modules/,
42 use: {
43 loader: 'babel-loader',
44 options: {
45 presets: [
46 ['@babel/preset-env', { targets: "defaults" }]
47 ]
48 }
49 }
50 }
51 ]
52}
53```
54
55### Options
56
57See the `babel` [options](https://babeljs.io/docs/en/options).
58
59You can pass options to the loader by using the [`options`](https://webpack.js.org/configuration/module/#ruleoptions--rulequery) property:
60
61```javascript
62module: {
63 rules: [
64 {
65 test: /\.m?js$/,
66 exclude: /node_modules/,
67 use: {
68 loader: 'babel-loader',
69 options: {
70 presets: [
71 ['@babel/preset-env', { targets: "defaults" }]
72 ],
73 plugins: ['@babel/plugin-proposal-class-properties']
74 }
75 }
76 }
77 ]
78}
79```
80
81This loader also supports the following loader-specific option:
82
83* `cacheDirectory`: Default `false`. When set, the given directory will be used to cache the results of the loader. Future webpack builds will attempt to read from the cache to avoid needing to run the potentially expensive Babel recompilation process on each run. If the value is set to `true` in options (`{cacheDirectory: true}`), the loader will use the default cache directory in `node_modules/.cache/babel-loader` or fallback to the default OS temporary file directory if no `node_modules` folder could be found in any root directory.
84
85* `cacheIdentifier`: Default is a string composed by the `@babel/core`'s version, the `babel-loader`'s version, the contents of `.babelrc` file if it exists, and the value of the environment variable `BABEL_ENV` with a fallback to the `NODE_ENV` environment variable. This can be set to a custom value to force cache busting if the identifier changes.
86
87* `cacheCompression`: Default `true`. When set, each Babel transform output will be compressed with Gzip. If you want to opt-out of cache compression, set it to `false` -- your project may benefit from this if it transpiles thousands of files.
88
89* `customize`: Default `null`. The path of a module that exports a `custom` callback [like the one that you'd pass to `.custom()`](#customized-loader). Since you already have to make a new file to use this, it is recommended that you instead use `.custom` to create a wrapper loader. Only use this if you _must_ continue using `babel-loader` directly, but still want to customize.
90
91## Troubleshooting
92
93### babel-loader is slow!
94
95Make sure you are transforming as few files as possible. Because you are probably matching `/\.m?js$/`, you might be transforming the `node_modules` folder or other unwanted source.
96
97To exclude `node_modules`, see the `exclude` option in the `loaders` config as documented above.
98
99You can also speed up babel-loader by as much as 2x by using the `cacheDirectory` option. This will cache transformations to the filesystem.
100
101### Some files in my node_modules are not transpiled for IE 11
102
103Although we typically recommend not compiling `node_modules`, you may need to when using libraries that do not support IE 11.
104
105For this, you can either use a combination of `test` and `not`, or [pass a function](https://webpack.js.org/configuration/module/#condition) to your `exclude` option. You can also use negative lookahead regex as suggested [here](https://github.com/webpack/webpack/issues/2031#issuecomment-294706065).
106
107```javascript
108{
109 test: /\.m?js$/,
110 exclude: {
111 test: /node_modules/, // Exclude libraries in node_modules ...
112 not: [
113 // Except for a few of them that needs to be transpiled because they use modern syntax
114 /unfetch/,
115 /d3-array|d3-scale/,
116 /@hapi[\\/]joi-date/,
117 ]
118 },
119 use: {
120 loader: 'babel-loader',
121 options: {
122 presets: [
123 ['@babel/preset-env', { targets: "ie 11" }]
124 ]
125 }
126 }
127 }
128```
129
130### Babel is injecting helpers into each file and bloating my code!
131
132Babel uses very small helpers for common functions such as `_extend`. By default, this will be added to every file that requires it.
133
134You can instead require the Babel runtime as a separate module to avoid the duplication.
135
136The following configuration disables automatic per-file runtime injection in Babel, requiring `@babel/plugin-transform-runtime` instead and making all helper references use it.
137
138See the [docs](https://babeljs.io/docs/plugins/transform-runtime/) for more information.
139
140**NOTE**: You must run `npm install -D @babel/plugin-transform-runtime` to include this in your project and `@babel/runtime` itself as a dependency with `npm install @babel/runtime`.
141
142```javascript
143rules: [
144 // the 'transform-runtime' plugin tells Babel to
145 // require the runtime instead of inlining it.
146 {
147 test: /\.m?js$/,
148 exclude: /node_modules/,
149 use: {
150 loader: 'babel-loader',
151 options: {
152 presets: [
153 ['@babel/preset-env', { targets: "defaults" }]
154 ],
155 plugins: ['@babel/plugin-transform-runtime']
156 }
157 }
158 }
159]
160```
161
162#### **NOTE**: transform-runtime & custom polyfills (e.g. Promise library)
163
164Since [@babel/plugin-transform-runtime](https://github.com/babel/babel/tree/main/packages/babel-plugin-transform-runtime) includes a polyfill that includes a custom [regenerator-runtime](https://github.com/facebook/regenerator/blob/master/packages/regenerator-runtime/runtime.js) and [core-js](https://github.com/zloirock/core-js), the following usual shimming method using `webpack.ProvidePlugin` will not work:
165
166```javascript
167// ...
168 new webpack.ProvidePlugin({
169 'Promise': 'bluebird'
170 }),
171// ...
172```
173
174The following approach will not work either:
175
176```javascript
177require('@babel/runtime/core-js/promise').default = require('bluebird');
178
179var promise = new Promise;
180```
181
182which outputs to (using `runtime`):
183
184```javascript
185'use strict';
186
187var _Promise = require('@babel/runtime/core-js/promise')['default'];
188
189require('@babel/runtime/core-js/promise')['default'] = require('bluebird');
190
191var promise = new _Promise();
192```
193
194The previous `Promise` library is referenced and used before it is overridden.
195
196One approach is to have a "bootstrap" step in your application that would first override the default globals before your application:
197
198```javascript
199// bootstrap.js
200
201require('@babel/runtime/core-js/promise').default = require('bluebird');
202
203// ...
204
205require('./app');
206```
207
208### The Node.js API for `babel` has been moved to `babel-core`.
209
210If you receive this message, it means that you have the npm package `babel` installed and are using the short notation of the loader in the webpack config (which is not valid anymore as of webpack 2.x):
211```javascript
212 {
213 test: /\.m?js$/,
214 loader: 'babel',
215 }
216```
217
218webpack then tries to load the `babel` package instead of the `babel-loader`.
219
220To fix this, you should uninstall the npm package `babel`, as it is deprecated in Babel v6. (Instead, install `@babel/cli` or `@babel/core`.)
221In the case one of your dependencies is installing `babel` and you cannot uninstall it yourself, use the complete name of the loader in the webpack config:
222```javascript
223 {
224 test: /\.m?js$/,
225 loader: 'babel-loader',
226 }
227```
228
229### Exclude libraries that should not be transpiled
230
231`core-js` and `webpack/buildin` will cause errors if they are transpiled by Babel.
232
233You will need to exclude them form `babel-loader`.
234
235```js
236{
237 "loader": "babel-loader",
238 "options": {
239 "exclude": [
240 // \\ for Windows, / for macOS and Linux
241 /node_modules[\\/]core-js/,
242 /node_modules[\\/]webpack[\\/]buildin/,
243 ],
244 "presets": [
245 "@babel/preset-env"
246 ]
247 }
248}
249```
250
251## Customize config based on webpack target
252
253Webpack supports bundling multiple [targets](https://webpack.js.org/concepts/targets/). For cases where you may want different Babel configurations for each target (like `web` _and_ `node`), this loader provides a `target` property via Babel's [caller](https://babeljs.io/docs/en/config-files#apicallercb) API.
254
255For example, to change the environment targets passed to `@babel/preset-env` based on the webpack target:
256
257```javascript
258// babel.config.js
259
260module.exports = api => {
261 return {
262 plugins: [
263 "@babel/plugin-proposal-nullish-coalescing-operator",
264 "@babel/plugin-proposal-optional-chaining"
265 ],
266 presets: [
267 [
268 "@babel/preset-env",
269 {
270 useBuiltIns: "entry",
271 // caller.target will be the same as the target option from webpack
272 targets: api.caller(caller => caller && caller.target === "node")
273 ? { node: "current" }
274 : { chrome: "58", ie: "11" }
275 }
276 ]
277 ]
278 }
279}
280```
281
282## Customized Loader
283
284`babel-loader` exposes a loader-builder utility that allows users to add custom handling
285of Babel's configuration for each file that it processes.
286
287`.custom` accepts a callback that will be called with the loader's instance of
288`babel` so that tooling can ensure that it using exactly the same `@babel/core`
289instance as the loader itself.
290
291In cases where you want to customize without actually having a file to call `.custom`, you
292may also pass the `customize` option with a string pointing at a file that exports
293your `custom` callback function.
294
295### Example
296
297```js
298// Export from "./my-custom-loader.js" or whatever you want.
299module.exports = require("babel-loader").custom(babel => {
300 function myPlugin() {
301 return {
302 visitor: {},
303 };
304 }
305
306 return {
307 // Passed the loader options.
308 customOptions({ opt1, opt2, ...loader }) {
309 return {
310 // Pull out any custom options that the loader might have.
311 custom: { opt1, opt2 },
312
313 // Pass the options back with the two custom options removed.
314 loader,
315 };
316 },
317
318 // Passed Babel's 'PartialConfig' object.
319 config(cfg) {
320 if (cfg.hasFilesystemConfig()) {
321 // Use the normal config
322 return cfg.options;
323 }
324
325 return {
326 ...cfg.options,
327 plugins: [
328 ...(cfg.options.plugins || []),
329
330 // Include a custom plugin in the options.
331 myPlugin,
332 ],
333 };
334 },
335
336 result(result) {
337 return {
338 ...result,
339 code: result.code + "\n// Generated by some custom loader",
340 };
341 },
342 };
343});
344```
345
346```js
347// And in your Webpack config
348module.exports = {
349 // ..
350 module: {
351 rules: [{
352 // ...
353 loader: path.join(__dirname, 'my-custom-loader.js'),
354 // ...
355 }]
356 }
357};
358```
359
360### `customOptions(options: Object): { custom: Object, loader: Object }`
361
362Given the loader's options, split custom options out of `babel-loader`'s
363options.
364
365
366### `config(cfg: PartialConfig): Object`
367
368Given Babel's `PartialConfig` object, return the `options` object that should
369be passed to `babel.transform`.
370
371
372### `result(result: Result): Result`
373
374Given Babel's result object, allow loaders to make additional tweaks to it.
375
376
377## License
378[MIT](https://couto.mit-license.org/)