-
Notifications
You must be signed in to change notification settings - Fork 135
New issue
Have a question about this project? # for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “#”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? # to your account
Add hook after all files have been processed? #155
Comments
Unfortunately I don't think this is possible. Babel plugins (like babel-plugin-macros) operate on a single file and aren't made aware of any other files that are being processed. |
@kentcdodds if @vedantroy does the tracking themselves as proposed (e.g. by using their let numberOfFiles = 0;
function macroHandler({ references, state, babel}) {
numberOfFiles++;
console.log(numberOfFiles)
}
export default createMacro(macroHandler) Theoretically, const macroState = {
files: []
}
export const beforeAll = () => {
// do something before any uses of this macro are processed
}
export const afterAll = () => {
// do something after all uses of this macro have been processed
for (const file of macroState.files) {
console.log(`File at path ${file} used 'register'`)
}
}
export default createMacro(({ references, state }) => {
const { filename } = state.file.opts
if (references.register?.length > 0) {
macroState.files.push(filename)
}
macroState
}) |
Sorry, I'm really confused. When/how would |
Yeah, after taking a look at the implementation again you're right of course — this is all processed by file, in import order. The sequence in my head (by macro in import order, then file) makes no sense in hindsight 😄 |
Yeah, this isn't possible, which is unfortunate but inevitable due to the way Babel works. |
Thought I'd mention you can actually get around this by leveraging the import { createMacro } from 'babel-plugin-macros';
import * as fs from 'fs';
import type { MacroHandler } from 'babel-plugin-macros';
const thingsFromAllFiles = [];
// Replaced each time the macro is run, so process.exit only runs _once_
let processExitHook = () => {};
process.on('exit', () => processExitHook());
const yourMacro: MacroHandler = ({ references, state }) => {
references.default.forEach(referencePath => {
// Here's where you'd do work. Maybe extract a string from the AST
thingsFromAllFiles.push("...");
});
// Replace. Not set! Else you'll stack exit hooks
processExitHook = () => {
console.log(`Found ${thingsFromAllFiles.length} things in all files`);
fs.writeFileSync("output.txt", thingsFromAllFiles.join('\n'));
};
};
export default createMacro(yourMacro); A real example is here in my repo: https://github.com/heyheyhello/stayknit/blob/fbc56a9d1f9ca15e4078af1b320b9d130bcc3190/contrib/babel-style-takeout/style-takeout.macro.ts I pull out CSS-in-JS to its own CSS file and replace the node with a generated CSS classname Works OK. The only trouble is |
For typecheck.macro, I am trying to support the following feature:
file1.ts
:file2.ts
:What's going on here is that the
register
macro is being called to "register" theExample
type. Then whencreateValidator
is called inside "file2.ts", it looks up the registered type and generates the validator.This utilizes the fact that macros can have global inter-file state, like so:
Problem description:
The issue is that I need to wait until all files have been macro-ed. Then I can process all register paths at once (to generate a global map of all the types), and then I can process all instances of
createValidator
.This would require a hook that is called once after all files have been processed. The hook wouldn't have to have any parameters or anything complicated.
Suggested solution:
The api could like this:
I would be very willing to make a PR and implement this feature because it's pretty crucial to typecheck.macro/I'm pretty sure typecheck.macro is only useful if it is a macro.
The text was updated successfully, but these errors were encountered: