Created
August 26, 2021 00:21
-
-
Save IkeyBenz/8915df0c7f08bde5a6b50a9e374fcfba to your computer and use it in GitHub Desktop.
make-relative-imports-absolute.ts
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
/** | |
* This script is intended to convert all relative imports in this project into | |
* absolute imports from the reference of the 'src' directory. | |
* | |
* Additional rules: | |
* - Files in src/core should not be effected | |
*/ | |
import fs from 'fs'; | |
import path from 'path'; | |
const getAllFilePaths = (dirname: string) => { | |
return fs.readdirSync(dirname).reduce((files, fileOrFolder) => { | |
const subPath = path.join(dirname, fileOrFolder); | |
if (fs.lstatSync(subPath).isDirectory()) { | |
files.push(...getAllFilePaths(subPath)); | |
} else { | |
files.push(subPath); | |
} | |
return files; | |
}, [] as string[]); | |
}; | |
const filterFilePaths = (filePaths: string[]): string[] => { | |
return filePaths | |
.filter((filePath) => filePath.endsWith('.ts') || filePath.endsWith('.tsx')) | |
.filter((filePath) => !filePath.includes('src/core')); | |
}; | |
const readFile = (filePath: string) => | |
new Promise<string>((resolve, reject) => { | |
fs.readFile(filePath, { encoding: 'utf-8' }, (err, data) => { | |
if (err) reject(err); | |
resolve(data); | |
}); | |
}); | |
const writeFile = (filePath: string, text: string) => | |
new Promise<void>((resolve, reject) => { | |
fs.writeFile(filePath, text, (err) => { | |
if (err) reject(err); | |
resolve(); | |
}); | |
}); | |
const getRelativeImportsInText = (text: string): string[] => { | |
return ( | |
text | |
// All cared about imports will be preceded by this string | |
.split("from '") | |
// Clean each part to remove the content after newlines | |
.map((part) => part.split('\n')[0]) | |
// Filter out the pieces of text that come before the word "from '" | |
.filter((part) => part.endsWith("';")) | |
// Filter for paths that are at least one folder deep | |
// .filter((part) => part.includes('../')) | |
.filter((part) => part.includes('/core/')) | |
// Finally remove the '; that is still attached to the end of each import | |
.map((part) => part.replace("';", '')) | |
); | |
}; | |
const resolveRelativeImport = ( | |
inFilePath: string, | |
relativeImport: string, | |
intendedRoot = 'hover-core', | |
) => { | |
const dir = inFilePath.slice(0, inFilePath.lastIndexOf('/')); | |
return path.join( | |
intendedRoot, | |
path.join(dir, relativeImport).split(intendedRoot + '/')[1], | |
); | |
}; | |
const makeRelativeImportsAbsolute = (filePath: string) => { | |
return readFile(filePath) | |
.then((fileText) => { | |
const pathsToReplace = getRelativeImportsInText(fileText); | |
return pathsToReplace.reduce((updatedFileText, relativeImport) => { | |
const absoluteImport = resolveRelativeImport(filePath, relativeImport); | |
console.log(relativeImport, ' => ', absoluteImport); | |
return updatedFileText.replace(relativeImport, absoluteImport); | |
}, fileText); | |
}) | |
.then((fileTextWithAbsoluteImports) => | |
writeFile(filePath, fileTextWithAbsoluteImports), | |
); | |
}; | |
const makeImportsAbsolute = async () => { | |
const srcPath = 'src'; | |
const filesToUpdate = filterFilePaths(getAllFilePaths(srcPath)); | |
console.log( | |
'\n\nabout to update', | |
filesToUpdate.length, | |
'files to have absolute imports', | |
); | |
Promise.all(filesToUpdate.map(makeRelativeImportsAbsolute)).then(() => { | |
console.log('done'); | |
}); | |
}; | |
makeImportsAbsolute(); |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment