is there a way to compile a JavaScript string, store and use variables from the compiled string?

Viewed 146

I am trying to build an HTML preprocessor that would help me out with my electron project. I have looked at other preprocessors and none meets my expectations so I decided to create mine. Here is an example of the code format or syntax.

{{@import Button from './components/Out'}}

{{@Component {
    name: 'Button',
    useStrict: true,
    props: {
        name: '',
        className: '',
        values: ''
    }
}}}
    {{@include './index', {
        name: props.name
    }}}
    <button class={{props.className}}>{{{name}}}</button>

    {{@if (avatar !== null || avatar !== undefined) }}
        <li class={{`${props.name}`}}>
            this is a test {{avatar}}
        </li>

        {{@each field in values}}
            <span class="d-flex">
                {{field.name}}
                <small>
                     power level: <b>{{field.power}}</b>
                </small>
            </span>
        {{/each}}
    {{/if}}

    <Button name="" text="" value="" href=""/>


{{/Component}}

//---- the problem is below; compiling the code and storing the values of each global variable
<@
    let avatar = 'My avatar is on the run';

    const values = [{name: 'Batman', power: '200kilowatts'}, {name: 'Spiderman', power: '60watts'}];

    const func = () => {
        let name = 'David';
        script = name;
    }
@>

I have parsed the entire file or code, and everything works fine but compiling that script.

NB: I used Esprima to extract the script's global variables.

First, I thought of using the window object to compile the script, that way, I can get each variable's value by calling window[variableName] I am using node js so I imported Jsdom but unfortunately it didn't work, window[variableName] kept returning undefined.

Then I thought of eval, but that also brought up issues because I can't make use of the variables in eval, so I thought of dynamically creating those variables first or saving them in the global object, but it certainly won't work, at least as far as I know.

Sorry for the long description.. the summary is, that I need to be able to get each variable's value after the string has been compiled. I have tried finding js-engines or js-compilers that can be installed with npm but not much luck with that. Also just in case, someone says they found a similar preprocessor, please, I have done my research and there isn't any similar. I placed a lot of functionality to this preprocessor and it's an important component for my electron project... So any help is perfect.... thank you for your time.

1 Answers

Here is a solution i come up with :

<script>
    let jsCode = `
    var test1 = 'var';
    const test2 = 'const';
    let test3 = 'let';

    console.log(this.globalCtxVar);

    return {
       test1,
       test2,
       test3
    }
`;
    let ctx = {
        globalCtxVar: 'testVar'
    };


    let fn = Function(jsCode);
    ctx = Object.assign(ctx, fn.call(ctx));
    console.log(ctx)
</script>

it allow to exec js code using Function and export variables using return, also ctx can be accessed within the code with this

at the end of the execution ctx looks like :

{
    "globalCtxVar": "testVar",
    "test1": "var",
    "test2": "const",
    "test3": "let"
}

So in the end it's the same as eval but with greater control of input/outputs since it's a function

Related