fix-core-esm-extensions.mjs 2.0 KB

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