mirror of
https://github.com/bulwarkmail/native.git
synced 2026-10-31 16:06:32 +00:00
93 files import icons from the `lucide-react-native` barrel. Metro has
no tree shaking, so the barrel pulled all 1,694 icons into the bundle
and evaluated every one of them at startup.
A small Babel plugin (`scripts/babel-plugin-lucide-imports.js`, wired
up in the new `babel.config.js` on top of `babel-preset-expo`) rewrites
each named import to the per-icon module the barrel re-exports, e.g.
`import { Mail } from 'lucide-react-native'` becomes a default import of
`lucide-react-native/dist/esm/icons/mail.js`. The name table is read
from the package's own barrel, so aliases such as `MailIcon` or renamed
icons keep resolving; an unknown name fails the build. The package's
`exports` map only lists the barrel, so the new `metro.config.js`
resolves these deep paths as plain files instead of warning about each.
A test checks that every icon imported in the app maps to an existing
module and that no default or namespace import brings the barrel back.
Measured with `npx expo export --platform android`:
- modules in the bundle: 3,995 -> 2,469 (lucide: 1,701 -> 175)
- Hermes bundle: 9.34 MB -> 8.19 MB
- modules evaluated at startup: 3,564 -> 2,038
Metro does not key its transform cache on the Babel config, so a warm
dev cache keeps serving the old barrel imports until
`npx expo start --clear`.
21 lines
875 B
JavaScript
21 lines
875 B
JavaScript
const { getDefaultConfig } = require('expo/metro-config');
|
|
|
|
const config = getDefaultConfig(__dirname);
|
|
|
|
// babel.config.js rewrites lucide-react-native imports to per-icon modules
|
|
// under dist/ (scripts/babel-plugin-lucide-imports.js). The package's
|
|
// `exports` map only lists its barrel, so resolve those paths as plain files
|
|
// instead of letting Metro warn about every one of them.
|
|
const LUCIDE_DEEP_IMPORT = 'lucide-react-native/dist/';
|
|
const upstreamResolveRequest = config.resolver.resolveRequest;
|
|
|
|
config.resolver.resolveRequest = (context, moduleName, platform) => {
|
|
const resolve = upstreamResolveRequest ?? context.resolveRequest;
|
|
if (moduleName.startsWith(LUCIDE_DEEP_IMPORT)) {
|
|
return resolve({ ...context, unstable_enablePackageExports: false }, moduleName, platform);
|
|
}
|
|
return resolve(context, moduleName, platform);
|
|
};
|
|
|
|
module.exports = config;
|