Skip to content

Instantly share code, notes, and snippets.

@eschaefer
Created March 29, 2019 12:35
Show Gist options
  • Save eschaefer/6eacfa2191863522866a06c3880e9803 to your computer and use it in GitHub Desktop.
Save eschaefer/6eacfa2191863522866a06c3880e9803 to your computer and use it in GitHub Desktop.
Codemod to convert central general/index imports into tree-shakeable imports
/*
jscodeshift --parser=flow --extensions=js,jsx -t ./mod.js ~/Projects/frontend/app/*
*/
const GENERALS = {
AddToCartBtn: 'addToCartBtn/',
AddToLightbox: 'addToLightbox/',
AdManagerExportButton: 'adManagerExportButton/',
AgoWrap: 'agoWrap.jsx',
AlbumFollowBtn: 'albumFollowBtn/',
AppLinks: 'appLinks/',
BlacklistCheck: 'blacklistCheck/',
BlackTooltip: 'blackTooltip.jsx',
CheckboxGroup: 'checkboxGroup.jsx',
CartItem: 'cartItem/',
CartItemv2: 'cartItemv2/',
CartSidebar: 'cartSidebar',
CopyButton: 'copyButton.jsx',
CollectionDropdown: 'dropdown/collectionDropdown.jsx',
Collapsible: 'collapsible.jsx',
Comment: 'comment.jsx',
CommentBtn: 'commentBtn/',
ContactForm: 'contactForm/',
ContentLeftImageRight: 'contentLeftImageRight/',
CreateLightbox: 'createLightbox/',
DateComponent: 'date.jsx',
DeleteLink: 'deleteLink/',
Device: 'device/',
Disable: 'disable.jsx',
DirectDownloadButton: 'directDownloadButton/',
Dropdown: 'dropdown/',
DropdownSelect: 'dropdownSelect.jsx',
Dropzone: 'dropzone.jsx',
EditLink: 'editLink',
EmbedLink: 'embedLink/',
EmptyState: 'emptyState.jsx',
EnterpriseUserSignupForm: 'enterpriseUserSignupForm',
ErrorMsg: 'error.jsx',
EyeemLogo: 'eyeemlogo.jsx',
FacebookAuth: 'facebookAuth/',
FadeIn: 'fadeIn.jsx',
Filestack: 'filestack.jsx',
FlagLink: 'flagLink/',
Flyout: 'flyout.jsx',
Footer: 'footer/',
FullHeight: 'fullHeight/',
Header: 'header.jsx',
Iframe: 'iframe.jsx',
ImageDetails: 'imageDetails.jsx',
InfoBox: 'infoBox.jsx',
IntercomWidget: 'intercomWidget/',
LicenseChooser: 'licenseChooser/',
LightboxActions: 'lightboxActions/',
LikeBtn: 'likeBtn/',
Link: 'link/',
LinkWithDifferentCopyOnHover: 'linkWithDifferentCopyOnHover.jsx',
LoginForm: 'loginForm/',
MlpSlider: 'mlpSlider/',
OrSeparator: 'orSeparator.jsx',
OverviewHeader: 'overviewHeader.jsx',
OverviewTable: 'overviewTable/',
PaginatablePhotoGrid: 'photoGrid/paginatable/',
ParseLinks: 'parseLinks.jsx',
Photo: 'photo/',
PhotoCreditLink: 'photoCreditLink.jsx',
PhotoFullWidth: 'photoFullWidth/',
PhotoStrip: 'photoStrip/',
PlainHeader: 'plainHeader.jsx',
PremiumLabel: 'premiumLabel.jsx',
Price: 'price.jsx',
PriceBadge: 'priceBadge.jsx',
ProgressBar: 'progressBar/',
Questions: 'questions.jsx',
RadioGroup: 'radioGroup.jsx',
RenderOnMount: 'renderOnMount.jsx',
ReleaseList: 'releaseList/',
ReleaseListItem: 'releaseListItem/',
ScrollCapture: 'scrollCapture.jsx',
SearchBar: 'searchBar/',
SearchTrigger: 'searchTrigger/',
SelectionStrip: 'selectionStrip/',
SelectGrid: 'selectGrid/',
ShareItem: 'shareItem.jsx',
ShareLightboxTrigger: 'shareLightboxTrigger/',
Sidebar: 'sidebar.jsx',
SignupForm: 'signupForm/',
SimplePhotoGrid: 'photoGrid/simple/',
Slider: 'slider/',
Spinner: 'spinner.jsx',
Sticky: 'sticky.jsx',
SocialServiceBox: 'socialServiceBox.jsx',
SubHeader: 'subHeader/',
Subnavigation: 'subnavigation/',
Tabs: 'tabs.jsx',
TooltipContent: 'tooltipContent.jsx',
TooltipPanel: 'tooltipPanel.jsx',
TooltipTrigger: 'tooltipTrigger/',
Translate: 'translate.jsx',
UserFollowBtn: 'userFollowBtn/',
UserGrid: 'userGrid/',
VideoFullWidth: 'videoFullWidth.jsx'
};
module.exports = function transformer(file, api) {
const j = api.jscodeshift;
const root = j(file.source);
var names = [];
var nodes = '';
var level = '';
const extractNames = path => {
const { specifiers } = path.node;
level = path.node.source.value;
console.log(level);
specifiers.forEach(item => {
if (item.local.name !== item.imported.name) {
names.push({ alias: item.local.name, name: item.imported.name });
} else {
names.push({ name: item.imported.name });
}
});
names.forEach(name => {
var extension = GENERALS[name.name];
var hasSlash = level.endsWith('/');
if (name.alias) {
nodes += `import ${name.alias} from '${
hasSlash ? level : level + '/'
}${extension}';\n`;
} else {
nodes += `import ${name.name} from '${
hasSlash ? level : level + '/'
}${extension}';\n`;
}
});
return j(path).replaceWith(nodes);
};
const getGenerals = () =>
root
.find(j.ImportDeclaration)
.filter(e => {
if (
e.node.source.value.endsWith('/general/') ||
e.node.source.value.endsWith('/general')
) {
return true;
}
return false;
})
.forEach(extractNames);
getGenerals();
return root.toSource();
};
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment