Skip to content

utility function to resolve React.lazy imports #3

@scarf005

Description

@scarf005

Example implementation

const resolveDynamicImportPath = (path: string) =>
  resolve(import.meta.dirname!) + path.replace('@src', '/src') + '.tsx'

const projectCache = new Project({
  useInMemoryFileSystem: true,
})

export const getRouteMappings =
  (resolveDynamicImport: (path: string) => string) =>
  (sourceFile: SourceFile): Record<string, string> => {
    const nodes = query(
      sourceFile.getText(),
      'Identifier[name=routes] ~ ObjectLiteralExpression > PropertyAssignment'
    ).flatMap((x) => {
      const container = query(x, 'Identifier[name=component] ~ Identifier')[0]
      if (container === undefined) return []

      const topDecl = sourceFile.getVariableDeclarationOrThrow(container?.getText())

      // HACK: assumes all components are of format React.lazy(() => import('<path>/componentName'))
      const path = topDecl.getFirstDescendantByKindOrThrow(SyntaxKind.StringLiteral)
      const resolvedPath = resolveDynamicImport(path.getLiteralText())
      const resolvedText = Deno.readTextFileSync(resolvedPath)

      const srcfile = projectCache.createSourceFile(resolvedPath, resolvedText)
      // https://ts-morph.com/details/exports#getting-exported-declarations
      const uri = encodeVSCodeURI(srcfile.getExportedDeclarations().get('default')![0])
      projectCache.removeSourceFile(srcfile)

      const name = query(x, 'PropertyAccessExpression Identifier[name=Route] ~ Identifier')[0]?.getText()

      return [[name, uri]] as const
    })

    return Object.fromEntries(nodes)
  }

Metadata

Metadata

Assignees

Labels

featNew feature or request

Type

No type

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions