Skip to content

About

Babel plugin that rewrites react-native barrel imports into direct module imports, so your bundle only includes the React Native APIs you actually use.

Topics

Resources

Stars

62 stars

Watchers

0 watching

Forks

Latest commit

 

History

16 Commits

Folders and files

Repository files navigation

babel-plugin-react-native-direct-imports

npm version npm downloads license

Babel plugin that replaces react-native imports with direct requires of the underlying modules, so only what you use ends up in the bundle.

Warning

This plugin is in an early stage. Expect rough edges and breaking changes, and please report issues if you run into any.

How the plugin works

import { View, AppRegistry, Systrace } from 'react-native';

// ↓ becomes

const View = require('react-native/Libraries/Components/View/View').default;
const AppRegistry = require('react-native/Libraries/ReactNative/AppRegistry').AppRegistry;
const Systrace = require('react-native/Libraries/Performance/Systrace');

Why

react-native/index.js is a CommonJS barrel with a lazy require() getter for every public API. Bundlers can't tree-shake it, so a single import { View } from 'react-native' pulls in all of React Native (VirtualView, PushNotificationIOS, ...).

Bundle with only import { ReactNativeVersion } from 'react-native', before and after:

Bundle before and after the plugin

To measure your own bundle, use react-native-bundle-discovery.

Why require() and not import?

React Native's modules are CommonJS. If the plugin emitted import View from '...', Babel's CommonJS transform would wrap every one in _interopRequireDefault() / _interopRequireWildcard() and add those helpers to each file. A plain require(...).default gives the same value without the extra code.

Install

npm install --save-dev babel-plugin-react-native-direct-imports

Usage

// babel.config.js
module.exports = {
  presets: [
    // the plugin generates deep imports on purpose
    ['module:@react-native/babel-preset', { disableDeepImportWarnings: true }],
  ],
  plugins: [
    process.env.NODE_ENV !== 'test' && [
      'react-native-direct-imports',
      { reactNativeVersion: require('react-native/package.json').version },
    ],
  ].filter(Boolean),
};

Then reset the Metro cache once (npx react-native start --reset-cache or npx expo start --clear).

reactNativeVersion picks the map from maps/ (default: the latest). Every stable release from 0.70.0 has one. The version must match exactly, otherwise the build fails, so update the plugin after upgrading React Native.

silenceBatchedUpdatesWarning (default: false) hides the warning logged once when unstable_batchedUpdates is imported on React Native 0.86+, where it does nothing and just calls the callback.

Notes

  • Unknown names and type-only imports are left untouched.
  • Re-exports (export { X } from 'react-native') and require('react-native') in compiled CommonJS code (e.g. in node_modules) are rewritten too.
  • Platform stays a local Platform variable, so Metro's Platform.OS / Platform.select inlining keeps working (not for aliases like Platform as P).
  • import * as RN from 'react-native' and module.exports = require('react-native') throw a build error.
  • Generated paths point to React Native internals, which is why every version has its own map.

Compatibility

  • ✅ Uniwind: withUniwindConfig also redirects deep react-native/Libraries/... imports of the components it styles, so className keeps working.
  • ⚠️ react-native-worklets bundle mode: before 0.14.0, getBundleModeMetroConfig resolves react-native to its own shim, which sets up the worklet runtime. The deep paths skip it, so don't combine them on react-native-worklets < 0.14.0; upgrade to 0.14.0 or newer.

Generating maps (development)

yarn generate-maps            # all versions
yarn generate-maps 0.88.0     # specific versions

License

MIT

About

Babel plugin that rewrites react-native barrel imports into direct module imports, so your bundle only includes the React Native APIs you actually use.

Topics

Resources

Stars

62 stars

Watchers

0 watching

Forks

Contributors

Languages