Currently, the is-npm codemod assumes that developers name the imported members isNpm, isYarn and isYarnOrNpm. However, there are two ways in which developers could alter the imports that can't be handled by the codemod:
// ESM
import { isNpm as banana, isYarn as pear, isNpmOrYarn as strawberry } from 'is-npm';
import * as banana from 'is-npm';
// CJS
const { isNpm: banana, isYarn: pear, isNpmOrYarn: strawberry } = require('is-npm');
const banana = require('is-npm');
Moreover, by relying on hardcoded names, we also could potentially make unsafe modifications to developer code (they could have an isNpm variable themselves which is different from the imported one and has a different meaning)
This PR makes the codemod detect the imported names dynamically so that it supports the styles above. It also adds test cases to handle the new styles.
The PR introduces the getImportIdentifierMap helper which creates a map like this:
// import { isNpm as banana, isYarn as pear, isNpmOrYarn as strawberry } from 'is-npm';
const map = {
isNpm: "banana",
isYarn: "pear",
isNpmOrYarn: "strawberry"
}
// import * as banana from 'is-npm';
const map = {
[Symbol(NAMEPSACE_IMPORT)]: "banana"
}
This helper should be useful for cases where a module exports multiple names and const { identifier } = removeImport() is not sufficient.
There is some duplication in the codemod code, as the "individual name import" and "namespace import" cases need to be handled separately. However, since I suspect that this issue will also apply to other codemods, I believe the duplication is fine for now — we can figure out better abstractions as we continue improving the mods.
Currently, the
is-npm
codemod assumes that developers name the imported membersisNpm
,isYarn
andisYarnOrNpm
. However, there are two ways in which developers could alter the imports that can't be handled by the codemod:Moreover, by relying on hardcoded names, we also could potentially make unsafe modifications to developer code (they could have an
isNpm
variable themselves which is different from the imported one and has a different meaning)This PR makes the codemod detect the imported names dynamically so that it supports the styles above. It also adds test cases to handle the new styles.
The PR introduces the
getImportIdentifierMap
helper which creates a map like this:This helper should be useful for cases where a module exports multiple names and
const { identifier } = removeImport()
is not sufficient.There is some duplication in the codemod code, as the "individual name import" and "namespace import" cases need to be handled separately. However, since I suspect that this issue will also apply to other codemods, I believe the duplication is fine for now — we can figure out better abstractions as we continue improving the mods.
Thanks for reading!