Skip to content

Commit 1ad2b7d

Browse files
wardpeetForsakenHarmony
authored andcommitted
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)
1 parent b07c385 commit 1ad2b7d

File tree

9 files changed

+267
-61
lines changed

9 files changed

+267
-61
lines changed

README.md

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -116,10 +116,10 @@ Libraries often wish to rename internal object properties or class members to sm
116116
-h, --help Displays this message
117117
118118
Examples
119-
$ microbundle microbundle --globals react=React,jquery=$
120-
$ microbundle microbundle --define API_KEY=1234
121-
$ microbundle microbundle --alias react=preact
122-
$ microbundle microbundle --no-sourcemap # don't generate sourcemaps
119+
$ microbundle build --globals react=React,jquery=$
120+
$ microbundle build --define API_KEY=1234
121+
$ microbundle build --alias react=preact
122+
$ microbundle build --no-sourcemap # don't generate sourcemaps
123123
```
124124

125125
## 🛣 Roadmap

package.json

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -45,6 +45,7 @@
4545
"@babel/core": "^7.4.5",
4646
"@babel/plugin-proposal-class-properties": "7.4.4",
4747
"@babel/plugin-syntax-jsx": "^7.2.0",
48+
"@babel/plugin-transform-flow-strip-types": "^7.4.4",
4849
"@babel/plugin-transform-react-jsx": "^7.3.0",
4950
"@babel/polyfill": "^7.4.4",
5051
"@babel/preset-flow": "^7.0.0",
@@ -59,6 +60,7 @@
5960
"filesize": "^4.1.2",
6061
"gzip-size": "^5.1.1",
6162
"kleur": "^3.0.3",
63+
"lodash.merge": "^4.6.1",
6264
"module-details-from-path": "^1.0.3",
6365
"pretty-bytes": "^5.2.0",
6466
"rollup": "^1.12.4",
@@ -67,7 +69,6 @@
6769
"rollup-plugin-bundle-size": "^1.0.1",
6870
"rollup-plugin-commonjs": "^10.0.0",
6971
"rollup-plugin-es3": "^1.1.0",
70-
"rollup-plugin-flow": "^1.1.1",
7172
"rollup-plugin-json": "^4.0.0",
7273
"rollup-plugin-node-resolve": "^5.0.0",
7374
"rollup-plugin-postcss": "^2.0.3",
@@ -85,6 +86,7 @@
8586
"@babel/preset-env": "^7.4.5",
8687
"babel-core": "^7.0.0-bridge.0",
8788
"babel-jest": "^24.8.0",
89+
"core-js": "^3.1.2",
8890
"cross-env": "^5.2.0",
8991
"directory-tree": "^2.2.3",
9092
"eslint": "^5.16.0",

src/index.js

Lines changed: 23 additions & 47 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@ import cssnano from 'cssnano';
88
import { rollup, watch } from 'rollup';
99
import commonjs from 'rollup-plugin-commonjs';
1010
import babel from 'rollup-plugin-babel';
11+
import customBabel from './lib/babel-custom';
1112
import nodeResolve from 'rollup-plugin-node-resolve';
1213
import { terser } from 'rollup-plugin-terser';
1314
import alias from 'rollup-plugin-alias';
@@ -18,7 +19,7 @@ import prettyBytes from 'pretty-bytes';
1819
import typescript from 'rollup-plugin-typescript2';
1920
import json from 'rollup-plugin-json';
2021
import logError from './log-error';
21-
import { readFile, isDir, isFile, stdout, stderr } from './utils';
22+
import { readFile, isDir, isFile, stdout, stderr, isTruthy } from './utils';
2223
import camelCase from 'camelcase';
2324

2425
const removeScope = name => name.replace(/^@.*\//, '');
@@ -540,56 +541,31 @@ function createConfig(options, entry, format, writeMeta) {
540541
},
541542
},
542543
}),
543-
babel({
544-
babelrc: false,
545-
configFile: false,
546-
compact: false,
547-
include: 'node_modules/**',
548-
plugins: [
549-
[
550-
require.resolve('babel-plugin-transform-replace-expressions'),
551-
{ replace: defines },
544+
// if defines is not set, we shouldn't run babel through node_modules
545+
isTruthy(defines) &&
546+
babel({
547+
babelrc: false,
548+
configFile: false,
549+
compact: false,
550+
include: 'node_modules/**',
551+
plugins: [
552+
[
553+
require.resolve('babel-plugin-transform-replace-expressions'),
554+
{ replace: defines },
555+
],
552556
],
553-
],
554-
}),
555-
babel({
557+
}),
558+
customBabel({
556559
extensions: EXTENSIONS,
557560
exclude: 'node_modules/**',
558561
passPerPreset: true, // @see https://babeljs.io/docs/en/options#passperpreset
559-
presets: [
560-
[
561-
'@babel/preset-env',
562-
{
563-
loose: true,
564-
modules: false,
565-
targets:
566-
options.target === 'node' ? { node: '8' } : undefined,
567-
exclude: ['transform-async-to-generator'],
568-
},
569-
],
570-
!useTypescript && ['@babel/preset-flow', { all: true }],
571-
].filter(Boolean),
572-
plugins: [
573-
[
574-
require.resolve('@babel/plugin-transform-react-jsx'),
575-
{
576-
pragma: options.jsx || 'h',
577-
pragmaFrag: options.jsxFragment || 'Fragment',
578-
},
579-
],
580-
[
581-
require.resolve('babel-plugin-transform-replace-expressions'),
582-
{ replace: defines },
583-
],
584-
[
585-
require.resolve('babel-plugin-transform-async-to-promises'),
586-
{ inlineHelpers: true, externalHelpers: true },
587-
],
588-
[
589-
require.resolve('@babel/plugin-proposal-class-properties'),
590-
{ loose: true },
591-
],
592-
],
562+
custom: {
563+
defines,
564+
targets: options.target === 'node' ? { node: '8' } : undefined,
565+
pragma: options.jsx || 'h',
566+
pragmaFrag: options.jsxFragment || 'Fragment',
567+
typescript: !!useTypescript,
568+
},
593569
}),
594570
options.compress !== false && [
595571
terser({

src/lib/babel-custom.js

Lines changed: 140 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,140 @@
1+
import { createConfigItem } from '@babel/core';
2+
import babelPlugin from 'rollup-plugin-babel';
3+
import merge from 'lodash.merge';
4+
import { isTruthy } from '../utils';
5+
6+
const mergeConfigItems = (type, ...configItemsToMerge) => {
7+
const mergedItems = [];
8+
9+
configItemsToMerge.forEach(configItemToMerge => {
10+
configItemToMerge.forEach(item => {
11+
const itemToMergeWithIndex = mergedItems.findIndex(
12+
mergedItem => mergedItem.file.resolved === item.file.resolved,
13+
);
14+
15+
if (itemToMergeWithIndex === -1) {
16+
mergedItems.push(item);
17+
return;
18+
}
19+
20+
mergedItems[itemToMergeWithIndex] = createConfigItem(
21+
[
22+
mergedItems[itemToMergeWithIndex].file.resolved,
23+
merge(mergedItems[itemToMergeWithIndex].options, item.options),
24+
],
25+
{
26+
type,
27+
},
28+
);
29+
});
30+
});
31+
32+
return mergedItems;
33+
};
34+
35+
const createConfigItems = (type, items) => {
36+
return items.map(({ name, ...options }) => {
37+
return createConfigItem([require.resolve(name), options], { type });
38+
});
39+
};
40+
41+
export default babelPlugin.custom(babelCore => {
42+
return {
43+
// Passed the plugin options.
44+
options({ custom: customOptions, ...pluginOptions }) {
45+
return {
46+
// Pull out any custom options that the plugin might have.
47+
customOptions,
48+
49+
// Pass the options back with the two custom options removed.
50+
pluginOptions,
51+
};
52+
},
53+
54+
config(config, { customOptions }) {
55+
const defaultPlugins = createConfigItems(
56+
'plugin',
57+
[
58+
{
59+
name: '@babel/plugin-transform-react-jsx',
60+
pragma: customOptions.jsx || 'h',
61+
pragmaFrag: customOptions.jsxFragment || 'Fragment',
62+
},
63+
isTruthy(customOptions.defines) && {
64+
name: 'babel-plugin-transform-replace-expressions',
65+
replace: customOptions.defines,
66+
},
67+
{
68+
name: 'babel-plugin-transform-async-to-promises',
69+
inlineHelpers: true,
70+
externalHelpers: true,
71+
},
72+
{
73+
name: '@babel/plugin-proposal-class-properties',
74+
loose: true,
75+
},
76+
].filter(Boolean),
77+
);
78+
79+
let babelOptions = {
80+
presets: [],
81+
plugins: [],
82+
};
83+
if (config.hasFilesystemConfig()) {
84+
babelOptions = config.options;
85+
86+
if (babelOptions.presets) {
87+
babelOptions.presets = babelOptions.presets.map(preset => {
88+
// When preset-env is configured we want to make sure we override some settings.
89+
// We want to make sure microbundle is still fast & creates small bundles
90+
if (preset.file.request === '@babel/preset-env') {
91+
preset = createConfigItem(
92+
[
93+
preset.file.resolved,
94+
merge(
95+
{
96+
loose: true,
97+
targets: customOptions.targets,
98+
},
99+
preset.options,
100+
{
101+
modules: false,
102+
exclude: merge(
103+
['transform-async-to-generator'],
104+
preset.options.exclude || [],
105+
),
106+
},
107+
),
108+
],
109+
{
110+
type: `preset`,
111+
},
112+
);
113+
}
114+
115+
return preset;
116+
});
117+
}
118+
} else {
119+
babelOptions.presets = createConfigItems('preset', [
120+
{
121+
name: '@babel/preset-env',
122+
targets: customOptions.targets,
123+
modules: false,
124+
loose: true,
125+
exclude: ['transform-async-to-generator'],
126+
},
127+
]);
128+
}
129+
130+
// Merge babelrc & our plugins together
131+
babelOptions.plugins = mergeConfigItems(
132+
'plugin',
133+
defaultPlugins,
134+
babelOptions.plugins || [],
135+
);
136+
137+
return babelOptions;
138+
},
139+
};
140+
});

src/utils.js

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -14,3 +14,11 @@ export const isFile = name =>
1414
.catch(() => false);
1515
export const stdout = console.log.bind(console); // eslint-disable-line no-console
1616
export const stderr = console.error.bind(console);
17+
18+
export const isTruthy = obj => {
19+
if (!obj) {
20+
return false;
21+
}
22+
23+
return obj.constructor !== Object || Object.keys(obj).length > 0;
24+
};

test/__snapshots__/index.test.js.snap

Lines changed: 56 additions & 9 deletions
Large diffs are not rendered by default.

test/fixtures/custom-babelrc/.babelrc

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,24 @@
1+
{
2+
"presets": [
3+
[
4+
"@babel/preset-env",
5+
{
6+
"loose": true,
7+
"modules": false,
8+
"useBuiltIns": "usage",
9+
"corejs": 3,
10+
"targets": {
11+
"esmodules": true
12+
}
13+
}
14+
]
15+
],
16+
"plugins": [
17+
[
18+
"@babel/plugin-proposal-class-properties",
19+
{
20+
"loose": false
21+
}
22+
]
23+
]
24+
}
Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
{
2+
"name": "custom-babelrc"
3+
}
Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
export class MyClass {
2+
myFields = ['foo', 'bar'];
3+
async foo() {
4+
return this.myFields.find(item => item === 'bar');
5+
}
6+
}

0 commit comments

Comments
 (0)