const lazyImportsBlacklist = require('./lazy-imports-blacklist'); module.exports = function(api, options = {}) { const { web = {}, native = {} } = options; const isWeb = api.caller(isTargetWeb); const platformOptions = isWeb ? { disableImportExportTransform: true, ...web } : { disableImportExportTransform: false, ...native }; // Note that if `options.lazyImports` is not set (i.e., `null` or `undefined`), // `metro-react-native-babel-preset` will handle it. const lazyImportsOption = options && options.lazyImports; return { presets: [ [ // We use `require` here instead of directly using the package name // because we want to specifically use the `metro-react-native-babel-preset` // installed in this folder's `node_modules` (`babel-preset-expo/node_modules/`). // This way the preset will not change unintentionally. // Reference: https://github.com/expo/expo/pull/4685#discussion_r307143920 require('metro-react-native-babel-preset'), { disableImportExportTransform: platformOptions.disableImportExportTransform, lazyImportExportTransform: lazyImportsOption === true ? importModuleSpecifier => { // Do not lazy-initialize packages that are local imports (similar to `lazy: true` behavior) // or are in the blacklist. return !( importModuleSpecifier.includes('./') || lazyImportsBlacklist.has(importModuleSpecifier) ); } : // Pass the option directly to `metro-react-native-babel-preset` // (which in turns pass it to `babel-plugin-transform-modules-commonjs`). lazyImportsOption, }, ], ], plugins: [ [ require.resolve('babel-plugin-module-resolver'), { alias: { 'react-native-vector-icons': '@expo/vector-icons', }, }, ], [require.resolve('@babel/plugin-proposal-decorators'), { legacy: true }], isWeb && [require.resolve('babel-plugin-react-native-web')], ].filter(Boolean), }; }; function isTargetWeb(caller) { return caller && caller.name === 'babel-loader'; }