Skip to content

Commit

Permalink
Add ability to extend babel and rollup
Browse files Browse the repository at this point in the history
  • Loading branch information
jaredpalmer committed Aug 22, 2019
1 parent d346cc3 commit 50f2d5e
Show file tree
Hide file tree
Showing 8 changed files with 271 additions and 75 deletions.
3 changes: 2 additions & 1 deletion .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -4,4 +4,5 @@ node_modules
.rts2_cache_cjs
.rts2_cache_esm
.rts2_cache_umd
dist
dist
tester
3 changes: 3 additions & 0 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,7 @@
"@babel/core": "^7.4.4",
"@babel/helper-module-imports": "^7.0.0",
"@babel/plugin-proposal-class-properties": "^7.4.4",
"@babel/plugin-transform-regenerator": "^7.4.5",
"@babel/polyfill": "^7.4.4",
"@babel/preset-env": "^7.4.4",
"@typescript-eslint/eslint-plugin": "^1.13.0",
Expand All @@ -43,6 +44,7 @@
"asyncro": "^3.0.0",
"babel-plugin-annotate-pure-calls": "^0.4.0",
"babel-plugin-dev-expression": "^0.2.1",
"babel-plugin-macros": "^2.6.1",
"babel-plugin-transform-async-to-promises": "^0.8.11",
"babel-plugin-transform-rename-import": "^2.3.0",
"babel-traverse": "^6.26.0",
Expand All @@ -65,6 +67,7 @@
"jest": "^24.8.0",
"jest-watch-typeahead": "^0.3.1",
"jpjs": "^1.2.1",
"lodash.merge": "^4.6.2",
"mkdirp": "^0.5.1",
"ora": "^3.4.0",
"pascal-case": "^2.0.1",
Expand Down
153 changes: 153 additions & 0 deletions src/babelPluginTsdx.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,153 @@
import { createConfigItem } from '@babel/core';
import babelPlugin from 'rollup-plugin-babel';
import merge from 'lodash.merge';

export const isTruthy = (obj?: any) => {
if (!obj) {
return false;
}

return obj.constructor !== Object || Object.keys(obj).length > 0;
};

const replacements = [{ original: 'lodash', replacement: 'lodash-es' }];

