-
Notifications
You must be signed in to change notification settings - Fork 1.6k
/
Copy pathupdate-imports.mjs
131 lines (111 loc) · 3.97 KB
/
update-imports.mjs
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
#!/usr/bin/env node
import fs from 'fs';
import path from 'path';
import process from 'process';
// Adjust the base directory to match your project layout:
const SRC_DIR = path.join(process.cwd(), 'test');
/**
* Recursively gather all .mjs files in the given directory
*/
function getAllMjsFiles(dir) {
let results = [];
const list = fs.readdirSync(dir, { withFileTypes: true });
for (const dirent of list) {
const fullPath = path.join(dir, dirent.name);
if (dirent.isDirectory()) {
// Recurse into subdirectories
results = results.concat(getAllMjsFiles(fullPath));
} else if (dirent.isFile() && fullPath.endsWith('.mjs')) {
results.push(fullPath);
}
}
return results;
}
/**
* Given an import path like '../../util', figure out if we should rewrite
* to '../../util.mjs' or '../../util/index.mjs', based on what is present in the file system.
*/
function resolveImport(rawImportPath, currentFileDir) {
// We only care about relative imports
if (!rawImportPath.startsWith('.')) {
// If it's not relative, leave it alone (e.g. 'react' or 'lodash')
return rawImportPath;
}
// The path on disk relative to the current file
const absoluteImportPath = path.resolve(currentFileDir, rawImportPath);
// 1. Check if `absoluteImportPath.mjs` exists
const candidateMjsFile = `${absoluteImportPath}.mjs`;
if (fs.existsSync(candidateMjsFile)) {
// Convert back to a relative path from the current file
return pathRelativeWinSafe(currentFileDir, candidateMjsFile);
}
// 2. Check if `absoluteImportPath/index.mjs` exists
const candidateIndexFile = path.join(absoluteImportPath, 'index.mjs');
if (fs.existsSync(candidateIndexFile)) {
return pathRelativeWinSafe(currentFileDir, candidateIndexFile);
}
// If neither .mjs nor index.mjs exist, leave it unchanged (or optionally throw an error)
return rawImportPath;
}
/**
* Convert absolute path back to a relative path (with forward slashes on all platforms).
* Because Node on Windows returns backslashes, which ESM imports won't like.
*/
function pathRelativeWinSafe(from, to) {
let relPath = path.relative(from, to);
// Replace backslashes with forward slashes
relPath = relPath.replace(/\\/g, '/');
// Ensure it starts with '.' or '..' if it isn’t already
if (!relPath.startsWith('.')) {
relPath = `./${relPath}`;
}
return relPath;
}
/**
* Perform the in-place rewrites for import statements in a single file.
*/
function rewriteImportsInFile(filePath) {
const fileDir = path.dirname(filePath);
let src = fs.readFileSync(filePath, 'utf8');
// Simple pattern capturing import statements of the form:
// import ... from '...';
// This will NOT catch every possible ESM shape (e.g., multiline). Adapt as needed.
const importRegex = /(\bimport\s+(?:[\s\S]+?)\s+from\s+['"])([^'"]+)(['"];)/g;
let changed = false;
src = src.replace(importRegex, (match, before, importPath, after) => {
const newImportPath = resolveImport(importPath, fileDir);
if (newImportPath !== importPath) {
changed = true;
return `${before}${newImportPath}${after}`;
}
return match;
});
// Optionally, handle require() if needed:
// const requireRegex = /(\brequire\s*\(\s*['"])([^'"]+)(['"]\s*\))/g;
// src = src.replace(requireRegex, (match, before, importPath, after) => {
// const newImportPath = resolveImport(importPath, fileDir);
// if (newImportPath !== importPath) {
// changed = true;
// return `${before}${newImportPath}${after}`;
// }
// return match;
// });
if (changed) {
fs.writeFileSync(filePath, src, 'utf8');
console.log(`Updated imports in: ${filePath}`);
}
}
/**
* Main routine:
* 1. Collect all .mjs files in src/
* 2. Rewrite their import statements
*/
function main() {
const allMjsFiles = getAllMjsFiles(SRC_DIR);
console.log(`Found ${allMjsFiles.length} .mjs files in ${SRC_DIR}.`);
for (const filePath of allMjsFiles) {
rewriteImportsInFile(filePath);
}
console.log('Done.');
}
main();