66 lines
1.6 KiB
TypeScript
66 lines
1.6 KiB
TypeScript
import { readFileSync } from "node:fs";
|
|
import { extname } from "node:path";
|
|
|
|
import type babel from "@babel/core";
|
|
import { transformSync } from "@babel/core";
|
|
import type * as esbuild from "esbuild";
|
|
import { once } from "lodash-es";
|
|
|
|
/**
|
|
* An esbuild plugin that processes files with Babel if `plugins` is not empty.
|
|
*/
|
|
export const babelPlugin = ({
|
|
filter = /\.[jt]sx?$/,
|
|
plugins: getPlugins,
|
|
}: {
|
|
filter?: RegExp;
|
|
plugins:
|
|
| babel.PluginItem[]
|
|
| ((file: { path: string; contents: string }) => babel.PluginItem[]);
|
|
}): esbuild.Plugin => ({
|
|
name: "babel-plugin",
|
|
setup(build) {
|
|
build.onLoad({ filter, namespace: "file" }, ({ path }) => {
|
|
const load = once(() => readFileSync(path, "utf-8"));
|
|
const plugins = Array.isArray(getPlugins)
|
|
? getPlugins
|
|
: getPlugins({
|
|
path,
|
|
get contents() {
|
|
return load();
|
|
},
|
|
});
|
|
|
|
if (!plugins.length) {
|
|
return;
|
|
}
|
|
|
|
const { code } = transformSync(load(), {
|
|
assumptions: {
|
|
noDocumentAll: true,
|
|
noClassCalls: true,
|
|
},
|
|
parserOpts: {
|
|
createImportExpressions: true,
|
|
plugins: [
|
|
"jsx",
|
|
"decorators",
|
|
"typescript",
|
|
"importAttributes",
|
|
"explicitResourceManagement",
|
|
"v8intrinsic",
|
|
],
|
|
},
|
|
filename: path,
|
|
plugins,
|
|
sourceType: "module",
|
|
})!;
|
|
|
|
return {
|
|
contents: code!,
|
|
loader: extname(path).slice(1) as "js" | "ts",
|
|
};
|
|
});
|
|
},
|
|
});
|