Skip to content

Replace direct babel usage with magicast #126

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
AriPerkkio opened this issue Jul 10, 2024 · 1 comment
Open

Replace direct babel usage with magicast #126

AriPerkkio opened this issue Jul 10, 2024 · 1 comment
Labels
maintenance Change related to maintaining TutorialKit

Comments

@AriPerkkio
Copy link
Member

Is your feature request related to a problem?

Currently CLI modifies user's astro.config.ts via AST transforms using Babel. This works really well but it quite heavy to maintain.

/**
* In the second pass, we search for a default export which is a call to `defineConfig`
* and we look for our `integrationId` that we just got from the `integrations` field.
*/
visit(ast, {
ExportDefaultDeclaration(path) {
if (!t.isCallExpression(path.node.declaration)) {
return;
}
const configObject = path.node.declaration.arguments[0];
if (!t.isObjectExpression(configObject)) {
throw new Error('TutorialKit is not part of the exported config');
}
const integrationsProp = configObject.properties.find((prop) => {
if (prop.type !== 'ObjectProperty') {
return false;
}
if (prop.key.type === 'Identifier') {
if (prop.key.name === 'integrations') {
return true;
}
}
if (prop.key.type === 'StringLiteral') {
if (prop.key.value === 'integrations') {
return true;
}
}
return false;
}) as t.ObjectProperty | undefined;
if (integrationsProp.value.type !== 'ArrayExpression') {
throw new Error('Unable to parse integrations in Astro config');
}
let integrationCall = integrationsProp.value.elements.find((expr) => {
return t.isCallExpression(expr) && t.isIdentifier(expr.callee) && expr.callee.name === integrationId.name;
}) as t.CallExpression | undefined;
// if the integration wasn't found we add it
if (!integrationCall) {
integrationCall = t.callExpression(integrationId, []);
integrationsProp.value.elements.push(integrationCall);
}
const integrationArgs = integrationCall.arguments;
// if `tutorialkit` is called as `tutorialkit()`
if (integrationArgs.length === 0) {
const objectArgs = fromValue(newTutorialKitArgs) as t.ObjectExpression;
if (objectArgs.properties.length > 0) {
integrationArgs.push(objectArgs);
}
return;
}
if (!t.isObjectExpression(integrationArgs[0])) {
throw new Error('Only updating an existing object literal as the config is supported');
}
// if `tutorialkit` is called with an object literal we update its existing properties
updateObject(newTutorialKitArgs, integrationArgs[0]);
},
});

Describe the solution you'd like.

Check if direct Babel usage could be replaced with magicast. It provides much nicer API to work with AST transforms. This package is also used by Vitest, where we modify user's vitest.config.ts. It's very similar to what TutorialKit does.

https://github.com/vitest-dev/vitest/blob/7012f8c12a3d0004e7e7651bbeee905ac9102098/packages/vitest/src/utils/coverage.ts#L349-L402

We should also add similar unit tests: https://github.com/vitest-dev/vitest/blob/main/test/coverage-test/test/threshold-auto-update.unit.test.ts

Describe alternatives you've considered.

Keep maintaining the direct Babel integration. It's reliable and does exactly what we need it to, but it's not as easy to maintain.

Additional context

No response

@AriPerkkio AriPerkkio added maintenance Change related to maintaining TutorialKit pr-welcome Accepting pull requests for this change and removed pr-welcome Accepting pull requests for this change labels Jul 10, 2024
@MoneyMouthBottom
Copy link

Get R Done

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
maintenance Change related to maintaining TutorialKit
Projects
None yet
Development

No branches or pull requests

2 participants