Skip to content

Commit

Permalink
feat: add support for ESM-based Babel configs. Closes #167
Browse files Browse the repository at this point in the history
  • Loading branch information
wessberg committed Jun 7, 2022
1 parent 5ba4c9c commit 15e8edd
Show file tree
Hide file tree
Showing 4 changed files with 45 additions and 6 deletions.
1 change: 1 addition & 0 deletions src/constant/constant.ts
Original file line number Diff line number Diff line change
Expand Up @@ -83,6 +83,7 @@ export const BABEL_RUNTIME_PREFIX_2 = "babel-runtime/";
export const SWC_HELPERS_PREFIX = "@swc/helpers";

export const BABEL_CONFIG_JS_FILENAME = "babel.config.js";
export const BABEL_CONFIG_MJS_FILENAME = "babel.config.mjs";
export const BABEL_CONFIG_JSON_FILENAME = "babel.config.json";
export const BABELRC_FILENAME = ".babelrc";

Expand Down
4 changes: 2 additions & 2 deletions src/plugin/typescript-plugin.ts
Original file line number Diff line number Diff line change
Expand Up @@ -144,7 +144,7 @@ export default function typescriptRollupPlugin(pluginInputOptions: Partial<Types
// Conditionally initialize babel at this point.
// Only require @babel/preset-typescript if relevant for the initial emit that may include TypeScript specific syntax
const babel = await loadBabel(initial);
const babelConfigResult = babelConfigFileFactory!(fileName, initial);
const babelConfigResult = await babelConfigFileFactory!(fileName, initial);

const transpilationResult = await babel.transformAsync(input.code, {
...babelConfigResult.config,
Expand Down Expand Up @@ -339,7 +339,7 @@ export default function typescriptRollupPlugin(pluginInputOptions: Partial<Types
let updatedSourceDescription: SourceDescription | undefined;

if (transpilerOptions.otherSyntax === "babel") {
const {config} = babelConfigChunkFactory!(chunk.fileName);
const {config} = await babelConfigChunkFactory!(chunk.fileName);
const babel = await loadBabel();

// When targeting CommonJS and using babel as a transpiler, we may need to rewrite forced ESM paths for preserved external helpers to paths that are compatible with CommonJS.
Expand Down
6 changes: 3 additions & 3 deletions src/transpiler/babel.ts
Original file line number Diff line number Diff line change
Expand Up @@ -160,16 +160,16 @@ export interface GetBabelConfigResult {
config: FullConfig | undefined;
}

export type BabelConfigFactory = (filename: string, inTypescriptStep?: boolean) => GetBabelConfigResult;
export type BabelConfigFactory = (filename: string, inTypescriptStep?: boolean) => Promise<GetBabelConfigResult>;

/**
* Gets a Babel Config based on the given options
*/
export function getBabelConfig({babel, babelConfig, cwd, forcedOptions = {}, defaultOptions = {}, browserslist, phase, hook}: GetBabelConfigOptions): BabelConfigFactory {
return (filename: string, inTypescriptStep = false) => {
return async (filename: string, inTypescriptStep = false) => {

// Load a partial Babel config based on the input options
const partialConfig = babel.loadPartialConfig(
const partialConfig = await babel.loadPartialConfigAsync(
// If babel options are provided directly
isBabelConfig(babelConfig) && Object.keys(babelConfig).length > 0
? // If the given babelConfig is an object of input options, use that as the basis for the full config
Expand Down
40 changes: 39 additions & 1 deletion test/babel.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ import test, {ExecutionContext} from "ava";
import {withTypeScript, withTypeScriptVersions} from "./util/ts-macro.js";
import {ConfigItem} from "@babel/core";
import {generateRollupBundle} from "./setup/setup-rollup.js";
import {BABEL_CONFIG_JS_FILENAME, BABEL_CONFIG_JSON_FILENAME, BABELRC_FILENAME} from "../src/constant/constant.js";
import {BABEL_CONFIG_JS_FILENAME, BABEL_CONFIG_JSON_FILENAME, BABELRC_FILENAME, BABEL_CONFIG_MJS_FILENAME} from "../src/constant/constant.js";
import {areTempFilesEqual, createTemporaryFile} from "./util/create-temporary-file.js";
import {getAppropriateEcmaVersionForBrowserslist} from "browserslist-generator";
import {formatCode} from "./util/format-code.js";
Expand Down Expand Up @@ -270,6 +270,44 @@ test.serial("Can resolve the nearest file-relative babel config. #1", withTypeSc
}
});

test.serial("Can handle ESM-based babel configs. #1", withTypeScript, async (t, {typescript}) => {
const unlinker = createTemporaryFile(BABEL_CONFIG_MJS_FILENAME, `export default {}`);
let configFileName: string | undefined;
let forcePass = false;

try {
await generateRollupBundle(
[
{
entry: true,
fileName: "index.ts",
text: `\
`
}
],
{
debug: false,
typescript,
cwd: unlinker.dir,
transpiler: "babel",
hook: {
babelConfig: (config, fileName) => {
configFileName = fileName;
return config;
}
}
}
);
} catch (ex) {
if (handlePotentiallyAllowedFailingBabelError(t, ex)) {
forcePass = true;
}
} finally {
unlinker.cleanup();
t.true(forcePass || (configFileName != null && areTempFilesEqual(configFileName, unlinker.path)));
}
});

test.serial("Won't apply @babel/preset-env if the browserslist option is 'false'. #1", withTypeScript, async (t, {typescript}) => {
let hasPresetEnv: boolean | undefined;
await generateRollupBundle(
Expand Down

0 comments on commit 15e8edd

Please sign in to comment.