Skip to content

Commit

Permalink
Browse files Browse the repository at this point in the history
Expose API to allow implementing custom loaders around babel-loader. (#…
  • Loading branch information
loganfsmyth committed May 17, 2018
1 parent 088f79c commit ebedae1
Show file tree
Hide file tree
Showing 2 changed files with 115 additions and 10 deletions.
76 changes: 76 additions & 0 deletions README.md
Expand Up @@ -205,4 +205,80 @@ In the case one of your dependencies is installing `babel` and you cannot uninst
}
```

## Customized Loader

`babel-loader` exposes a loader-builder utility that allows users to add custom handling
of Babel's configuration for each file that it processes.

`.custom` 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.

### Example

```js
module.exports = require("babel-loader").custom(babel => {
function myPlugin() {
return {
visitor: {},
};
}

return {
// Passed the loader options.
customOptions({ opt1, opt2, ...loader }) {
return {
// Pull out any custom options that the loader might have.
custom: { opt1, opt2 },

// Pass the options back with the two custom options removed.
loader,
};
},

// Passed Babel's 'PartialConfig' object.
config(cfg) {
if (cfg.hasFilesystemConfig()) {
// Use the normal config
return cfg.options;
}

return {
...cfg.options,
plugins: [
...(cfg.options.plugins || []),

// Include a custom plugin in the options.
myPlugin,
],
};
},

result(result) {
return {
...result,
code: result.code + "\n// Generated by some custom loader",
};
},
};
});
```

### `customOptions(options: Object): { custom: Object, loader: Object }`

Given the loader's options, split custom options out of `babel-loader`'s
options.


### `config(cfg: PartialConfig): Object`

Given Babel's `PartialConfig` object, return the `options` object that should
be passed to `babel.transform`.


### `result(result: Result): Result`

Given Babel's result object, allow loaders to make additional tweaks to it.


## [License](http://couto.mit-license.org/)
49 changes: 39 additions & 10 deletions src/index.js
Expand Up @@ -14,19 +14,33 @@ function subscribe(subscriber, metadata, context) {
}
}

module.exports = function(source, inputSourceMap) {
// Make the loader async
const callback = this.async();
module.exports = makeLoader();
module.exports.custom = makeLoader;

loader
.call(this, source, inputSourceMap)
.then(args => callback(null, ...args), err => callback(err));
};
function makeLoader(callback) {
const overrides = callback ? callback(babel) : undefined;

async function loader(source, inputSourceMap) {
return function(source, inputSourceMap) {
// Make the loader async
const callback = this.async();

loader
.call(this, source, inputSourceMap, overrides)
.then(args => callback(null, ...args), err => callback(err));
};
}

async function loader(source, inputSourceMap, overrides) {
const filename = this.resourcePath;

const loaderOptions = loaderUtils.getOptions(this) || {};
let loaderOptions = loaderUtils.getOptions(this) || {};

let customOptions;
if (overrides && overrides.customOptions) {
const result = await overrides.customOptions.call(this, loaderOptions);
customOptions = result.custom;
loaderOptions = result.loader;
}

// Deprecation handling
if ("forceEnv" in loaderOptions) {
Expand Down Expand Up @@ -73,7 +87,13 @@ async function loader(source, inputSourceMap) {

const config = babel.loadPartialConfig(programmaticOptions);
if (config) {
const options = config.options;
let options = config.options;
if (overrides && overrides.config) {
options = await overrides.config.call(this, config, {
source,
customOptions,
});
}

const {
cacheDirectory = null,
Expand Down Expand Up @@ -105,6 +125,15 @@ async function loader(source, inputSourceMap) {
}

if (result) {
if (overrides && overrides.result) {
result = await overrides.result.call(this, result, {
source,
customOptions,
config,
options,
});
}

const { code, map, metadata } = result;

metadataSubscribers.forEach(subscriber => {
Expand Down

0 comments on commit ebedae1

Please sign in to comment.