-
Notifications
You must be signed in to change notification settings - Fork 137
Description
babel-plugin-macrosversion: 3.0.1nodeversion: v14.15.1npmversion: 6.14.8
Relevant code or config
// File: test.macro.js
const { createMacro } = require("babel-plugin-macros");
let callbackCounter = 0;
// Counts macro calls and adds comments to every detected macro usage
function macroCallback({ references, state, babel, source, config }) {
callbackCounter += 1;
for (const importName in references) {
for (const path of references[importName]) {
path.addComment("leading", callbackCounter);
}
}
}
module.exports = createMacro(macroCallback);// File: index.js
macro = 1;
macro;
macro("before require");
const macro = require("./test.macro");
macro("after require");
macro = "Direct assignment is always ignored";
macro.v = "This works";
{
macro("before require");
const macro = require("./test.macro");
macro("after require");
}
macro;// File: index-after-macro.js
"use strict";
macro = 1;
/*1*/
macro;
/*1*/
macro("before require");
/*1*/
macro("after require");
macro = "Direct assignment is always ignored";
/*1*/
macro.v = "This works";
{
/*2*/
macro("before require");
/*2*/
macro("after require");
}
/*1*/
macro;Problem description and suggested solutions:
I can see few issues here:
-
You can access a macro in a scope before initialization. It's a bit unexpected and there are no warnings/errors. It may cause some issues especially if there are some global variables.
-
When you do assignments, direct assignment is completely ignored.
Even if the macro was imported or required as const there is no error.
I assume that it has something to do with global variables, but I think
it would be nice, if a user could handle a scenario like this in a macro.
Either to just print an error message like 'usage like this is not allowed' or
to do something else. -
Babel-plugin-macros allows for scoping (awesome), but the way it's handled right now
makes it impossible to handle all macro usages within a single function (without some nasty tricks, atleast).
Maybe there is a way to handle scoping better? Sometimes user may want to do some global post-processing in a file after processing all macros. References could be organised like this for example:
[
{
scope: 0, // id
importName: "default/*/name",
localName: "importName/as",
path: PathNode(),
},
/* .. */
];I gives more context about the macro usage.
Of course, localName name currently can be easily checked with Identifier name prop.
The main issue are scopes.
Also two minor things.
- Syntax like this (similar to
require()) is not recognized. Not that I need it, it's just something I noticed. It looks like a minor oversight, but maybe it's intentional.
const macro = import('./test.macro');- Syntax like this causes an 'Cannot read property 'name' of undefined' error. Again, just something I noticed.
import * as macro from "./test.macro";