From 15e8edd828972cad274caab88ac91081414e82c5 Mon Sep 17 00:00:00 2001 From: Frederik Wessberg Date: Tue, 7 Jun 2022 23:51:14 +0200 Subject: [PATCH] feat: add support for ESM-based Babel configs. Closes #167 --- src/constant/constant.ts | 1 + src/plugin/typescript-plugin.ts | 4 ++-- src/transpiler/babel.ts | 6 ++--- test/babel.test.ts | 40 ++++++++++++++++++++++++++++++++- 4 files changed, 45 insertions(+), 6 deletions(-) diff --git a/src/constant/constant.ts b/src/constant/constant.ts index ef7bdede..1dc56742 100644 --- a/src/constant/constant.ts +++ b/src/constant/constant.ts @@ -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"; diff --git a/src/plugin/typescript-plugin.ts b/src/plugin/typescript-plugin.ts index 79e7963c..39266ad7 100644 --- a/src/plugin/typescript-plugin.ts +++ b/src/plugin/typescript-plugin.ts @@ -144,7 +144,7 @@ export default function typescriptRollupPlugin(pluginInputOptions: Partial GetBabelConfigResult; +export type BabelConfigFactory = (filename: string, inTypescriptStep?: boolean) => Promise; /** * 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 diff --git a/test/babel.test.ts b/test/babel.test.ts index 7c94a575..5698c75c 100644 --- a/test/babel.test.ts +++ b/test/babel.test.ts @@ -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"; @@ -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(