Last active
October 1, 2019 16:06
-
-
Save mbret/edbfec5df3adac6dbf980b43be08f556 to your computer and use it in GitHub Desktop.
Symlink for React Native 0.59 (symlink + scoped package + hast name collision)
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
/** | |
* Metro configuration for React Native | |
* https://github.com/facebook/react-native | |
* | |
* @format | |
*/ | |
const { | |
getSymLinkedModules, | |
getBlacklistedModulesForAlternateRoot, | |
getExtraModulesForAlternateRoot, | |
escapeRegExp | |
} = require("./metroConfigUtils"); | |
const fs = require("fs"); | |
// Get blacklist factory | |
const blacklist = require("metro-config/src/defaults/blacklist"); | |
let moduleBlacklist = []; | |
// alternate roots (outside of project root) | |
const alternateRoots = getSymLinkedModules(); | |
// resolve external package dependencies by forcing them to look into path.join(__dirname, "node_modules") | |
const extraNodeModules = alternateRoots.reduce((obj, item) => { | |
Object.assign(obj, getExtraModulesForAlternateRoot(item)); | |
return obj; | |
}, {}); | |
alternateRoots.forEach(root => { | |
const modules = getBlacklistedModulesForAlternateRoot(root); | |
moduleBlacklist = moduleBlacklist.concat( | |
Object.keys(modules).map(key => RegExp(`${escapeRegExp(`${modules[key]}\\`)}.*`)) | |
); | |
}); | |
console.log(alternateRoots) | |
module.exports = { | |
watchFolders: alternateRoots, | |
resolver: { | |
extraNodeModules, | |
blacklistRE: blacklist(moduleBlacklist) | |
}, | |
transformer: { | |
getTransformOptions: async () => ({ | |
transform: { | |
experimentalImportSupport: false, | |
inlineRequires: false, | |
}, | |
}), | |
}, | |
}; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
const path = require("path"); | |
const fs = require("fs"); | |
const baseModulePath = path.resolve(__dirname, "node_modules"); | |
exports.getSymLinkedModules = function () { | |
function checkModule(fileName, alternateRoots, modulePath) { | |
try { | |
const fullFileName = path.join(modulePath, fileName); | |
const stats = fs.lstatSync(fullFileName); | |
if (stats.isSymbolicLink()) { | |
const realPath = fs.realpathSync(fullFileName); | |
if (realPath.substring(0, (__dirname).length) !== __dirname) alternateRoots.push(realPath); | |
} | |
} catch (e) { | |
// void | |
} | |
} | |
function checkAllModules(modulePath, alternateRoots) { | |
const stats = fs.lstatSync(modulePath); | |
if (!stats.isDirectory()) return alternateRoots; | |
fs.readdirSync(modulePath).forEach((fileName) => { | |
if (fileName.charAt(0) === ".") return; | |
if (fileName.charAt(0) !== "@") checkModule(fileName, alternateRoots, modulePath); | |
else checkAllModules(path.join(modulePath, fileName), alternateRoots); | |
}); | |
return alternateRoots; | |
} | |
return checkAllModules(baseModulePath, []); | |
} | |
exports.getExtraModulesForAlternateRoot = function (fullPath) { | |
const packagePath = path.join(fullPath, "package.json"); | |
const packageJSON = require(packagePath); | |
const alternateModules = [].concat( | |
Object.keys(packageJSON.dependencies || {}), | |
Object.keys(packageJSON.devDependencies || {}), | |
Object.keys(packageJSON.peerDependencies || {}) | |
); | |
const extraModules = {}; | |
for (let i = 0, il = alternateModules.length; i < il; i++) { | |
const moduleName = alternateModules[i]; | |
extraModules[moduleName] = path.join(baseModulePath, moduleName); | |
} | |
return extraModules; | |
} | |
exports.getBlacklistedModulesForAlternateRoot = function (fullPath) { | |
const packagePath = path.join(fullPath, "package.json"); | |
const packageJSON = require(packagePath); | |
const alternateModules = [].concat( | |
Object.keys(packageJSON.peerDependencies || {}) | |
); | |
const extraModules = {}; | |
for (let i = 0, il = alternateModules.length; i < il; i++) { | |
const moduleName = alternateModules[i]; | |
extraModules[moduleName] = path.join(fullPath, "node_modules", moduleName); | |
} | |
return extraModules; | |
} | |
exports.escapeRegExp = function (string) { | |
return string.replace(/[.*+?^${}()|[\]\\]/g, '\\$&'); // $& means the whole matched string | |
} |
This made my day. THANK YOU!!!
🔥 !! Thanks @mbret
:\ I get
Module `@babel/runtime/regenerator` does not exist in the Haste module map or in these directories:
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
@mbret
Hey i'm trying your gist on my project, it seems i'm not using it the right way.
i have this:
~/git/react-native-myModule/
~/git/myApp/
I've tried:
Then applied your metro.config on
~/git/myApp/ folder
Now metro bundler auto detects the symlinked react-native-myModule just fine, but i'm getting naming collisions like this
I'm missing something?