0

我对 jscodeshift 很陌生。

目标: 我正在尝试构建一个执行以下操作的 codemod:

  1. 删除旧导入 -> 完成
  2. 添加新的导入 -> 完成
  3. 更新旧导入的所有引用 -> 不确定如何执行此操作

我正在为此任务使用转换导入库。

源代码:

import type { Query } from 'assets/core_api/types/query' // OLD IMPORT
// import type { IQuery } from '@demo/sdk // -> END GOAL: NEW IMPORT
import * as React from 'react'

export interface IProps {
  query: Query
}

const Demo = ({ query: Query }) => {
  return <div>Hello</div>
}

// component
export const DemoComponent: React.FC<IProps> = ({ query }) => {
  return <Demo query={query} />
}

代码:

// To Run: jscodeshift ./explore.tsx -t ./explore-mod.ts --extensions=ts,tsx --parser=tsx
const transformImports = require('transform-imports')

module.exports = function (fileInfo, api, options) {
  const j = api.jscodeshift
  const root = j(fileInfo.source)
  let transformedSource = fileInfo.source

  /* Add new Import */
  const addIQueryImport = () => {
    return j(root.find(j.Declaration).at(0).get()).insertBefore(
      "import type { IQuery } from '@demo/sdk'"
    )
  }

  // Check if new import exists.
  const importDeclaration = root.find(j.ImportDeclaration, {
    source: {
      type: 'StringLiteral',
      value: '@demo/sdk',
    },
  })

  const identifierCollection = importDeclaration.find(j.Identifier)
  const isIQueryExistingOnCode = identifierCollection.length

  // If there is no existing new import, add it.
  if (!isIQueryExistingOnCode) {
    addIQueryImport()
    transformedSource = root.toSource()
  }

  // Remove old assets
  return transformImports(transformedSource, importDefs => {
    importDefs.forEach(importDef => {
      if (importDef.source !== 'assets/core_api/types/query') {
        return
      }
      // If imported export is 'Query' then remove it.
      if (importDef.importedExport.name === 'Query') {
        importDef.remove()
      }
    })
  })
}

问题: 如何更新代码中对QuerytoiQuery的引用?

4

0 回答 0