Empresas
Empleos
  • Sobre nosotros
  • Soluciones
    • Publicación de vacantes
      Publica tu vacante y recibe candidatos calificados en 48h.
    • Evaluación de candidatos
      500+ pruebas técnicas y psicológicas, más anti-fraude.
    • Headhunting
      Búsqueda ejecutiva a la medida de principio a fin.
    • Nómina + EOR
      Dispersión de nómina y EOR en más de 15 países de LATAM.
  • Precios
  • Empleos

0

164
Vistas
Wrap all variable declarations in a function

I have a Javascript function declartions as a string (gotten from Function.toString), and I want to wrap all variable declarations with a function (also in Javascript), E.g. const value = 42 to const value = wrapper(42).

First I thought of using RegEx to get the original values and location and then replace them with the wrapped value, but the RegEx got too complex very fast because of needing to think about things like multiline strings and objects. Using RegEx would also impact the ease of other people contributing to the project.

After that I looked into using a module for this, I found Acorn (used by Babel, Svelte. Parses the Javascript into an ESTree, the spec for Javascript Abstract Syntax Trees): https://github.com/acornjs/acorn, but I couldn't find a way of parsing the ESTree back to a Javascript function declaration after making the modifications.

Is there a way of parsing the ESTree back to a function, or another better solution?

about 4 years ago · Juan Pablo Isaza
1 Respuestas
Responde la pregunta

0

You don't really need a function to stringify the tree back into code. Instead, take note of the offsets where the change should occur, and then don't apply the change in the tree, but to the original string.

Here is a demo with the acorn API:

function test () { // The function we want to tamper with
    const value = 42, prefix = "prefix";
    
    let x = 3;
    for (let i = 0; i < 10; i++) {
        x = (x * 997 + value) % 1000;
    }
    return prefix + " " + x;
}

function addInitWrappers(str) { // Returns an updated string
    let ast = acorn.parse(str, {ecmaVersion: 2020});
    
    function* iter(node) {
        if (Object(node) !== node) return; // Primitive
        if (node.type == "VariableDeclaration" && node.kind == "const") {
            for (let {init} of node.declarations) {
                yield init; // yield the offset where this initialisation occurs
            }
        }
        for (let value of Object.values(node)) {
            yield* iter(value);
        }
    }
    
    // Inject the wrapper -- starting at the back
    for (let {start, end} of [...iter(ast)].reverse()) {
        str = str.slice(0, start) + "wrapper(" + str.slice(start, end) + ")" + str.slice(end);
    }
    return str;
}

function wrapper(value) { // A wrapper function to demo with
    return value + 1;
}

console.log("before wrapping test() returns:", test());
let str = test.toString();
str = addInitWrappers(str);
eval(str); // Override the test function with its new definition
console.log("after wrapping test() returns:", test());
<script src="https://cdnjs.cloudflare.com/ajax/libs/acorn/8.7.1/acorn.min.js"></script>

about 4 years ago · Juan Pablo Isaza Denunciar
Responde la pregunta
Encuentra empleos remotos

¡Descubre la nueva forma de encontrar empleo!

Top de empleos
Top categorías de empleo
Empresas
Publicar vacante Precios Comercial
Legal
Términos y condiciones Política de privacidad
© 2026 PeakU Inc. All Rights Reserved.
Andres GPT
Recomiéndame algunas ofertas
Necesito ayuda