fix-core-esm-extensions.mjs 2.0 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970
  1. import { existsSync } from 'node:fs'
  2. import { readdir, readFile, writeFile } from 'node:fs/promises'
  3. import { dirname, extname, join, resolve } from 'node:path'
  4. import { fileURLToPath } from 'node:url'
  5. const scriptDir = dirname(fileURLToPath(import.meta.url))
  6. const packageRoot = resolve(scriptDir, '..')
  7. const coreDistDir = join(packageRoot, 'dist')
  8. const relativeSpecifierPattern = /(\bfrom\s*['"]|\bimport\s*\(\s*['"])(\.{1,2}\/[^'"]+)(['"])/g
  9. const hasKnownExtension = specifier => extname(specifier) !== ''
  10. const resolveJsSpecifier = (fileDir, specifier) => {
  11. if (hasKnownExtension(specifier)) {
  12. return specifier
  13. }
  14. const candidate = resolve(fileDir, `${specifier}.js`)
  15. if (existsSync(candidate)) {
  16. return `${specifier}.js`
  17. }
  18. const indexCandidate = resolve(fileDir, specifier, 'index.js')
  19. return existsSync(indexCandidate) ? `${specifier}/index.js` : specifier
  20. }
  21. async function fixFile(filePath) {
  22. const source = await readFile(filePath, 'utf8')
  23. const fileDir = dirname(filePath)
  24. const fixed = source.replace(relativeSpecifierPattern, (_match, prefix, specifier, suffix) => {
  25. return `${prefix}${resolveJsSpecifier(fileDir, specifier)}${suffix}`
  26. })
  27. if (fixed !== source) {
  28. await writeFile(filePath, fixed, 'utf8')
  29. return true
  30. }
  31. return false
  32. }
  33. async function collectJsFiles(dir) {
  34. const entries = await readdir(dir, { withFileTypes: true })
  35. const files = []
  36. for (const entry of entries) {
  37. const path = join(dir, entry.name)
  38. if (entry.isDirectory()) {
  39. files.push(...await collectJsFiles(path))
  40. continue
  41. }
  42. if (entry.isFile() && extname(entry.name) === '.js') {
  43. files.push(path)
  44. }
  45. }
  46. return files
  47. }
  48. const files = await collectJsFiles(coreDistDir)
  49. let changedCount = 0
  50. for (const file of files) {
  51. const changed = await fixFile(file)
  52. if (changed) {
  53. changedCount += 1
  54. }
  55. }
  56. console.log(`[core-esm] Normalized relative import extensions in ${changedCount} file${changedCount === 1 ? '' : 's'}.`)