3320513d7a
Lucide ships one module per icon, but the barrel import dragged all ~1600 in. A local Babel plugin rewrites each named import to its own icon module, so the bundle drops from 4.66 MB to 3.40 MB and the earliest tap that reliably lands a photo moves from ~1.8 s to ~1.6 s on the test device.
39 lines
1.2 KiB
JavaScript
39 lines
1.2 KiB
JavaScript
// Lucide ships one module per icon, but the barrel import drags all ~1600 in.
|
|
// Rewrite each named import into its own icon module so Metro only walks what we use.
|
|
const lucidePerIcon = () => ({
|
|
visitor: {
|
|
ImportDeclaration(path) {
|
|
if (path.node.source.value !== "lucide-react-native") return;
|
|
const t = require("@babel/types");
|
|
const kebab = (n) =>
|
|
n
|
|
.replace(/([a-z0-9])([A-Z])/g, "$1-$2")
|
|
.replace(/([A-Za-z])(\d)/g, "$1-$2")
|
|
.toLowerCase();
|
|
path.replaceWithMultiple(
|
|
path.node.specifiers.map((s) =>
|
|
s.type === "ImportSpecifier"
|
|
? t.importDeclaration(
|
|
[t.importDefaultSpecifier(s.local)],
|
|
t.stringLiteral(`lucide-react-native/icons/${kebab(s.imported.name)}`)
|
|
)
|
|
: t.importDeclaration([s], t.stringLiteral("lucide-react-native"))
|
|
)
|
|
);
|
|
},
|
|
},
|
|
});
|
|
module.exports = function (api) {
|
|
api.cache(true);
|
|
return {
|
|
presets: [
|
|
["babel-preset-expo", { jsxImportSource: "nativewind" }],
|
|
"nativewind/babel",
|
|
],
|
|
plugins: [
|
|
"react-native-reanimated/plugin",
|
|
lucidePerIcon
|
|
],
|
|
};
|
|
};
|