From aab004def227e7b02de1461acc92d38317d99160 Mon Sep 17 00:00:00 2001 From: Edward Faulkner Date: Thu, 21 Nov 2024 10:08:42 -0500 Subject: [PATCH] Support esm babel plugins This adds test coverage for a vite app with a babel plugin published as an ES module and fixes the one place (in our esbuild resolver) where we were preventing that from working. --- packages/vite/src/esbuild-resolver.ts | 10 ++++---- tests/scenarios/vite-internals-test.ts | 34 ++++++++++++++++++++++++++ 2 files changed, 39 insertions(+), 5 deletions(-) diff --git a/packages/vite/src/esbuild-resolver.ts b/packages/vite/src/esbuild-resolver.ts index e3ee2bc20..683864139 100644 --- a/packages/vite/src/esbuild-resolver.ts +++ b/packages/vite/src/esbuild-resolver.ts @@ -1,5 +1,5 @@ import type { Plugin as EsBuildPlugin, OnLoadResult, PluginBuild, ResolveResult } from 'esbuild'; -import { transform } from '@babel/core'; +import { transformAsync } from '@babel/core'; import core from '@embroider/core'; const { ResolverLoader, virtualContent, needsSyntheticComponentJS, isInComponents } = core; import fs from 'fs-extra'; @@ -17,15 +17,15 @@ export function esBuildResolver(): EsBuildPlugin { let resolverLoader = new ResolverLoader(process.cwd()); let preprocessor = new Preprocessor(); - function transformAndAssert(src: string, filename: string): string { - const result = transform(src, { filename }); + async function transformAndAssert(src: string, filename: string): Promise { + const result = await transformAsync(src, { filename }); if (!result || result.code == null) { throw new Error(`Failed to load file ${filename} in esbuild-hbs-loader`); } return result.code!; } - function onLoad({ path, namespace }: { path: string; namespace: string }): OnLoadResult { + async function onLoad({ path, namespace }: { path: string; namespace: string }): Promise { let src: string; if (namespace === 'embroider-template-only-component') { src = templateOnlyComponent; @@ -40,7 +40,7 @@ export function esBuildResolver(): EsBuildPlugin { src = preprocessor.process(src, { filename: path }); } if (['.hbs', '.gjs', '.gts', '.js', '.ts'].some(ext => path.endsWith(ext))) { - src = transformAndAssert(src, path); + src = await transformAndAssert(src, path); } return { contents: src }; } diff --git a/tests/scenarios/vite-internals-test.ts b/tests/scenarios/vite-internals-test.ts index 45981b9fc..e95d63c19 100644 --- a/tests/scenarios/vite-internals-test.ts +++ b/tests/scenarios/vite-internals-test.ts @@ -113,6 +113,16 @@ function buildViteInternalsTest(testNonColocatedTemplates: boolean, app: Project }, }, tests: { + unit: { + 'babel-plugin-is-module-test.js': ` + import { module, test } from "qunit"; + module("Unit | babel-plugin-is-module", function () { + test("it ran", function (assert) { + assert.strictEqual("sample-transform-target", "sample-transform-result"); + }); + }); + `, + }, integration: { components: { 'example-test.js': ` @@ -230,6 +240,30 @@ function buildViteInternalsTest(testNonColocatedTemplates: boolean, app: Project }, }); app.addDevDependency(v1ExampleAddon); + + let babelPlugin = app.addDevDependency('babel-plugin-is-a-module', { + files: { + 'index.mjs': `export default function({ types }) { + return { + visitor: { + StringLiteral(path) { + if (path.node.value === 'sample-transform-target') { + path.replaceWith(types.stringLiteral('sample-transform-result')); + } + }, + }, + }; + }`, + }, + }); + babelPlugin.pkg.exports = { + '.': './index.mjs', + }; + app.files['babel.config.cjs'] = editBabelConfig(app.files['babel.config.cjs'] as string); +} + +function editBabelConfig(src: string): string { + return src.replace(/babelCompatSupport\(\),/, `babelCompatSupport\(\), 'babel-plugin-is-a-module',`); } function runViteInternalsTest(scenario: Scenario) {