Skip to content

Instantly share code, notes, and snippets.

@kristojorg
Last active February 9, 2022 12:08
Show Gist options
  • Save kristojorg/abe305a2ecf49e173c56ef42e977f362 to your computer and use it in GitHub Desktop.
Save kristojorg/abe305a2ecf49e173c56ef42e977f362 to your computer and use it in GitHub Desktop.
A codemod to add specificity to styled-components generated css. This helped me fix the issue of jss being placed in the head below styled-components
const tagTypes = {
Identifier: node => node,
CallExpression: node => node.callee,
MemberExpression: node => node.object,
};
module.exports = (file, api, options) => {
const j = api.jscodeshift;
const ast = j(file.source);
// find the taggedtemplate expressions
return ast
.find(j.TaggedTemplateExpression)
.replaceWith(path => {
const { quasi, tag } = path.node;
// if it is not one of the right types, continue
if (!(tag.type in tagTypes))
return j.taggedTemplateExpression(tag, quasi);
// Get the identifier for styled in either styled.View`...` or styled(View)`...`
// this should check if it is a "styled" tagged template expression
const callee = tagTypes[tag.type](tag);
if (callee.type !== 'Identifier' || callee.name !== 'styled')
return j.taggedTemplateExpression(tag, quasi);
// get the internals of the expression in order to wrap it.
const firstEl = quasi.quasis[0];
const lastEl = quasi.quasis[quasi.quasis.length - 1];
// modify them as needed. Whitepsace is ugly here, but
// I use prettier to update this after.
firstEl.value.raw = `
&& { ${firstEl.value.raw}`;
firstEl.value.cooked = `
&& { ${firstEl.value.cooked}`;
lastEl.value.raw = `${lastEl.value.raw} }`;
lastEl.value.cooked = `${lastEl.value.cooked} }`;
// return a new taggedTemplateExpression
const newTemplateLiteral = j.templateLiteral(
quasi.quasis,
quasi.expressions
);
return j.taggedTemplateExpression(tag, newTemplateLiteral);
})
.toSource();
};
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment