Codegen provides tools to help you migrate away from default exports to named exports in your TypeScript codebase. This tutorial builds on the concepts covered in exports to show you how to automate this conversion process.

Overview

Default exports can make code harder to maintain and refactor. Converting them to named exports provides several benefits:

  • Better IDE support for imports and refactoring
  • More explicit and consistent import statements
  • Easier to track symbol usage across the codebase

Converting Default Exports

Here’s how to convert default exports to named exports:

for file in codebase.files:
    target_file = file.filepath
    if not target_file:
        print(f"⚠️ Target file not found: {filepath}")
        continue

    # Get corresponding non-shared file
    non_shared_path = target_file.filepath.replace('/shared/', '/')
    if not codebase.has_file(non_shared_path):
        print(f"⚠️ No matching non-shared file for: {filepath}")
        continue

    non_shared_file = codebase.get_file(non_shared_path)
    print(f"πŸ“„ Processing {target_file.filepath}")

    # Process individual exports
    for export in target_file.exports:
        # Handle default exports
        if export.is_reexport() and export.is_default_export():
            print(f"  πŸ”„ Converting default export '{export.name}'")
            default_export = next((e for e in non_shared_file.default_exports), None)
            if default_export:
                default_export.make_non_default()

    print(f"✨ Fixed exports in {target_file.filepath}")

Understanding the Process

Let’s break down how this works:

Best Practices

  1. Check for Missing Files: Always verify files exist before processing:
if not target_file:
    print(f"⚠️ Target file not found: {filepath}")
    continue
  1. Log Progress: Add logging to track the conversion process:
print(f"πŸ“„ Processing {target_file.filepath}")
print(f"  πŸ”„ Converting default export '{export.name}'")
  1. Handle Missing Exports: Check that default exports exist before converting:
default_export = next((e for e in non_shared_file.default_exports), None)
if default_export:
    default_export.make_non_default()

Next Steps

After converting default exports:

  1. Run your test suite to verify everything still works
  2. Update any import statements that were using default imports
  3. Review the changes to ensure all exports were converted correctly
  4. Consider adding ESLint rules to prevent new default exports

Remember to test thoroughly after converting default exports, as this change affects how other files import the converted modules.

Complete Codemod

Here’s the complete codemod that you can copy and use directly:


for file in codebase.files:
    target_file = file.filepath
    if not target_file:
        print(f"⚠️ Target file not found: {filepath}")
        continue

    # Get corresponding non-shared file
    non_shared_path = target_file.filepath.replace('/shared/', '/')
    if not codebase.has_file(non_shared_path):
        print(f"⚠️ No matching non-shared file for: {filepath}")
        continue

    non_shared_file = codebase.get_file(non_shared_path)
    print(f"πŸ“„ Processing {target_file.filepath}")

    # Process individual exports
    for export in target_file.exports:
        # Handle default exports
        if export.is_reexport() and export.is_default_export():
            print(f"  πŸ”„ Converting default export '{export.name}'")
            default_export = next((e for e in non_shared_file.default_exports), None)
            if default_export:
                default_export.make_non_default()

    print(f"✨ Fixed exports in {target_file.filepath}")

Was this page helpful?