export const mergeConfigItems = (type: any, ...configItemsToMerge: any[]) => {
const mergedItems: any[] = [];

configItemsToMerge.forEach(configItemToMerge => {
configItemToMerge.forEach((item: any) => {
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;
};

export const createConfigItems = (type: any, items: any[]) => {
return items.map(({ name, ...options }) => {
return createConfigItem([require.resolve(name), options], { type });
});
};

export const babelPluginTsdx = babelPlugin.custom((babelCore: any) => ({
// Passed the plugin options.
options({ custom: customOptions, ...pluginOptions }: any) {
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: any, { customOptions }: any) {
const defaultPlugins = createConfigItems(
'plugin',
[
// {
// name: '@babel/plugin-transform-react-jsx',
// pragma: customOptions.jsx || 'h',
// pragmaFrag: customOptions.jsxFragment || 'Fragment',
// },
{ name: 'babel-plugin-annotate-pure-calls' },
{ name: 'babel-plugin-dev-expression' },
{
name: 'babel-plugin-transform-rename-import',
replacements,
},
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,
},
{
name: '@babel/plugin-transform-regenerator',
async: false,
},
{
name: 'babel-plugin-macros',
},
isTruthy(customOptions.extractErrors) && {
name: './errors/transformErrorMessages',
},
].filter(Boolean)
);

const babelOptions = config.options || {};

const envIdx = (babelOptions.presets || []).findIndex((preset: any) =>
preset.file.request.includes('@babel/preset-env')
);

if (envIdx !== -1) {
const preset = babelOptions.presets[envIdx];
babelOptions.presets[envIdx] = createConfigItem(
[
preset.file.resolved,
merge(
{
loose: true,
targets: customOptions.targets,
},
preset.options,
{
modules: false,
exclude: merge(
['transform-async-to-generator', 'transform-regenerator'],
preset.options.exclude || []
),
}
),
],
{
type: `preset`,
}
);
} else {
babelOptions.presets = createConfigItems('preset', [
{
name: '@babel/preset-env',
targets: customOptions.targets,
modules: false,
loose: true,
exclude: ['transform-async-to-generator', 'transform-regenerator'],
},
]);
}

// Merge babelrc & our plugins together
babelOptions.plugins = mergeConfigItems(
'plugin',
defaultPlugins,
babelOptions.plugins || []
);

return babelOptions;
},
}));
81 changes: 22 additions & 59 deletions src/createRollupConfig.ts
Original file line number Diff line number Diff line change
@@ -1,73 +1,26 @@
import { DEFAULT_EXTENSIONS } from '@babel/core';
import { safeVariableName, safePackageName, external } from './utils';
import { paths } from './constants';
import { terser } from 'rollup-plugin-terser';
import babel from 'rollup-plugin-babel';
import { DEFAULT_EXTENSIONS } from '@babel/core';
// import babel from 'rollup-plugin-babel';
import commonjs from 'rollup-plugin-commonjs';
import json from 'rollup-plugin-json';
import replace from 'rollup-plugin-replace';
import resolve from 'rollup-plugin-node-resolve';
import sourceMaps from 'rollup-plugin-sourcemaps';
import typescript from 'rollup-plugin-typescript2';
import { extractErrors } from './errors/extractErrors';

const replacements = [{ original: 'lodash', replacement: 'lodash-es' }];
import { babelPluginTsdx } from './babelPluginTsdx';
import { TsdxOptions } from './types';

const errorCodeOpts = {
errorMapFilePath: paths.appRoot + '/errors/codes.json',
errorMapFilePath: paths.appErrorsJson,
};

interface TsdxOptions {
input: string;
name: string;
target: 'node' | 'browser';
env: 'development' | 'production';
tsconfig?: string;
extractErrors?: string;
minify?: boolean;
}

const babelOptions = (format: 'cjs' | 'esm' | 'umd', opts: TsdxOptions) => ({
exclude: 'node_modules/**',
extensions: [...DEFAULT_EXTENSIONS, 'ts', 'tsx'],
passPerPreset: true, // @see https://babeljs.io/docs/en/options#passperpreset
presets: [
[
require.resolve('@babel/preset-env'),
{
loose: true,
modules: false,
targets: opts.target === 'node' ? { node: '8' } : undefined,
exclude: ['transform-async-to-generator'],
},
],
],
plugins: [
require.resolve('babel-plugin-annotate-pure-calls'),
require.resolve('babel-plugin-dev-expression'),
format !== 'cjs' && [
require.resolve('babel-plugin-transform-rename-import'),
{ replacements },
],
[
require.resolve('babel-plugin-transform-async-to-promises'),
{ inlineHelpers: true, externalHelpers: true },
],
[
require.resolve('@babel/plugin-proposal-class-properties'),
{ loose: true },
],
opts.extractErrors && require('./errors/transformErrorMessages'),
].filter(Boolean),
});

// shebang cache map thing because the transform only gets run once
let shebang: any = {};

export function createRollupConfig(
format: 'cjs' | 'umd' | 'esm',
opts: TsdxOptions
) {
export function createRollupConfig(opts: TsdxOptions) {
const findAndRecordErrorCodes = extractErrors({
...errorCodeOpts,
...opts,
Expand All @@ -78,7 +31,7 @@ export function createRollupConfig(

const outputName = [
`${paths.appDist}/${safePackageName(opts.name)}`,
format,
opts.format,
opts.env,
shouldMinify ? 'min' : '',
'js',
Expand All @@ -101,7 +54,7 @@ export function createRollupConfig(
// Set filenames of the consumer's package
file: outputName,
// Pass through the file format
format,
format: opts.format,
// Do not let Rollup call Object.freeze() on namespace import objects
// (i.e. import * as namespaceImportObject from...) that are accessed dynamically.
freeze: false,
Expand Down Expand Up @@ -146,7 +99,7 @@ export function createRollupConfig(
opts.target !== 'node' ? 'browser' : undefined,
].filter(Boolean) as string[],
}),
format === 'umd' &&
opts.format === 'umd' &&
commonjs({
// use a regex to make sure to include eventual hoisted packages
include: /\/node_modules\//,
Expand Down Expand Up @@ -174,7 +127,7 @@ export function createRollupConfig(
},
typescript({
typescript: require('typescript'),
cacheRoot: `./.rts2_cache_${format}`,
cacheRoot: `./.rts2_cache_${opts.format}`,
tsconfig: opts.tsconfig,
tsconfigDefaults: {
compilerOptions: {
Expand All @@ -189,7 +142,17 @@ export function createRollupConfig(
},
},
}),
babel(babelOptions(format, opts)),
babelPluginTsdx({
exclude: 'node_modules/**',
extensions: [...DEFAULT_EXTENSIONS, 'ts', 'tsx'],
passPerPreset: true,
custom: {
targets: opts.target === 'node' ? { node: '8' } : undefined,
extractErrors: opts.extractErrors,
format: opts.format,
// defines: opts.defines,
},
}),
opts.env !== undefined &&
replace({
'process.env.NODE_ENV': JSON.stringify(opts.env),
Expand All @@ -208,7 +171,7 @@ export function createRollupConfig(
passes: 10,
},
ecma: 5,
toplevel: format === 'cjs',
toplevel: opts.format === 'cjs',
warnings: true,
}),
],
Expand Down
3 changes: 3 additions & 0 deletions src/env.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ declare module 'eslint-config-react-app';
// @see line 226 of https://unpkg.com/@babel/core@7.4.4/lib/index.js
declare module '@babel/core' {
export const DEFAULT_EXTENSIONS: string[];
export function createConfigItem(boop: any[], options: any) {}
}

// Rollup plugins
Expand All @@ -22,3 +23,5 @@ declare module 'camelcase';
declare module 'babel-traverse';
declare module 'babylon';
declare module '@babel/helper-module-imports';

declare module 'lodash.merge';
Loading

0 comments on commit 50f2d5e

Please sign in to comment.