From a6136aefc83ab722679e495145e460bebf36f4b8 Mon Sep 17 00:00:00 2001 From: stream-ci-bot Date: Fri, 18 Jun 2021 13:28:50 -0300 Subject: [PATCH 1/5] use new metro-dev-helpers instead of copy-pasted metro config --- examples/ExpoMessaging/metro.config.js | 155 +--------------- examples/NativeMessaging/metro.config.js | 157 +--------------- examples/SampleApp/metro.config.js | 181 +------------------ examples/TypeScriptMessaging/metro.config.js | 175 +----------------- metro-dev-helpers.js | 144 +++++++++++++++ 5 files changed, 168 insertions(+), 644 deletions(-) create mode 100644 metro-dev-helpers.js diff --git a/examples/ExpoMessaging/metro.config.js b/examples/ExpoMessaging/metro.config.js index dc82335281..27eeee91d3 100644 --- a/examples/ExpoMessaging/metro.config.js +++ b/examples/ExpoMessaging/metro.config.js @@ -1,152 +1,13 @@ /* eslint-env node */ -function resolvePath(...parts) { - const thisPath = PATH.resolve.apply(PATH, parts); - if (!FS.existsSync(thisPath)) return; - - return FS.realpathSync(thisPath); -} - -function isExternalModule(modulePath) { - return modulePath.substring(0, __dirname.length) !== __dirname; -} - -function listDirectories(rootPath, cb) { - FS.readdirSync(rootPath).forEach((fileName) => { - if (fileName.charAt(0) === '.') return; - - let fullFileName = PATH.join(rootPath, fileName), - stats = FS.lstatSync(fullFileName), - symbolic = false; - - if (stats.isSymbolicLink()) { - fullFileName = resolvePath(fullFileName); - if (!fullFileName) return; - - stats = FS.lstatSync(fullFileName); - - symbolic = true; - } - - if (!stats.isDirectory()) return; - - const external = isExternalModule(fullFileName); - cb({ rootPath, symbolic, external, fullFileName, fileName }); - }); -} - -function buildFullModuleMap( - moduleRoot, - mainModuleMap, - externalModuleMap, - _alreadyVisited, - _prefix, -) { - if (!moduleRoot) return; - - const alreadyVisited = _alreadyVisited || {}, - prefix = _prefix; - - if (alreadyVisited && alreadyVisited.hasOwnProperty(moduleRoot)) return; - - alreadyVisited[moduleRoot] = true; - - listDirectories(moduleRoot, ({ fileName, fullFileName, symbolic, external }) => { - if (symbolic) - return buildFullModuleMap( - resolvePath(fullFileName, 'node_modules'), - mainModuleMap, - externalModuleMap, - alreadyVisited, - ); - - const moduleMap = external ? externalModuleMap : mainModuleMap, - moduleName = prefix ? PATH.join(prefix, fileName) : fileName; - - if (fileName.charAt(0) !== '@') moduleMap[moduleName] = fullFileName; - else - return buildFullModuleMap( - fullFileName, - mainModuleMap, - externalModuleMap, - alreadyVisited, - fileName, - ); - }); -} - -function buildModuleResolutionMap() { - const moduleMap = {}, - externalModuleMap = {}; - - buildFullModuleMap(baseModulePath, moduleMap, externalModuleMap); - - // Root project modules take precedence over external modules - return Object.assign({}, externalModuleMap, moduleMap); -} - -function findAlternateRoots(moduleRoot = baseModulePath, alternateRoots = [], _alreadyVisited) { - const alreadyVisited = _alreadyVisited || {}; - if (alreadyVisited && alreadyVisited.hasOwnProperty(moduleRoot)) return; - - alreadyVisited[moduleRoot] = true; - - listDirectories(moduleRoot, ({ fullFileName, fileName, external }) => { - if (fileName.charAt(0) !== '@') { - if (external) alternateRoots.push(fullFileName); - } else { - findAlternateRoots(fullFileName, alternateRoots, alreadyVisited); - } - }); - - return alternateRoots; -} - -function getPolyfillHelper() { - let getPolyfills; - - // Get default react-native polyfills - try { - getPolyfills = require('react-native/rn-get-polyfills'); - } catch (e) { - getPolyfills = () => []; - } - - // See if project has custom polyfills, if so, include the PATH to them - try { - const customPolyfills = require.resolve('./polyfills.js'); - getPolyfills = (function (originalGetPolyfills) { - return () => originalGetPolyfills().concat(customPolyfills); - })(getPolyfills); - } catch (e) { - //ignore - } - - return getPolyfills; -} const PATH = require('path'); -const FS = require('fs'), - blacklist = require('metro-config/src/defaults/blacklist'); +const blacklist = require('metro-config/src/defaults/blackList'); -const repoDir = PATH.dirname(PATH.dirname(__dirname)); +const extractExternalModules = require('stream-chat-react-native-core/metro-dev-helpers'); -const moduleBlacklist = [ - new RegExp(repoDir + '/examples/NativeMessaging/.*'), - new RegExp(repoDir + '/examples/SampleApp/.*'), - new RegExp(repoDir + '/examples/TypeScriptMessaging/.*'), - new RegExp(repoDir + '/native-package/.*'), - new RegExp(repoDir + '/expo-package/node_modules/.*'), - new RegExp(repoDir + '/node_modules/.*'), - ], - baseModulePath = resolvePath(__dirname, 'node_modules'), - // watch alternate roots (outside of project root) - alternateRoots = findAlternateRoots(), - // build full module map for proper - // resolution of modules in external roots - extraNodeModules = buildModuleResolutionMap(); +const projectRoot = PATH.resolve(__dirname); -if (alternateRoots && alternateRoots.length) - console.log('Found alternate project roots: ', alternateRoots); +const { alternateRoots, extraNodeModules, moduleBlacklist } = extractExternalModules(projectRoot); module.exports = { resolver: { @@ -154,11 +15,5 @@ module.exports = { extraNodeModules, useWatchman: false, }, - watchFolders: [PATH.resolve(__dirname)].concat(alternateRoots), - // transformer: { - // babelTransformerPath: require.resolve('./compiler/transformer'), - // }, - serializer: { - getPolyfills: getPolyfillHelper(), - }, + watchFolders: [projectRoot].concat(alternateRoots), }; diff --git a/examples/NativeMessaging/metro.config.js b/examples/NativeMessaging/metro.config.js index b2268a4c41..27eeee91d3 100644 --- a/examples/NativeMessaging/metro.config.js +++ b/examples/NativeMessaging/metro.config.js @@ -1,164 +1,19 @@ /* eslint-env node */ -function resolvePath(...parts) { - const thisPath = PATH.resolve.apply(PATH, parts); - if (!FS.existsSync(thisPath)) return; - - return FS.realpathSync(thisPath); -} - -function isExternalModule(modulePath) { - return modulePath.substring(0, __dirname.length) !== __dirname; -} - -function listDirectories(rootPath, cb) { - FS.readdirSync(rootPath).forEach((fileName) => { - if (fileName.charAt(0) === '.') return; - - let fullFileName = PATH.join(rootPath, fileName), - stats = FS.lstatSync(fullFileName), - symbolic = false; - - if (stats.isSymbolicLink()) { - fullFileName = resolvePath(fullFileName); - if (!fullFileName) return; - - stats = FS.lstatSync(fullFileName); - - symbolic = true; - } - - if (!stats.isDirectory()) return; - - const external = isExternalModule(fullFileName); - cb({ rootPath, symbolic, external, fullFileName, fileName }); - }); -} - -function buildFullModuleMap( - moduleRoot, - mainModuleMap, - externalModuleMap, - _alreadyVisited, - _prefix, -) { - if (!moduleRoot) return; - - const alreadyVisited = _alreadyVisited || {}, - prefix = _prefix; - - if (alreadyVisited && alreadyVisited.hasOwnProperty(moduleRoot)) return; - - alreadyVisited[moduleRoot] = true; - - listDirectories(moduleRoot, ({ fileName, fullFileName, symbolic, external }) => { - if (symbolic) - return buildFullModuleMap( - resolvePath(fullFileName, 'node_modules'), - mainModuleMap, - externalModuleMap, - alreadyVisited, - ); - - const moduleMap = external ? externalModuleMap : mainModuleMap, - moduleName = prefix ? PATH.join(prefix, fileName) : fileName; - - if (fileName.charAt(0) !== '@') moduleMap[moduleName] = fullFileName; - else - return buildFullModuleMap( - fullFileName, - mainModuleMap, - externalModuleMap, - alreadyVisited, - fileName, - ); - }); -} - -function buildModuleResolutionMap() { - const moduleMap = {}, - externalModuleMap = {}; - - buildFullModuleMap(baseModulePath, moduleMap, externalModuleMap); - - // Root project modules take precedence over external modules - return Object.assign({}, externalModuleMap, moduleMap); -} - -function findAlternateRoots(moduleRoot = baseModulePath, alternateRoots = [], _alreadyVisited) { - const alreadyVisited = _alreadyVisited || {}; - if (alreadyVisited && alreadyVisited.hasOwnProperty(moduleRoot)) return; - - alreadyVisited[moduleRoot] = true; - - listDirectories(moduleRoot, ({ fullFileName, fileName, external }) => { - if (fileName.charAt(0) !== '@') { - if (external) alternateRoots.push(fullFileName); - } else { - findAlternateRoots(fullFileName, alternateRoots, alreadyVisited); - } - }); - - return alternateRoots; -} - -function getPolyfillHelper() { - let getPolyfills; - - // Get default react-native polyfills - try { - getPolyfills = require('react-native/rn-get-polyfills'); - } catch (e) { - getPolyfills = () => []; - } - - // See if project has custom polyfills, if so, include the PATH to them - try { - const customPolyfills = require.resolve('./polyfills.js'); - getPolyfills = (function (originalGetPolyfills) { - return () => originalGetPolyfills().concat(customPolyfills); - })(getPolyfills); - } catch (e) { - //ignore - } - - return getPolyfills; -} const PATH = require('path'); -const FS = require('fs'), - exclusionList = require('metro-config/src/defaults/exclusionList'); +const blacklist = require('metro-config/src/defaults/blackList'); -const repoDir = PATH.dirname(PATH.dirname(__dirname)); +const extractExternalModules = require('stream-chat-react-native-core/metro-dev-helpers'); -const moduleExclusionList = [ - new RegExp(repoDir + '/examples/ExpoMessaging/.*'), - new RegExp(repoDir + '/examples/SampleApp/.*'), - new RegExp(repoDir + '/examples/TypeScriptMessaging/.*'), - new RegExp(repoDir + '/expo-package/.*'), - new RegExp(repoDir + '/native-package/node_modules/.*'), - new RegExp(repoDir + '/node_modules/.*'), - ], - baseModulePath = resolvePath(__dirname, 'node_modules'), - // watch alternate roots (outside of project root) - alternateRoots = findAlternateRoots(), - // build full module map for proper - // resolution of modules in external roots - extraNodeModules = buildModuleResolutionMap(); +const projectRoot = PATH.resolve(__dirname); -if (alternateRoots && alternateRoots.length) - console.log('Found alternate project roots: ', alternateRoots); +const { alternateRoots, extraNodeModules, moduleBlacklist } = extractExternalModules(projectRoot); module.exports = { resolver: { - blacklistRE: exclusionList(moduleExclusionList), + blacklistRE: blacklist(moduleBlacklist), extraNodeModules, useWatchman: false, }, - watchFolders: [PATH.resolve(__dirname)].concat(alternateRoots), - // transformer: { - // babelTransformerPath: require.resolve('./compiler/transformer'), - // }, - serializer: { - getPolyfills: getPolyfillHelper(), - }, + watchFolders: [projectRoot].concat(alternateRoots), }; diff --git a/examples/SampleApp/metro.config.js b/examples/SampleApp/metro.config.js index 2de8fae491..27eeee91d3 100644 --- a/examples/SampleApp/metro.config.js +++ b/examples/SampleApp/metro.config.js @@ -1,186 +1,19 @@ -/* eslint-disable */ -function resolvePath(...parts) { - const thisPath = PATH.resolve.apply(PATH, parts); - if (!FS.existsSync(thisPath)) return; - - return FS.realpathSync(thisPath); -} - -function isExternalModule(modulePath) { - return modulePath.substring(0, __dirname.length) !== __dirname; -} - -function listDirectories(rootPath, cb) { - FS.readdirSync(rootPath).forEach((fileName) => { - if (fileName.charAt(0) === '.') return; - - let fullFileName = PATH.join(rootPath, fileName), - stats = FS.lstatSync(fullFileName), - symbolic = false; - - if (stats.isSymbolicLink()) { - fullFileName = resolvePath(fullFileName); - if (!fullFileName) return; - - stats = FS.lstatSync(fullFileName); - - symbolic = true; - } - - if (!stats.isDirectory()) return; - - const external = isExternalModule(fullFileName); - cb({ rootPath, symbolic, external, fullFileName, fileName }); - }); -} - -function buildFullModuleMap( - moduleRoot, - mainModuleMap, - externalModuleMap, - _alreadyVisited, - _prefix, -) { - if (!moduleRoot) return; - - const alreadyVisited = _alreadyVisited || {}, - prefix = _prefix; - - if (alreadyVisited && alreadyVisited.hasOwnProperty(moduleRoot)) return; - - alreadyVisited[moduleRoot] = true; - - listDirectories(moduleRoot, ({ external, fileName, fullFileName, symbolic }) => { - if (symbolic) - return buildFullModuleMap( - resolvePath(fullFileName, 'node_modules'), - mainModuleMap, - externalModuleMap, - alreadyVisited, - ); - - const moduleMap = external ? externalModuleMap : mainModuleMap, - moduleName = prefix ? PATH.join(prefix, fileName) : fileName; - - if (fileName.charAt(0) !== '@') moduleMap[moduleName] = fullFileName; - else - return buildFullModuleMap( - fullFileName, - mainModuleMap, - externalModuleMap, - alreadyVisited, - fileName, - ); - }); -} - -function buildModuleResolutionMap() { - const moduleMap = {}, - externalModuleMap = {}; - - buildFullModuleMap(baseModulePath, moduleMap, externalModuleMap); - - // Root project modules take precedence over external modules - return Object.assign({}, externalModuleMap, moduleMap); -} - -function findAlternateRoots(moduleRoot = baseModulePath, alternateRoots = [], _alreadyVisited) { - const alreadyVisited = _alreadyVisited || {}; - if (alreadyVisited && alreadyVisited.hasOwnProperty(moduleRoot)) return; - - alreadyVisited[moduleRoot] = true; - - listDirectories(moduleRoot, ({ external, fileName, fullFileName }) => { - if (fileName.charAt(0) !== '@') { - if (external) alternateRoots.push(fullFileName); - } else { - findAlternateRoots(fullFileName, alternateRoots, alreadyVisited); - } - }); - - return alternateRoots; -} - -function getPolyfillHelper() { - let getPolyfills; - - // Get default react-native polyfills - try { - getPolyfills = require('react-native/rn-get-polyfills'); - } catch (e) { - getPolyfills = () => []; - } - - // See if project has custom polyfills, if so, include the PATH to them - try { - const customPolyfills = require.resolve('./polyfills.js'); - getPolyfills = (function (originalGetPolyfills) { - return () => originalGetPolyfills().concat(customPolyfills); - })(getPolyfills); - } catch (e) { - //ignore - } - - return getPolyfills; -} +/* eslint-env node */ const PATH = require('path'); -const FS = require('fs'), - exclusionList = require('metro-config/src/defaults/exclusionList'); +const blacklist = require('metro-config/src/defaults/blackList'); -const repoDir = PATH.dirname(PATH.dirname(__dirname)); +const extractExternalModules = require('stream-chat-react-native-core/metro-dev-helpers'); -const moduleExclusionList = [ - new RegExp(repoDir + '/examples/ExpoMessaging/.*'), - new RegExp(PATH.dirname(repoDir) + '/flat-list-mvcp/node_modules/.*'), - new RegExp(PATH.dirname(repoDir) + '/flat-list-mvcp/Example/.*'), - new RegExp(repoDir + '/examples/NativeMessaging/.*'), - new RegExp(repoDir + '/examples/TypeScriptMessaging/.*'), - // new RegExp(repoDir + '/native-example/(.*)'), - new RegExp(repoDir + '/expo-package/.*'), - new RegExp(repoDir + '/native-package/node_modules/.*'), - new RegExp(repoDir + '/node_modules/.*'), - ], - baseModulePath = resolvePath(__dirname, 'node_modules'), - // watch alternate roots (outside of project root) - alternateRoots = findAlternateRoots(), - // build full module map for proper - // resolution of modules in external roots - extraNodeModules = buildModuleResolutionMap(); +const projectRoot = PATH.resolve(__dirname); -if (alternateRoots && alternateRoots.length) - console.log('Found alternate project roots: ', alternateRoots); +const { alternateRoots, extraNodeModules, moduleBlacklist } = extractExternalModules(projectRoot); -console.log(moduleExclusionList); module.exports = { resolver: { - blacklistRE: exclusionList(moduleExclusionList), + blacklistRE: blacklist(moduleBlacklist), extraNodeModules, useWatchman: false, }, - watchFolders: [PATH.resolve(__dirname)].concat(alternateRoots), - // transformer: { - // babelTransformerPath: require.resolve('./compiler/transformer'), - // }, - serializer: { - getPolyfills: getPolyfillHelper(), - }, + watchFolders: [projectRoot].concat(alternateRoots), }; - -// /** -// * Metro configuration for React Native -// * https://github.com/facebook/react-native -// * -// * @format -// */ - -// module.exports = { -// transformer: { -// getTransformOptions: async () => ({ -// transform: { -// experimentalImportSupport: false, -// inlineRequires: false, -// }, -// }), -// }, -// }; diff --git a/examples/TypeScriptMessaging/metro.config.js b/examples/TypeScriptMessaging/metro.config.js index e1dc970758..27eeee91d3 100644 --- a/examples/TypeScriptMessaging/metro.config.js +++ b/examples/TypeScriptMessaging/metro.config.js @@ -1,182 +1,19 @@ /* eslint-env node */ -function resolvePath(...parts) { - const thisPath = PATH.resolve.apply(PATH, parts); - if (!FS.existsSync(thisPath)) return; - - return FS.realpathSync(thisPath); -} - -function isExternalModule(modulePath) { - return modulePath.substring(0, __dirname.length) !== __dirname; -} - -function listDirectories(rootPath, cb) { - FS.readdirSync(rootPath).forEach((fileName) => { - if (fileName.charAt(0) === '.') return; - - let fullFileName = PATH.join(rootPath, fileName), - stats = FS.lstatSync(fullFileName), - symbolic = false; - - if (stats.isSymbolicLink()) { - fullFileName = resolvePath(fullFileName); - if (!fullFileName) return; - - stats = FS.lstatSync(fullFileName); - - symbolic = true; - } - - if (!stats.isDirectory()) return; - - const external = isExternalModule(fullFileName); - cb({ rootPath, symbolic, external, fullFileName, fileName }); - }); -} - -function buildFullModuleMap( - moduleRoot, - mainModuleMap, - externalModuleMap, - _alreadyVisited, - _prefix, -) { - if (!moduleRoot) return; - - const alreadyVisited = _alreadyVisited || {}, - prefix = _prefix; - - if (alreadyVisited && alreadyVisited.hasOwnProperty(moduleRoot)) return; - - alreadyVisited[moduleRoot] = true; - - listDirectories(moduleRoot, ({ fileName, fullFileName, symbolic, external }) => { - if (symbolic) - return buildFullModuleMap( - resolvePath(fullFileName, 'node_modules'), - mainModuleMap, - externalModuleMap, - alreadyVisited, - ); - - const moduleMap = external ? externalModuleMap : mainModuleMap, - moduleName = prefix ? PATH.join(prefix, fileName) : fileName; - - if (fileName.charAt(0) !== '@') moduleMap[moduleName] = fullFileName; - else - return buildFullModuleMap( - fullFileName, - mainModuleMap, - externalModuleMap, - alreadyVisited, - fileName, - ); - }); -} - -function buildModuleResolutionMap() { - const moduleMap = {}, - externalModuleMap = {}; - - buildFullModuleMap(baseModulePath, moduleMap, externalModuleMap); - - // Root project modules take precedence over external modules - return Object.assign({}, externalModuleMap, moduleMap); -} - -function findAlternateRoots(moduleRoot = baseModulePath, alternateRoots = [], _alreadyVisited) { - const alreadyVisited = _alreadyVisited || {}; - if (alreadyVisited && alreadyVisited.hasOwnProperty(moduleRoot)) return; - - alreadyVisited[moduleRoot] = true; - - listDirectories(moduleRoot, ({ fullFileName, fileName, external }) => { - if (fileName.charAt(0) !== '@') { - if (external) alternateRoots.push(fullFileName); - } else { - findAlternateRoots(fullFileName, alternateRoots, alreadyVisited); - } - }); - - return alternateRoots; -} - -function getPolyfillHelper() { - let getPolyfills; - - // Get default react-native polyfills - try { - getPolyfills = require('react-native/rn-get-polyfills'); - } catch (e) { - getPolyfills = () => []; - } - - // See if project has custom polyfills, if so, include the PATH to them - try { - const customPolyfills = require.resolve('./polyfills.js'); - getPolyfills = (function (originalGetPolyfills) { - return () => originalGetPolyfills().concat(customPolyfills); - })(getPolyfills); - } catch (e) { - //ignore - } - - return getPolyfills; -} const PATH = require('path'); -const FS = require('fs'), - exclusionList = require('metro-config/src/defaults/exclusionList'); +const blacklist = require('metro-config/src/defaults/blackList'); -const repoDir = PATH.dirname(PATH.dirname(__dirname)); +const extractExternalModules = require('stream-chat-react-native-core/metro-dev-helpers'); -const moduleExclusionList = [ - new RegExp(repoDir + '/examples/ExpoMessaging/.*'), - new RegExp(repoDir + '/examples/NativeMessaging/.*'), - new RegExp(repoDir + '/examples/SampleApp/.*'), - new RegExp(repoDir + '/expo-package/.*'), - new RegExp(repoDir + '/native-package/node_modules/.*'), - new RegExp(repoDir + '/node_modules/.*'), - ], - baseModulePath = resolvePath(__dirname, 'node_modules'), - // watch alternate roots (outside of project root) - alternateRoots = findAlternateRoots(), - // build full module map for proper - // resolution of modules in external roots - extraNodeModules = buildModuleResolutionMap(); +const projectRoot = PATH.resolve(__dirname); -if (alternateRoots && alternateRoots.length) - console.log('Found alternate project roots: ', alternateRoots); +const { alternateRoots, extraNodeModules, moduleBlacklist } = extractExternalModules(projectRoot); module.exports = { resolver: { - blacklistRE: exclusionList(moduleExclusionList), + blacklistRE: blacklist(moduleBlacklist), extraNodeModules, useWatchman: false, }, - watchFolders: [PATH.resolve(__dirname)].concat(alternateRoots), - // transformer: { - // babelTransformerPath: require.resolve('./compiler/transformer'), - // }, - serializer: { - getPolyfills: getPolyfillHelper(), - }, + watchFolders: [projectRoot].concat(alternateRoots), }; - -// /** -// * Metro configuration for React Native -// * https://github.com/facebook/react-native -// * -// * @format -// */ - -// module.exports = { -// transformer: { -// getTransformOptions: async () => ({ -// transform: { -// experimentalImportSupport: false, -// inlineRequires: false, -// }, -// }), -// }, -// }; diff --git a/metro-dev-helpers.js b/metro-dev-helpers.js new file mode 100644 index 0000000000..669f476f6b --- /dev/null +++ b/metro-dev-helpers.js @@ -0,0 +1,144 @@ +/* eslint-env node */ +function resolvePath(...parts) { + const thisPath = PATH.resolve.apply(PATH, parts); + if (!FS.existsSync(thisPath)) { + return; + } + + return FS.realpathSync(thisPath); +} + +function isExternalModule(repoDir, modulePath) { + return modulePath.substring(0, repoDir.length) !== repoDir; +} + +function listDirectories(repoDir, rootPath, cb) { + FS.readdirSync(rootPath).forEach((fileName) => { + if (fileName.charAt(0) === '.') { + return; + } + + let fullFileName = PATH.join(rootPath, fileName), + stats = FS.lstatSync(fullFileName), + symbolic = false; + + if (stats.isSymbolicLink()) { + fullFileName = resolvePath(fullFileName); + if (!fullFileName) { + return; + } + + stats = FS.lstatSync(fullFileName); + + symbolic = true; + } + + if (!stats.isDirectory()) { + return; + } + + const external = isExternalModule(repoDir, fullFileName); + cb({ external, fileName, fullFileName, rootPath, symbolic }); + }); +} + +function buildFullModuleMap( + repoDir, + moduleRoot, + mainModuleMap, + externalModuleMap, + _alreadyVisited, + _prefix, +) { + if (!moduleRoot) { + return; + } + + const alreadyVisited = _alreadyVisited || {}, + prefix = _prefix; + + // eslint-disable-next-line no-prototype-builtins + if (alreadyVisited && alreadyVisited.hasOwnProperty(moduleRoot)) { + return; + } + + alreadyVisited[moduleRoot] = true; + + listDirectories(repoDir, moduleRoot, ({ external, fileName, fullFileName, symbolic }) => { + if (symbolic) { + return buildFullModuleMap( + repoDir, + resolvePath(fullFileName, 'node_modules'), + mainModuleMap, + externalModuleMap, + alreadyVisited, + ); + } + + const moduleMap = external ? externalModuleMap : mainModuleMap, + moduleName = prefix ? PATH.join(prefix, fileName) : fileName; + + if (fileName.charAt(0) !== '@') { + moduleMap[moduleName] = fullFileName; + } else { + return buildFullModuleMap( + repoDir, + fullFileName, + mainModuleMap, + externalModuleMap, + alreadyVisited, + fileName, + ); + } + }); +} + +function buildModuleResolutionMap(repoDir, moduleRoot) { + const moduleMap = {}, + externalModuleMap = {}; + + buildFullModuleMap(repoDir, moduleRoot, moduleMap, externalModuleMap); + + // Root project modules take precedence over external modules + return Object.assign({}, externalModuleMap, moduleMap); +} + +const PATH = require('path'); +const FS = require('fs'); + +const defaultBlackList = [ + '/examples/NativeMessaging', + '/examples/ExpoMessaging', + '/examples/TypeScriptMessaging', + '/examples/SampleApp', + '/native-package/node_modules', + '/expo-package', + '/node_modules', +]; + +module.exports = function extractExternalModules(repoDir) { + const pjson = require(PATH.join(repoDir, 'package.json')); + const sdkRoot = PATH.join( + repoDir, + pjson.dependencies['stream-chat-react-native-core'].replace('link:', ''), + ); + const sdkNativeRoot = PATH.join( + repoDir, + pjson.dependencies['stream-chat-react-native'].replace('link:', ''), + ); + + const alternateRoots = [sdkRoot, sdkNativeRoot]; + + if (alternateRoots && alternateRoots.length) + console.log('Found alternate project roots: ', alternateRoots); + + const moduleBlacklist = defaultBlackList + .filter((item) => repoDir.slice(-item.length) !== item) + .map((item) => new RegExp(sdkRoot + item + '/.*')); + // watch alternate roots (outside of project root) + // build full module map for proper + // resolution of modules in external roots + const extraNodeModules = buildModuleResolutionMap(repoDir, PATH.join(repoDir, 'node_modules')); + + return { alternateRoots, extraNodeModules, moduleBlacklist }; +}; From f475bd4f61ce41b3be5171bc62830feedde9a455 Mon Sep 17 00:00:00 2001 From: stream-ci-bot Date: Fri, 18 Jun 2021 13:33:49 -0300 Subject: [PATCH 2/5] use exclusionList on samples where metro-config is updated --- examples/NativeMessaging/metro.config.js | 2 +- examples/SampleApp/metro.config.js | 2 +- examples/TypeScriptMessaging/metro.config.js | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/examples/NativeMessaging/metro.config.js b/examples/NativeMessaging/metro.config.js index 27eeee91d3..bfeb2d7234 100644 --- a/examples/NativeMessaging/metro.config.js +++ b/examples/NativeMessaging/metro.config.js @@ -1,7 +1,7 @@ /* eslint-env node */ const PATH = require('path'); -const blacklist = require('metro-config/src/defaults/blackList'); +const blacklist = require('metro-config/src/defaults/exclusionList'); const extractExternalModules = require('stream-chat-react-native-core/metro-dev-helpers'); diff --git a/examples/SampleApp/metro.config.js b/examples/SampleApp/metro.config.js index 27eeee91d3..bfeb2d7234 100644 --- a/examples/SampleApp/metro.config.js +++ b/examples/SampleApp/metro.config.js @@ -1,7 +1,7 @@ /* eslint-env node */ const PATH = require('path'); -const blacklist = require('metro-config/src/defaults/blackList'); +const blacklist = require('metro-config/src/defaults/exclusionList'); const extractExternalModules = require('stream-chat-react-native-core/metro-dev-helpers'); diff --git a/examples/TypeScriptMessaging/metro.config.js b/examples/TypeScriptMessaging/metro.config.js index 27eeee91d3..bfeb2d7234 100644 --- a/examples/TypeScriptMessaging/metro.config.js +++ b/examples/TypeScriptMessaging/metro.config.js @@ -1,7 +1,7 @@ /* eslint-env node */ const PATH = require('path'); -const blacklist = require('metro-config/src/defaults/blackList'); +const blacklist = require('metro-config/src/defaults/exclusionList'); const extractExternalModules = require('stream-chat-react-native-core/metro-dev-helpers'); From 7aea3c9307011f570f22786ff72800b0768161c4 Mon Sep 17 00:00:00 2001 From: stream-ci-bot Date: Fri, 18 Jun 2021 18:07:31 -0300 Subject: [PATCH 3/5] better organization on metro-dev-helpers --- .gitignore | 2 + examples/ExpoMessaging/metro.config.js | 4 +- examples/NativeMessaging/metro.config.js | 4 +- examples/SampleApp/metro.config.js | 4 +- examples/TypeScriptMessaging/metro.config.js | 4 +- metro-dev-helpers/extract-linked-packages.js | 45 ++++++++++++++++++ .../lib/extract-extra-node-modules.js | 46 ++----------------- metro-dev-helpers/lib/find-linked-packages.js | 20 ++++++++ metro-dev-helpers/lib/index.js | 9 ++++ 9 files changed, 89 insertions(+), 49 deletions(-) create mode 100644 metro-dev-helpers/extract-linked-packages.js rename metro-dev-helpers.js => metro-dev-helpers/lib/extract-extra-node-modules.js (65%) create mode 100644 metro-dev-helpers/lib/find-linked-packages.js create mode 100644 metro-dev-helpers/lib/index.js diff --git a/.gitignore b/.gitignore index 31265353a0..9753ebfc40 100644 --- a/.gitignore +++ b/.gitignore @@ -10,6 +10,8 @@ yarn-error.log .DS_Store dist/ lib/ +# lib/ ignores metro-dev-helpers/lib so: +!metro-dev-helpers/lib .env* examples/SampleApp/ios/vendor/ vendor diff --git a/examples/ExpoMessaging/metro.config.js b/examples/ExpoMessaging/metro.config.js index 27eeee91d3..63b02a09fc 100644 --- a/examples/ExpoMessaging/metro.config.js +++ b/examples/ExpoMessaging/metro.config.js @@ -3,11 +3,11 @@ const PATH = require('path'); const blacklist = require('metro-config/src/defaults/blackList'); -const extractExternalModules = require('stream-chat-react-native-core/metro-dev-helpers'); +const extractLinkedPackages = require('stream-chat-react-native-core/metro-dev-helpers/extract-linked-packages'); const projectRoot = PATH.resolve(__dirname); -const { alternateRoots, extraNodeModules, moduleBlacklist } = extractExternalModules(projectRoot); +const { alternateRoots, extraNodeModules, moduleBlacklist } = extractLinkedPackages(projectRoot); module.exports = { resolver: { diff --git a/examples/NativeMessaging/metro.config.js b/examples/NativeMessaging/metro.config.js index bfeb2d7234..ca0a4a206f 100644 --- a/examples/NativeMessaging/metro.config.js +++ b/examples/NativeMessaging/metro.config.js @@ -3,11 +3,11 @@ const PATH = require('path'); const blacklist = require('metro-config/src/defaults/exclusionList'); -const extractExternalModules = require('stream-chat-react-native-core/metro-dev-helpers'); +const extractLinkedPackages = require('stream-chat-react-native-core/metro-dev-helpers/extract-linked-packages'); const projectRoot = PATH.resolve(__dirname); -const { alternateRoots, extraNodeModules, moduleBlacklist } = extractExternalModules(projectRoot); +const { alternateRoots, extraNodeModules, moduleBlacklist } = extractLinkedPackages(projectRoot); module.exports = { resolver: { diff --git a/examples/SampleApp/metro.config.js b/examples/SampleApp/metro.config.js index bfeb2d7234..ca0a4a206f 100644 --- a/examples/SampleApp/metro.config.js +++ b/examples/SampleApp/metro.config.js @@ -3,11 +3,11 @@ const PATH = require('path'); const blacklist = require('metro-config/src/defaults/exclusionList'); -const extractExternalModules = require('stream-chat-react-native-core/metro-dev-helpers'); +const extractLinkedPackages = require('stream-chat-react-native-core/metro-dev-helpers/extract-linked-packages'); const projectRoot = PATH.resolve(__dirname); -const { alternateRoots, extraNodeModules, moduleBlacklist } = extractExternalModules(projectRoot); +const { alternateRoots, extraNodeModules, moduleBlacklist } = extractLinkedPackages(projectRoot); module.exports = { resolver: { diff --git a/examples/TypeScriptMessaging/metro.config.js b/examples/TypeScriptMessaging/metro.config.js index bfeb2d7234..ca0a4a206f 100644 --- a/examples/TypeScriptMessaging/metro.config.js +++ b/examples/TypeScriptMessaging/metro.config.js @@ -3,11 +3,11 @@ const PATH = require('path'); const blacklist = require('metro-config/src/defaults/exclusionList'); -const extractExternalModules = require('stream-chat-react-native-core/metro-dev-helpers'); +const extractLinkedPackages = require('stream-chat-react-native-core/metro-dev-helpers/extract-linked-packages'); const projectRoot = PATH.resolve(__dirname); -const { alternateRoots, extraNodeModules, moduleBlacklist } = extractExternalModules(projectRoot); +const { alternateRoots, extraNodeModules, moduleBlacklist } = extractLinkedPackages(projectRoot); module.exports = { resolver: { diff --git a/metro-dev-helpers/extract-linked-packages.js b/metro-dev-helpers/extract-linked-packages.js new file mode 100644 index 0000000000..e459002326 --- /dev/null +++ b/metro-dev-helpers/extract-linked-packages.js @@ -0,0 +1,45 @@ +/* eslint-env node */ +const PATH = require('path'); + +const { extractExtraNodeModules, findLinkedPackages } = require('./lib'); + +const sdkBlacklistedPaths = [ + '/examples/NativeMessaging', + '/examples/ExpoMessaging', + '/examples/TypeScriptMessaging', + '/examples/SampleApp', + '/native-package/node_modules', + '/expo-package', + '/node_modules', +]; + +module.exports = function extractLinkedPackages(repoDir) { + // Map containing linked packages and their real paths + const linkedPackages = findLinkedPackages(repoDir); + + const sdkRootPackage = linkedPackages['stream-chat-react-native-core']; + const sdkNativePackage = linkedPackages['stream-chat-react-native']; + + if (!sdkRootPackage) { + throw new Error('stream-chat-react-native-core is not linked!'); + } + + if (!sdkRootPackage) { + throw new Error('stream-chat-react-native is not linked!'); + } + + const alternateRoots = [sdkRootPackage, sdkNativePackage]; + + // Blacklisting samples and other packages folders so theyre not taken in consideration + // The filter operation checks if this helper is being used inside of one of the blacklisted + // folders and if so, removes it from the blacklist. + const moduleBlacklist = sdkBlacklistedPaths + .filter((item) => repoDir.slice(-item.length) !== item) + .map((item) => new RegExp(sdkRootPackage + item + '/.*')); + + // Recursively extract node_modules for repoDir and linked packages + const repoNodeModules = PATH.join(repoDir, 'node_modules'); + const extraNodeModules = extractExtraNodeModules(repoDir, repoNodeModules); + + return { alternateRoots, extraNodeModules, moduleBlacklist }; +}; diff --git a/metro-dev-helpers.js b/metro-dev-helpers/lib/extract-extra-node-modules.js similarity index 65% rename from metro-dev-helpers.js rename to metro-dev-helpers/lib/extract-extra-node-modules.js index 669f476f6b..b97874c93b 100644 --- a/metro-dev-helpers.js +++ b/metro-dev-helpers/lib/extract-extra-node-modules.js @@ -1,4 +1,8 @@ /* eslint-env node */ + +const PATH = require('path'); +const FS = require('fs'); + function resolvePath(...parts) { const thisPath = PATH.resolve.apply(PATH, parts); if (!FS.existsSync(thisPath)) { @@ -93,7 +97,7 @@ function buildFullModuleMap( }); } -function buildModuleResolutionMap(repoDir, moduleRoot) { +module.exports = function extractExtraNodeModules(repoDir, moduleRoot) { const moduleMap = {}, externalModuleMap = {}; @@ -101,44 +105,4 @@ function buildModuleResolutionMap(repoDir, moduleRoot) { // Root project modules take precedence over external modules return Object.assign({}, externalModuleMap, moduleMap); -} - -const PATH = require('path'); -const FS = require('fs'); - -const defaultBlackList = [ - '/examples/NativeMessaging', - '/examples/ExpoMessaging', - '/examples/TypeScriptMessaging', - '/examples/SampleApp', - '/native-package/node_modules', - '/expo-package', - '/node_modules', -]; - -module.exports = function extractExternalModules(repoDir) { - const pjson = require(PATH.join(repoDir, 'package.json')); - const sdkRoot = PATH.join( - repoDir, - pjson.dependencies['stream-chat-react-native-core'].replace('link:', ''), - ); - const sdkNativeRoot = PATH.join( - repoDir, - pjson.dependencies['stream-chat-react-native'].replace('link:', ''), - ); - - const alternateRoots = [sdkRoot, sdkNativeRoot]; - - if (alternateRoots && alternateRoots.length) - console.log('Found alternate project roots: ', alternateRoots); - - const moduleBlacklist = defaultBlackList - .filter((item) => repoDir.slice(-item.length) !== item) - .map((item) => new RegExp(sdkRoot + item + '/.*')); - // watch alternate roots (outside of project root) - // build full module map for proper - // resolution of modules in external roots - const extraNodeModules = buildModuleResolutionMap(repoDir, PATH.join(repoDir, 'node_modules')); - - return { alternateRoots, extraNodeModules, moduleBlacklist }; }; diff --git a/metro-dev-helpers/lib/find-linked-packages.js b/metro-dev-helpers/lib/find-linked-packages.js new file mode 100644 index 0000000000..01d7627f3c --- /dev/null +++ b/metro-dev-helpers/lib/find-linked-packages.js @@ -0,0 +1,20 @@ +/* eslint-env node */ + +const PATH = require('path'); + +const LINK_STRING = 'link:'; + +module.exports = function findLinkedPackages(repoDir) { + const pjson = require(PATH.join(repoDir, 'package.json')); + const dependencies = {...pjson.dependencies, ...pjson.devDependencies}; + const linkedDependencies = Object.entries(dependencies).filter(([,value]) => { + return value.slice(0, LINK_STRING.length) === LINK_STRING; + }); + + const linkedDependenciesPathMap = linkedDependencies.reduce((acc, [nextKey, nextValue]) => { + acc[nextKey] = PATH.resolve(nextValue.replace(LINK_STRING, '')); + return acc; + }, {}) + + return linkedDependenciesPathMap; +}; diff --git a/metro-dev-helpers/lib/index.js b/metro-dev-helpers/lib/index.js new file mode 100644 index 0000000000..db2e29ceb9 --- /dev/null +++ b/metro-dev-helpers/lib/index.js @@ -0,0 +1,9 @@ +/* eslint-env node */ + +const extractExtraNodeModules = require('./extract-extra-node-modules'); +const findLinkedPackages = require('./find-linked-packages'); + +module.exports = { + extractExtraNodeModules, + findLinkedPackages, +}; From 0d8383ef516ee0ee8f6dc57817e4dff2ec46c0a6 Mon Sep 17 00:00:00 2001 From: stream-ci-bot Date: Mon, 21 Jun 2021 09:49:55 -0300 Subject: [PATCH 4/5] only exclude node_modules from expo-packages on new metro-dev-helpers --- metro-dev-helpers/extract-linked-packages.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/metro-dev-helpers/extract-linked-packages.js b/metro-dev-helpers/extract-linked-packages.js index e459002326..377e56322f 100644 --- a/metro-dev-helpers/extract-linked-packages.js +++ b/metro-dev-helpers/extract-linked-packages.js @@ -9,7 +9,7 @@ const sdkBlacklistedPaths = [ '/examples/TypeScriptMessaging', '/examples/SampleApp', '/native-package/node_modules', - '/expo-package', + '/expo-package/node_modules', '/node_modules', ]; From 5ac8a0f56fd5de962590b55f06b3290524a96157 Mon Sep 17 00:00:00 2001 From: stream-ci-bot Date: Mon, 21 Jun 2021 11:26:46 -0300 Subject: [PATCH 5/5] include expo package on alternate roots when available --- metro-dev-helpers/extract-linked-packages.js | 17 ++++++++++++++--- 1 file changed, 14 insertions(+), 3 deletions(-) diff --git a/metro-dev-helpers/extract-linked-packages.js b/metro-dev-helpers/extract-linked-packages.js index 377e56322f..859b9d676d 100644 --- a/metro-dev-helpers/extract-linked-packages.js +++ b/metro-dev-helpers/extract-linked-packages.js @@ -19,16 +19,27 @@ module.exports = function extractLinkedPackages(repoDir) { const sdkRootPackage = linkedPackages['stream-chat-react-native-core']; const sdkNativePackage = linkedPackages['stream-chat-react-native']; + const sdkExpoPackage = linkedPackages['stream-chat-expo']; if (!sdkRootPackage) { throw new Error('stream-chat-react-native-core is not linked!'); } - if (!sdkRootPackage) { - throw new Error('stream-chat-react-native is not linked!'); + const alternateRoots = [sdkRootPackage]; + + if (sdkNativePackage) { + alternateRoots.push(sdkNativePackage); } - const alternateRoots = [sdkRootPackage, sdkNativePackage]; + if (sdkExpoPackage) { + alternateRoots.push(sdkExpoPackage); + } + + if (!sdkNativePackage && !sdkExpoPackage) { + throw new Error( + 'stream-chat-react-native or stream-chat-expo is not linked! You need to link at least one.', + ); + } // Blacklisting samples and other packages folders so theyre not taken in consideration // The filter operation checks if this helper is being used inside of one of the blacklisted