69 lines
1.9 KiB
TypeScript
69 lines
1.9 KiB
TypeScript
|
import { existsSync, readFileSync, statSync, writeFileSync } from 'fs'
|
||
|
import glob from 'glob'
|
||
|
import path from 'path'
|
||
|
import { parse, print, visit } from 'recast'
|
||
|
|
||
|
const extensions = ['.js', '.mjs', '.cjs']
|
||
|
function resolveRelativePath(importingFile: string, relativePath: string) {
|
||
|
if (!relativePath.startsWith('.')) {
|
||
|
return relativePath
|
||
|
}
|
||
|
|
||
|
const containingDir = path.dirname(importingFile)
|
||
|
|
||
|
if (
|
||
|
existsSync(path.join(containingDir, relativePath)) &&
|
||
|
!statSync(path.join(containingDir, relativePath)).isDirectory()
|
||
|
) {
|
||
|
// if the file already exists, e.g. .css files, just use it
|
||
|
return relativePath
|
||
|
}
|
||
|
|
||
|
// strip the file extension if applicable
|
||
|
relativePath.replace(/\.(m|c)?js$/, '')
|
||
|
|
||
|
for (const extension of extensions) {
|
||
|
if (relativePath.endsWith(extension)) {
|
||
|
return relativePath
|
||
|
} else {
|
||
|
let candidate = `${relativePath}${extension}`
|
||
|
if (existsSync(path.join(containingDir, candidate))) {
|
||
|
return candidate
|
||
|
}
|
||
|
|
||
|
candidate = `${relativePath}/index${extension}`
|
||
|
|
||
|
if (existsSync(path.join(containingDir, candidate))) {
|
||
|
return candidate
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
|
||
|
throw new Error(`Could not resolve relative path ${relativePath} from ${importingFile}`)
|
||
|
}
|
||
|
|
||
|
export function addJsExtensions(distDir: string) {
|
||
|
for (const file of glob.sync(path.join(distDir, '**/*.{mjs,cjs,js}'))) {
|
||
|
const code = parse(readFileSync(file, 'utf8'), { parser: require('recast/parsers/typescript') })
|
||
|
|
||
|
visit(code, {
|
||
|
visitImportDeclaration(path) {
|
||
|
path.value.source.value = resolveRelativePath(file, path.value.source.value)
|
||
|
return false
|
||
|
},
|
||
|
visitExportAllDeclaration(path) {
|
||
|
path.value.source.value = resolveRelativePath(file, path.value.source.value)
|
||
|
return false
|
||
|
},
|
||
|
visitExportNamedDeclaration(path) {
|
||
|
if (path.value.source) {
|
||
|
path.value.source.value = resolveRelativePath(file, path.value.source.value)
|
||
|
}
|
||
|
return false
|
||
|
},
|
||
|
})
|
||
|
|
||
|
writeFileSync(file, print(code).code)
|
||
|
}
|
||
|
}
|