Проблемы со ссылками на переменные обновления для jsCodemod
Я новичок в jscodeshift, и мне нужна помощь.
Цель: я пытаюсь создать код-мод, который выполняет следующие действия:
- Удалить старый импорт -> ГОТОВО
- Добавить новый импорт -> ГОТОВО
- Обновите все ссылки старого импорта -> НУЖНА ПОМОЩЬ :(
Я использую библиотеку импорта преобразования, чтобы помочь мне.
Исходный код:
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()
}
})
})
}
Вопрос: как обновить ссылки на
Query
к
iQuery
в коде?
1 ответ
Вы можете использовать мою библиотеку Putout для этой цели. Вот пример включения :
export const include = () => [
'import type {Query} from "assets/core_api/types/query"'
]
export const fix = (path) => {
path.scope.rename('Query', 'IQuery');
path.node.source.value = '@demo/sdk';
}
Что он делает:
- ✅ включить узел с типом;
- ✅ переименовать
Query
кIQuery
с помощью API-интерфейса Babel ; - ✅ обновить значение
source
, то естьStringLiteral
;