|
| 1 | +#!/usr/bin/env node |
| 2 | + |
| 3 | +/* |
| 4 | + * Using libraries within examples and linking them within packages.json like: |
| 5 | + * "react-native-library-name": "file:../" |
| 6 | + * will cause problems with the metro bundler if the example will run via |
| 7 | + * `react-native run-[ios|android]`. This will result in an error as the metro |
| 8 | + * bundler will find multiple versions for the same module while resolving it. |
| 9 | + * The reason for that is that if the library is installed it also copies in the |
| 10 | + * example folder itself as well as the node_modules folder of the library |
| 11 | + * although their are defined in .npmignore and should be ignored in theory. |
| 12 | + * |
| 13 | + * This postinstall script removes the node_modules folder as well as all |
| 14 | + * entries from the libraries .npmignore file within the examples node_modules |
| 15 | + * folder after the library was installed. This should resolve the metro |
| 16 | + * bundler issue mentioned above. |
| 17 | + * |
| 18 | + * It is expected this scripts lives in the libraries root folder within a |
| 19 | + * scripts folder. As first parameter the relative path to the libraries |
| 20 | + * folder within the example's node_modules folder may be provided. |
| 21 | + * This script will determine the path from this project's package.json file |
| 22 | + * if no such relative path is provided. |
| 23 | + * An example's package.json entry could look like: |
| 24 | + * "postinstall": "node ../scripts/examples_postinstall.js node_modules/react-native-library-name/" |
| 25 | + */ |
| 26 | + |
| 27 | +'use strict' |
| 28 | + |
| 29 | +const fs = require('fs') |
| 30 | +const path = require('path') |
| 31 | + |
| 32 | +/// Delete all files and directories for the given path |
| 33 | +const removeFileDirectoryRecursively = fileDirPath => { |
| 34 | + // Remove file |
| 35 | + if (!fs.lstatSync(fileDirPath).isDirectory()) { |
| 36 | + fs.unlinkSync(fileDirPath) |
| 37 | + return |
| 38 | + } |
| 39 | + |
| 40 | + // Go down the directory an remove each file / directory recursively |
| 41 | + fs.readdirSync(fileDirPath).forEach(entry => { |
| 42 | + const entryPath = path.join(fileDirPath, entry) |
| 43 | + removeFileDirectoryRecursively(entryPath) |
| 44 | + }) |
| 45 | + fs.rmdirSync(fileDirPath) |
| 46 | +} |
| 47 | + |
| 48 | +const removeFileDir = fileDirPath => { |
| 49 | + try { |
| 50 | + removeFileDirectoryRecursively(fileDirPath) |
| 51 | + console.log(`Deleted: ${fileDirPath}`) |
| 52 | + } catch (err) { |
| 53 | + console.log(`Error deleting ${fileDirPath}: ${err.message}`) |
| 54 | + } |
| 55 | +} |
| 56 | + |
| 57 | +/// Remove example/node_modules/react-native-library-name/node_modules directory |
| 58 | +const removeLibraryNodeModulesPath = nodeModulesPath => { |
| 59 | + if (!fs.existsSync(nodeModulesPath)) { |
| 60 | + console.log( |
| 61 | + `No node_modules found at ${nodeModulesPath}. Skipping delete.` |
| 62 | + ) |
| 63 | + return |
| 64 | + } |
| 65 | + |
| 66 | + removeFileDir(nodeModulesPath) |
| 67 | +} |
| 68 | + |
| 69 | +/// Remove all entries from the .npmignore within example/node_modules/react-native-library-name/ |
| 70 | +const removeLibraryNpmIgnorePaths = (npmIgnorePath, libraryNodeModulesPath) => { |
| 71 | + if (!fs.existsSync(npmIgnorePath)) { |
| 72 | + console.log( |
| 73 | + `No .npmignore found at ${npmIgnorePath}. Skipping deleting content.` |
| 74 | + ) |
| 75 | + return |
| 76 | + } |
| 77 | + |
| 78 | + fs.readFileSync(npmIgnorePath, 'utf8') |
| 79 | + .split(/\r?\n/) |
| 80 | + .forEach(entry => { |
| 81 | + if (entry.length === 0) { |
| 82 | + return |
| 83 | + } |
| 84 | + |
| 85 | + const npmIgnoreLibraryNodeModulesEntryPath = path.resolve( |
| 86 | + libraryNodeModulesPath, |
| 87 | + entry |
| 88 | + ) |
| 89 | + if (!fs.existsSync(npmIgnoreLibraryNodeModulesEntryPath)) { |
| 90 | + return |
| 91 | + } |
| 92 | + |
| 93 | + removeFileDir(npmIgnoreLibraryNodeModulesEntryPath) |
| 94 | + }) |
| 95 | +}; |
| 96 | + |
| 97 | +// Main start sweeping process |
| 98 | +(() => { |
| 99 | + // Read out dir of example project |
| 100 | + const cwd = process.cwd() |
| 101 | + |
| 102 | + console.log(`Starting postinstall cleanup for ${cwd}`) |
| 103 | + |
| 104 | + // Resolve the React Native library's path within the example's node_modules directory |
| 105 | + const libraryNodeModulesPath = |
| 106 | + process.argv.length > 2 |
| 107 | + ? path.resolve(cwd, process.argv[2]) |
| 108 | + : path.resolve(cwd, 'node_modules', require('../package.json').name) |
| 109 | + |
| 110 | + console.log('Removing nested node_modules directory...') |
| 111 | + const nodeModulesPath = path.resolve(libraryNodeModulesPath, 'node_modules') |
| 112 | + removeLibraryNodeModulesPath(nodeModulesPath) |
| 113 | + |
| 114 | + console.log('Processing .npmignore entries...') |
| 115 | + const npmIgnorePath = path.resolve(__dirname, '../.npmignore') |
| 116 | + removeLibraryNpmIgnorePaths(npmIgnorePath, libraryNodeModulesPath) |
| 117 | +})() |
0 commit comments