I'm implementing module level's tree shaking in here https://github.com/chang-ke/metro/pull/1 锛坕t can shake lodash-es,react-native-svg now锛塰ope given some suggestions
@cpojer Does metro interested in it?锛坱hen review it)
I actually find this super interesting. What status is your PR in? How far along is the implementation and can you show some differences in bundle sizes?
I actually find this super interesting. What status is your PR in? How far along is the implementation and can you show some differences in bundle sizes?
actually it used in my project now, but no test case. the differences of bundle sizes dependes on what npm package you used, I will give some cases and this pr has example project that you can get some real differences bundle sizes by running
Just a side note: I propose that tree-shaking for metro bundler follows webpack sideEffects package.json field, see https://webpack.js.org/guides/tree-shaking/#mark-the-file-as-side-effect-free
Just a side note: I propose that tree-shaking for metro bundler follows webpack
sideEffectspackage.json field, see https://webpack.js.org/guides/tree-shaking/#mark-the-file-as-side-effect-free
got it
I actually find this super interesting. What status is your PR in? How far along is the implementation and can you show some differences in bundle sizes?
metro config
/**
* Metro configuration for React Native
* https://github.com/facebook/react-native
*
* @format
*/
const path = require('path');
const { getDefaultConfig } = require('metro-config');
module.exports = (async () => {
const {
resolver: { sourceExts, resolverMainFields },
} = await getDefaultConfig();
return {
watchFolders: [path.resolve('../packages/')],
transformer: {
getTransformOptions: async () => ({
transform: {
experimentalImportSupport: false,
inlineRequires: false,
},
}),
experimentalTreeShaking: true,
assetRegistryPath: require.resolve(
'react-native/Libraries/Image/AssetRegistry',
),
babelTransformerPath: require.resolve('../packages/metro-react-native-babel-transformer'),
},
serializer: {
getPolyfills: require('react-native/rn-get-polyfills'),
getModulesRunBeforeMainModule: () => [require.resolve(
require.resolve('react-native/Libraries/Core/InitializeCore'),
)]
},
resolver: {
sourceExts: ['ios.js', 'android.js', ...sourceExts],
blockList: /(website\/node_modules\/.*|.*\/__tests__\/.*)$/,
resolverMainFields: ['react-native', 'module', ...resolverMainFields],
},
}})();
index.js:
/**
* @format
*/
import {AppRegistry} from 'react-native'
index.js:
/**
* @format
*/
import {AppRegistry} from 'react-native'
import App from './App';
import {name as appName} from './app.json';
AppRegistry.registerComponent(appName, () => App);
App.js:
import React from 'react';
import {SafeAreaView, StatusBar, Text} from 'react-native';
import {Svg, Path} from 'react-native-svg';
const App = () => {
return (
<>
<StatusBar barStyle="dark-content" />
<SafeAreaView>
<Svg
width="130"
height="130"
fill="blue"
stroke="red"
color="green"
viewBox="-16 -16 544 544">
<Path
d="M318.37,85.45L422.53,190.11,158.89,455,54.79,350.38ZM501.56,60.2L455.11,13.53a45.93,45.93,0,0,0-65.11,0L345.51,58.24,449.66,162.9l51.9-52.15A35.8,35.8,0,0,0,501.56,60.2ZM0.29,497.49a11.88,11.88,0,0,0,14.34,14.17l116.06-28.28L26.59,378.72Z"
strokeWidth="32"
/>
<Path d="M0,0L512,512" stroke="currentColor" strokeWidth="32" />
</Svg>
</SafeAreaView>
</>
);
};
export default App;
index.js:
/**
* @format
*/
import {AppRegistry} from 'react-native'
import App from './App';
import {name as appName} from './app.json';
AppRegistry.registerComponent(appName, () => App);
App.js:
import React from 'react';
import {SafeAreaView, StatusBar, Text} from 'react-native';
import {toString} from 'lodash-es';
const App = () => {
return (
<>
<StatusBar barStyle="dark-content" />
<SafeAreaView>
<Text>{toString([1, 2])}</Text>
</SafeAreaView>
</>
);
};
export default App;
What is the next step here?
I have to say I am very interested in this work.
We are now at 7.10 mB in our project.
@chang-ke could it be useful that we try your fix in our project?
If you can give me the basics on how to use it in my project I could give another example of tree-shaking for our huge app.
What is the next step here?
I have to say I am very interested in this work.
We are now at
7.10 mBin our project.@chang-ke could it be useful that we try your fix in our project?
If you can give me the basics on how to use it in my project I could give another example of tree-shaking for our huge app.
you can clone this repo and run it by https://github.com/facebook/metro/issues/632#issuecomment-790253097 's metro config or https://github.com/chang-ke/metro/tree/feature/tree-shaking/examples.
Most helpful comment
metro config
common bundle (only [email protected])
index.js:
### bundle size: 658KB
common bundle with react-native-svg
index.js:
App.js:
no tree-shaking bundle size: 1191KB
tree-shaking bundle size: 700KB
common bundle with lodash-es
index.js:
App.js:
no tree-shaking bundle size: 940KB
tree-shaking bundle size: 661KB