[Issue][Native] All icons are added to the native bundle #1634
Replies: 3 comments 5 replies
-
You'd have to import them directly, or we'd need a babel plugin that auto-rewrites the imports which is a good idea. Converting to discussion since its more of a feature request. |
Beta Was this translation helpful? Give feedback.
-
you can use https://microsoft.github.io/rnx-kit/docs/guides/bundling#tree-shaking it basically runs the metro-produced code through esbuild, afaik |
Beta Was this translation helpful? Give feedback.
-
for those coming here from expo, rnx-kit is a bit annoying (if even possible) to match with expo easyly so i tried something else. and use babel transform on lucide-icon. https://www.npmjs.com/package/babel-plugin-transform-imports // config.babel.js
const wordSeparators = /[\s\u2000-\u206F\u2E00-\u2E7F\\'!"#$%&()*+,\-.\/:;<=>?@\[\]^_`{|}~]+/
const capital_plus_lower = /[A-ZÀ-Ý\u00C0-\u00D6\u00D9-\u00DD][a-zà-ÿ]/g
const capitals = /[A-Z0-9À-Ý\u00C0-\u00D6\u00D9-\u00DD]+/g
function kebabCase(str) {
let res = str
// replace word starts with space + lower case equivalent for later parsing
// 1) treat cap + lower as start of new word
res = str.replace(
capital_plus_lower,
(match) =>
// match is one caps followed by one non-cap
` ${match[0].toLowerCase() || match[0]}${match[1]}`,
)
// 2) treat all remaining capitals as words
res = res.replace(
capitals,
(match) =>
// match is a series of caps
` ${match.toLowerCase()}`,
)
return res.trim().split(wordSeparators).join("-").replace(/^-/, "").replace(/-\s*$/, "")
}
module.exports = (api) => {
api.cache(true)
return {
presets: [["babel-preset-expo", { jsxRuntime: "automatic" }]],
env: {
production: {
plugins: ["transform-remove-console"],
},
},
plugins: [
[
"transform-imports",
{
"@tamagui/lucide-icons": {
transform: (importName) => `@tamagui/lucide-icons/dist/esm/icons/${kebabCase(importName)}`,
preventFullImport: true,
skipDefaultConversion: true,
},
},
],
"react-native-reanimated/plugin",
],
}
} |
Beta Was this translation helpful? Give feedback.
Uh oh!
There was an error while loading. Please reload this page.
Uh oh!
There was an error while loading. Please reload this page.
-
Current Behavior
When importing any component from Tamagui in a native app, all of the icons are added to the bundle, the screenshot below is from the kitchen sink app in this repo, there are 4 icons used but all of them are added to the bundle
Expected Behavior
Only used icons directly or indirectly should be added to the bundle
Worth noting that Metro doesn't directly support tree shaking (see facebook/metro#227) but there is definitely something that can be done to prevent all the icons to be imported when importing anything from Tamagui
while investigating this on my app, I removed everything except importing a single
YStack
and all icons were added to the bundleTamagui Version
Reproduction
Any further question or context please ask, hopefully I painted the right picture
Beta Was this translation helpful? Give feedback.
All reactions