babel-plugin-tree-shake-imports
A babel plugin to tree-shake namespace imports.
This babel plugin helps you to use TypeScript namespaces, in particular ambient namespaces, or regular barrel files for the purpose of namespacing by tree-shaking their import declarations:
ts
// Vanilla approach:
import { getUserEmail } from "utils/user/getUserEmail";
const userEmail = getUserEmail(user);
// Using namespaces:
import { User } from "utils";
const userEmail = User.email(user);
// After transforming with babel-plugin-tree-shake-imports:
import { email as _email } from "utils/User/email";
const userEmail = email(user);
Features
- Works for all (ESM) import specifier types, including mixed ones
- Allows you to rewire/skip each individual imported module
- Supports recursive destructuring
Examples
ts
import Foo from "foo";
Foo.bar;
ts
import { bar as _bar } from "foo/bar";
_bar;
ts
import { Foo } from "foo";
Foo.bar;
ts
import { bar as _bar } from "foo/bar";
_bar;
ts
import { Foo as Bar } from "foo";
Bar.bar;
ts
import { bar as _bar } from "foo/bar";
_bar;
ts
import * as Foo from "foo";
Foo.bar;
ts
import { bar as _bar } from "foo/bar";
_bar;
ts
import Foo from "foo";
Foo.bar.baz;
ts
import { baz as _baz } from "foo/bar/baz";
_baz;
Installation
sh
npm -D install @monstermann/babel-plugin-tree-shake-imports
sh
pnpm -D add @monstermann/babel-plugin-tree-shake-imports
sh
yarn -D add @monstermann/babel-plugin-tree-shake-imports
sh
bun -D add @monstermann/babel-plugin-tree-shake-imports
Usage
ts
export default {
plugins: [["@monstermann/babel-plugin-tree-shake-imports", options]],
};
ts
import { defineConfig } from "vite";
import react from "@vitejs/plugin-react";
export default defineConfig(() => ({
plugins: [
react({
babel: {
plugins: [
["@monstermann/babel-plugin-tree-shake-imports", options],
],
},
}),
],
}));
Options
ts
import { A as B } from "c";
A.d;
ts
const options = {
resolve({
// The path of the file being transformed: "example.ts"
filePath,
// The imported module: "c"
importPath,
// The imported identifier: "A"
importName,
// The local alias: "B"
// Same as `importName` if not available.
localName,
// The property that was accessed: "d"
propertyName,
// The type of the import: "named"
// One of: "named" | "default" | "wildcard"
importType,
}) {
// Skip this import:
return null;
return undefined;
return false;
// Transform this to:
// import { d as _d } from "c/d";
// _d;
return {
type: "named",
path: `${importPath}/${propertyName}`,
};
// Transform this to:
// import { e as _d } from "c/d";
// _d;
return {
type: "named",
importName: "e",
path: `${importPath}/${propertyName}`,
};
// Transform this to:
// import _d from "c/d";
// _d;
return {
type: "default",
path: `${importPath}/${propertyName}`,
};
},
};
Troubleshooting
You can use the debug
flag to print the individual transformations being done to each file.
ts
const options = {
debug: true,
resolve: () => ({ path, type }),
};