feat(babel): merges babelrc with microbunde babel config (#396)

* feat(babel): merges babelrc with microbunde babel config

* update tests

* Fix README.md

Fix examples description

* remove unused rollup-plugin-flow dependency (#379)
This commit is contained in:
Ward Peeters 2019-05-29 00:03:08 +02:00 committed by Leah
parent 445fde2ff0
commit 0eadcd9bce
8 changed files with 262 additions and 56 deletions

View File

@ -60,6 +60,7 @@
"filesize": "^4.1.2",
"gzip-size": "^5.1.1",
"kleur": "^3.0.3",
"lodash.merge": "^4.6.1",
"module-details-from-path": "^1.0.3",
"pretty-bytes": "^5.2.0",
"rollup": "^1.12.4",
@ -85,6 +86,7 @@
"@babel/preset-env": "^7.4.5",
"babel-core": "^7.0.0-bridge.0",
"babel-jest": "^24.8.0",
"core-js": "^3.1.2",
"cross-env": "^5.2.0",
"directory-tree": "^2.2.3",
"eslint": "^5.16.0",

View File

@ -8,6 +8,7 @@ import cssnano from 'cssnano';
import { rollup, watch } from 'rollup';
import commonjs from 'rollup-plugin-commonjs';
import babel from 'rollup-plugin-babel';
import customBabel from './lib/babel-custom';
import nodeResolve from 'rollup-plugin-node-resolve';
import { terser } from 'rollup-plugin-terser';
import alias from 'rollup-plugin-alias';
@ -18,7 +19,7 @@ import prettyBytes from 'pretty-bytes';
import typescript from 'rollup-plugin-typescript2';
import json from 'rollup-plugin-json';
import logError from './log-error';
import { readFile, isDir, isFile, stdout, stderr } from './utils';
import { readFile, isDir, isFile, stdout, stderr, isTruthy } from './utils';
import camelCase from 'camelcase';
const removeScope = name => name.replace(/^@.*\//, '');
@ -540,56 +541,31 @@ function createConfig(options, entry, format, writeMeta) {
},
},
}),
babel({
babelrc: false,
configFile: false,
compact: false,
include: 'node_modules/**',
plugins: [
[
require.resolve('babel-plugin-transform-replace-expressions'),
{ replace: defines },
// if defines is not set, we shouldn't run babel through node_modules
isTruthy(defines) &&
babel({
babelrc: false,
configFile: false,
compact: false,
include: 'node_modules/**',
plugins: [
[
require.resolve('babel-plugin-transform-replace-expressions'),
{ replace: defines },
],
],
],
}),
babel({
}),
customBabel({
extensions: EXTENSIONS,
exclude: 'node_modules/**',
passPerPreset: true, // @see https://babeljs.io/docs/en/options#passperpreset
presets: [
[
'@babel/preset-env',
{
loose: true,
modules: false,
targets:
options.target === 'node' ? { node: '8' } : undefined,
exclude: ['transform-async-to-generator'],
},
],
!useTypescript && ['@babel/preset-flow', { all: true }],
].filter(Boolean),
plugins: [
[
require.resolve('@babel/plugin-transform-react-jsx'),
{
pragma: options.jsx || 'h',
pragmaFrag: options.jsxFragment || 'Fragment',
},
],
[
require.resolve('babel-plugin-transform-replace-expressions'),
{ replace: defines },
],
[
require.resolve('babel-plugin-transform-async-to-promises'),
{ inlineHelpers: true, externalHelpers: true },
],
[
require.resolve('@babel/plugin-proposal-class-properties'),
{ loose: true },
],
],
custom: {
defines,
targets: options.target === 'node' ? { node: '8' } : undefined,
pragma: options.jsx || 'h',
pragmaFrag: options.jsxFragment || 'Fragment',
typescript: !!useTypescript,
},
}),
options.compress !== false && [
terser({

140
src/lib/babel-custom.js Normal file
View File

@ -0,0 +1,140 @@
import { createConfigItem } from '@babel/core';
import babelPlugin from 'rollup-plugin-babel';
import merge from 'lodash.merge';
import { isTruthy } from '../utils';
const mergeConfigItems = (type, ...configItemsToMerge) => {
const mergedItems = [];
configItemsToMerge.forEach(configItemToMerge => {
configItemToMerge.forEach(item => {
const itemToMergeWithIndex = mergedItems.findIndex(
mergedItem => mergedItem.file.resolved === item.file.resolved,
);
if (itemToMergeWithIndex === -1) {
mergedItems.push(item);
return;
}
mergedItems[itemToMergeWithIndex] = createConfigItem(
[
mergedItems[itemToMergeWithIndex].file.resolved,
merge(mergedItems[itemToMergeWithIndex].options, item.options),
],
{
type,
},
);
});
});
return mergedItems;
};
const createConfigItems = (type, items) => {
return items.map(({ name, ...options }) => {
return createConfigItem([require.resolve(name), options], { type });
});
};
export default babelPlugin.custom(babelCore => {
return {
// Passed the plugin options.
options({ custom: customOptions, ...pluginOptions }) {
return {
// Pull out any custom options that the plugin might have.
customOptions,
// Pass the options back with the two custom options removed.
pluginOptions,
};
},
config(config, { customOptions }) {
const defaultPlugins = createConfigItems(
'plugin',
[
{
name: '@babel/plugin-transform-react-jsx',
pragma: customOptions.jsx || 'h',
pragmaFrag: customOptions.jsxFragment || 'Fragment',
},
isTruthy(customOptions.defines) && {
name: 'babel-plugin-transform-replace-expressions',
replace: customOptions.defines,
},
{
name: 'babel-plugin-transform-async-to-promises',
inlineHelpers: true,
externalHelpers: true,
},
{
name: '@babel/plugin-proposal-class-properties',
loose: true,
},
].filter(Boolean),
);
let babelOptions = {
presets: [],
plugins: [],
};
if (config.hasFilesystemConfig()) {
babelOptions = config.options;
if (babelOptions.presets) {
babelOptions.presets = babelOptions.presets.map(preset => {
// When preset-env is configured we want to make sure we override some settings.
// We want to make sure microbundle is still fast & creates small bundles
if (preset.file.request === '@babel/preset-env') {
preset = createConfigItem(
[
preset.file.resolved,
merge(
{
loose: true,
targets: customOptions.targets,
},
preset.options,
{
modules: false,
exclude: merge(
['transform-async-to-generator'],
preset.options.exclude || [],
),
},
),
],
{
type: `preset`,
},
);
}
return preset;
});
}
} else {
babelOptions.presets = createConfigItems('preset', [
{
name: '@babel/preset-env',
targets: customOptions.targets,
modules: false,
loose: true,
exclude: ['transform-async-to-generator'],
},
]);
}
// Merge babelrc & our plugins together
babelOptions.plugins = mergeConfigItems(
'plugin',
defaultPlugins,
babelOptions.plugins || [],
);
return babelOptions;
},
};
});

View File

@ -14,3 +14,11 @@ export const isFile = name =>
.catch(() => false);
export const stdout = console.log.bind(console); // eslint-disable-line no-console
export const stderr = console.error.bind(console);
export const isTruthy = obj => {
if (!obj) {
return false;
}
return obj.constructor !== Object || Object.keys(obj).length > 0;
};

File diff suppressed because one or more lines are too long

24
test/fixtures/custom-babelrc/.babelrc vendored Normal file
View File

@ -0,0 +1,24 @@
{
"presets": [
[
"@babel/preset-env",
{
"loose": true,
"modules": false,
"useBuiltIns": "usage",
"corejs": 3,
"targets": {
"esmodules": true
}
}
]
],
"plugins": [
[
"@babel/plugin-proposal-class-properties",
{
"loose": false
}
]
]
}

View File

@ -0,0 +1,3 @@
{
"name": "custom-babelrc"
}

View File

@ -0,0 +1,6 @@
export class MyClass {
myFields = ['foo', 'bar'];
async foo() {
return this.myFields.find(item => item === 'bar');
}
}