Created
August 2, 2019 12:19
-
-
Save ArminBu/e03c79291de585b0d732b1e2d198d8aa to your computer and use it in GitHub Desktop.
This script should replace all absolute alias imports with relative imports. It expects 1 argument for the root directory
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 args = process.argv; | |
const rootName = args[2]; | |
const rootPath = path.resolve(process.cwd(), rootName); | |
const alias = "@"; | |
if (!rootPath || !alias) return; | |
const { promisify } = require("util"); | |
const fs = require("fs"); | |
const readFileAsync = promisify(fs.readFile); | |
const readDirAsync = promisify(fs.readdir); | |
const writeFileAsync = promisify(fs.writeFile); | |
const statsAsync = promisify(fs.stat); | |
function testForAliasImport(file) { | |
if (!file.content) return file; | |
const regex = /"@(\/\w+[\w\/.]+)"/gi; | |
let match, | |
search = file.content; | |
while ((match = regex.exec(search))) { | |
const matchString = match[0]; | |
console.log(`found alias import ${matchString} in ${file.filepath}`); | |
file.content = file.content.replace( | |
matchString, | |
aliasToRelative(file, matchString) | |
); | |
search = search.substring(match.index + matchString.length); | |
} | |
return file; | |
} | |
function aliasToRelative(file, importString) { | |
let importPath = importString | |
.replace(alias, "") | |
.split('"') | |
.join(""); | |
const hasExtension = !!path.parse(importString).ext; | |
if (!hasExtension) { | |
importPath += ".ext"; | |
} | |
const filepath = file.filepath | |
.replace(rootPath, "") | |
.split("\\") | |
.join("/"); | |
let relativeImport = path.posix.relative(path.dirname(filepath), importPath); | |
if (!hasExtension) { | |
relativeImport = relativeImport.replace(".ext", ""); | |
} | |
if (!relativeImport.startsWith("../")) { | |
relativeImport = "./" + relativeImport; | |
} | |
relativeImport = `"${relativeImport}"`; | |
console.log(`replaced alias import ${importString} with ${relativeImport}`); | |
return relativeImport; | |
} | |
async function writeFile(file) { | |
if (!file || !file.content || !file.filepath) return file; | |
try { | |
console.log(`writing new contents to file ${file.filepath}...`); | |
await writeFileAsync(file.filepath, file.content); | |
} catch (e) { | |
console.error(e); | |
} | |
} | |
async function prepareFile(filepath) { | |
const stat = await statsAsync(filepath); | |
return { stat, filepath }; | |
} | |
async function processFile(file) { | |
if (file.stat.isFile()) { | |
console.log(`reading file ${file.filepath}...`); | |
file.content = await readFileAsync(file.filepath); | |
file.content = file.content.toString(); | |
} else if (file.stat.isDirectory()) { | |
console.log(`traversing dir ${file.filepath}...`); | |
await traverseDir(file.filepath); | |
} | |
return file; | |
} | |
async function traverseDir(dirPath) { | |
try { | |
const filenames = await readDirAsync(dirPath); | |
const filepaths = filenames.map(name => path.join(dirPath, name)); | |
const fileStats = await Promise.all(filepaths.map(prepareFile)); | |
const files = await Promise.all(fileStats.map(processFile)); | |
await Promise.all(files.map(testForAliasImport).map(writeFile)); | |
} catch (e) { | |
console.error(e); | |
} | |
} | |
traverseDir(rootPath) | |
.then(() => console.log("done")) | |
.catch(console.error); | |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
no. using regex to parse sources is just wrong
eslint is the best tool for javascript codemods, so...
https://github.com/johvin/eslint-import-resolver-alias - resolve alias imports, ...
https://github.com/dword-design/eslint-plugin-import-alias - enforce the use of import aliases
https://github.com/joshuajaco/eslint-plugin-workspaces/blob/main/lib/rules/no-absolute-imports.js - absolute to relative imports
https://github.com/joshuajaco/eslint-plugin-workspaces/blob/main/lib/rules/no-relative-imports.js - relative to absolute imports
https://github.com/qdanik/eslint-plugin-path/blob/main/lib/rules/no-relative-imports.js - relative to absolute imports