From a53372ceb3a5ce9707e7a8a60139434025df5722 Mon Sep 17 00:00:00 2001 From: Nicolas Gallagher Date: Mon, 19 Feb 2018 12:34:32 -0800 Subject: [PATCH] [fix] babel-plugin only rewrites paths for known modules Don't rewrite import paths for non-existent modules or types. They will attempt to be imported from the package's main export. This change currently requires a module map to be generated for the babel-plugin to use. The map is automatically regenerated for any commit that alters the entry file of react-native-web. Fix #822 --- package.json | 3 + .../__snapshots__/index-test.js.snap | 2 +- .../src/index.js | 4 +- .../src/moduleMap.js | 61 +++++++++++++++++++ scripts/babel/createModuleMap.js | 24 ++++++++ 5 files changed, 92 insertions(+), 2 deletions(-) create mode 100644 packages/babel-plugin-react-native-web/src/moduleMap.js create mode 100644 scripts/babel/createModuleMap.js diff --git a/package.json b/package.json index 1e085443..3c3b0885 100644 --- a/package.json +++ b/package.json @@ -62,6 +62,9 @@ "fmt:cmd", "git update-index --again", "eslint" + ], + "packages/react-native-web/src/index.js": [ + "node ./scripts/babel/createModuleMap.js" ] }, "prettier": { diff --git a/packages/babel-plugin-react-native-web/src/__tests__/__snapshots__/index-test.js.snap b/packages/babel-plugin-react-native-web/src/__tests__/__snapshots__/index-test.js.snap index 7c0cb841..8a6cc907 100644 --- a/packages/babel-plugin-react-native-web/src/__tests__/__snapshots__/index-test.js.snap +++ b/packages/babel-plugin-react-native-web/src/__tests__/__snapshots__/index-test.js.snap @@ -41,7 +41,7 @@ import * as ReactNativeModules from 'react-native'; import ReactNative from 'react-native-web/dist/index'; import View from 'react-native-web/dist/exports/View'; -import Invalid from 'react-native-web/dist/exports/Invalid'; +import { Invalid } from 'react-native-web/dist/index'; import MyView from 'react-native-web/dist/exports/View'; import ViewPropTypes from 'react-native-web/dist/exports/ViewPropTypes'; import * as ReactNativeModules from 'react-native-web/dist/index'; diff --git a/packages/babel-plugin-react-native-web/src/index.js b/packages/babel-plugin-react-native-web/src/index.js index a8b86ac5..bdd2606b 100644 --- a/packages/babel-plugin-react-native-web/src/index.js +++ b/packages/babel-plugin-react-native-web/src/index.js @@ -1,5 +1,7 @@ +const moduleMap = require('./moduleMap'); + const getDistLocation = importName => - importName ? `react-native-web/dist/exports/${importName}` : undefined; + importName && moduleMap[importName] ? `react-native-web/dist/exports/${importName}` : undefined; const isReactNativeRequire = (t, node) => { const { declarations } = node; diff --git a/packages/babel-plugin-react-native-web/src/moduleMap.js b/packages/babel-plugin-react-native-web/src/moduleMap.js new file mode 100644 index 00000000..6299c8da --- /dev/null +++ b/packages/babel-plugin-react-native-web/src/moduleMap.js @@ -0,0 +1,61 @@ +// THIS FILE IS AUTOMATICALLY GENERATED. DO NOT EDIT. +module.exports = { + ART: true, + ActivityIndicator: true, + Animated: true, + AppRegistry: true, + AppState: true, + AsyncStorage: true, + BackHandler: true, + Button: true, + CheckBox: true, + Clipboard: true, + ColorPropType: true, + Dimensions: true, + Easing: true, + EdgeInsetsPropType: true, + FlatList: true, + I18nManager: true, + Image: true, + ImageBackground: true, + InteractionManager: true, + Keyboard: true, + KeyboardAvoidingView: true, + Linking: true, + ListView: true, + Modal: true, + NativeModules: true, + NetInfo: true, + PanResponder: true, + Picker: true, + PixelRatio: true, + Platform: true, + PointPropType: true, + ProgressBar: true, + RefreshControl: true, + SafeAreaView: true, + ScrollView: true, + SectionList: true, + Slider: true, + StatusBar: true, + StyleSheet: true, + Switch: true, + Text: true, + TextInput: true, + TextPropTypes: true, + Touchable: true, + TouchableHighlight: true, + TouchableNativeFeedback: true, + TouchableOpacity: true, + TouchableWithoutFeedback: true, + UIManager: true, + Vibration: true, + View: true, + ViewPropTypes: true, + VirtualizedList: true, + createElement: true, + findNodeHandle: true, + processColor: true, + render: true, + unmountComponentAtNode: true +}; diff --git a/scripts/babel/createModuleMap.js b/scripts/babel/createModuleMap.js new file mode 100644 index 00000000..4a4f142c --- /dev/null +++ b/scripts/babel/createModuleMap.js @@ -0,0 +1,24 @@ +/** + * Creates a map of exported modules, allowing the RNW babel plugin to rewrite + * paths only for modules it knows are exported by RNW. + */ +const fs = require('fs'); +const path = require('path'); + +const isDirectory = source => fs.lstatSync(source).isDirectory(); +const getDirectories = source => + fs.readdirSync(source).filter(name => isDirectory(path.join(source, name))); + +const packagesDir = path.join(__dirname, '../../packages/'); +const exportsDir = path.join(packagesDir, 'react-native-web/src/exports'); +const moduleMapOutfile = path.join(__dirname, 'babel-plugin-react-native-web/src/moduleMap.js'); + +const moduleMap = getDirectories(exportsDir).reduce((acc, curr) => { + acc[curr] = true; + return acc; +}, {}); + +const data = `// THIS FILE IS AUTOMATICALLY GENERATED. DO NOT EDIT. +module.exports = ${JSON.stringify(moduleMap, null, 2)}`; + +fs.writeFileSync(moduleMapOutfile, data);